Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/electric-cleanup-stream-listeners.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/electric-db-collection': patch
---

Release the shape stream's visibility listener when a sync run is cleaned up. The Electric client registers a `visibilitychange` listener for each `ShapeStream` (an `AppState` subscription on React Native, from `@electric-sql/client` 1.5.23) and removes it only in `unsubscribeAll()`, so aborting the stream left the listener behind, and the listener kept the stream reachable. An app that cleans up and recreates collections, or whose on-demand cache rotates its provider session, gained one retained stream each time.
7 changes: 7 additions & 0 deletions docs/collections/electric-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,13 @@ A mutation handler waiting on one of them rejects; a later handler can wait for
evidence from the replacement session. The replacement reloads demanded
subsets and does not treat acknowledgements from the retired session as current.

Before constructing a replacement `ShapeStream`, Electric releases the
adapter-owned resources of the retired provider session, including its
subscriptions and host lifecycle listeners. The replacement starts after cache
rotation completes. An HTTP request that ignores cancellation may still finish
later; its response cannot publish rows or settle waits for the replacement
session.

Persisted resumes wait for the cached row baseline to finish hydrating. If the
persistence wrapper cannot verify hydration completion, Electric starts a fresh
snapshot instead of using the saved offset and handle. It warns once per options
Expand Down
19 changes: 17 additions & 2 deletions docs/contributing/oracle-coverage.md

Large diffs are not rendered by default.

1,214 changes: 1,214 additions & 0 deletions docs/contributing/oracle-reviews/2026-10-26-pr-2257.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/db/tests/oracle-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const staticOracleProperties = [
`query-db.refetch-ordered-prefix`,
`ordered-loader.request-authority`,
`replay.ordered-window-faults`,
`replay.keyed-request-failures`,
`replay.subscription-demand-origin`,
`oracle-replay.calibration`,
`structural-identity.equal-representations`,
Expand All @@ -65,6 +66,8 @@ const staticOracleProperties = [
`electric.persistence-interleaving`,
`electric.sdk-snapshot-delivery`,
`electric.sdk-dnf-membership`,
`electric.sdk-source-release`,
`electric.sdk-rotation-release`,
`electric-recovery.publication-stream-convergence`,
`sqlite-resume.startup-generation`,
`sqlite-resume.managed-claim-read`,
Expand Down
13 changes: 12 additions & 1 deletion packages/db/tests/oracle-replay-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const ownerGroups: ReadonlyArray<readonly [string, string, string]> = [
[
`electric-db-collection/tests/electric-sdk-delivery-oracle.property.test.ts`,
`electric`,
`sdk-snapshot-delivery sdk-dnf-membership`,
`sdk-snapshot-delivery sdk-dnf-membership sdk-source-release sdk-rotation-release`,
],
[
`db/tests/collection-sync-reentrancy-oracle.test.ts`,
Expand Down Expand Up @@ -244,6 +244,11 @@ const ownerGroups: ReadonlyArray<readonly [string, string, string]> = [
`ordered-work`,
`consumer-parity eager-indexed-window eager-joined-window eager-joined-gap eager-full-join eager-held-load`,
],
[
`db/tests/query/load-subset-replay-refinement-oracle.test.ts`,
`replay`,
`ordered-window-faults keyed-request-failures subscription-demand-origin`,
],
[
`db/tests/query/pagination-oracle.property.test.ts`,
`pagination`,
Expand Down Expand Up @@ -402,6 +407,12 @@ const replayTestNames = new Map([
])

function directReplayTestName(property: string): string | undefined {
if (property === `replay.ordered-window-faults`)
return `keeps the ordered window under load and release faults \\(replay campaign\\)`
if (property === `replay.keyed-request-failures`)
return `distinguishes keyed request failure from reacquisition \\(replay campaign\\)`
if (property === `replay.subscription-demand-origin`)
return `distinguishes failed demand origins \\(replay campaign\\)`
if (property === `cold-join.compound`)
return `recomputes generated compound histories, seed=undefined`
if (property === `oracle-replay.calibration`)
Expand Down
Loading
Loading