@tanstack/browser-db-sqlite-persistence 0.2.23 → 0.2.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -1
- package/dist/assets/{opfs-worker-uyjx5Rus.js → opfs-worker-accoEoax.js} +17 -6
- package/dist/assets/{opfs-worker-uyjx5Rus.js.map → opfs-worker-accoEoax.js.map} +1 -1
- package/dist/cjs/browser-coordinator.cjs +5 -534
- package/dist/cjs/browser-coordinator.cjs.map +1 -1
- package/dist/cjs/browser-coordinator.d.cts +3 -65
- package/dist/cjs/browser-persistence.cjs +19 -8
- package/dist/cjs/browser-persistence.cjs.map +1 -1
- package/dist/cjs/index.cjs +16 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +2 -2
- package/dist/cjs/opfs-database.cjs +58 -1
- package/dist/cjs/opfs-database.cjs.map +1 -1
- package/dist/cjs/opfs-database.d.cts +4 -0
- package/dist/cjs/opfs-worker.cjs +1 -1
- package/dist/cjs/wa-sqlite-driver.cjs +38 -14
- package/dist/cjs/wa-sqlite-driver.cjs.map +1 -1
- package/dist/cjs/wa-sqlite-driver.d.cts +3 -3
- package/dist/esm/browser-coordinator.d.ts +3 -65
- package/dist/esm/browser-coordinator.js +5 -534
- package/dist/esm/browser-coordinator.js.map +1 -1
- package/dist/esm/browser-persistence.js +19 -8
- package/dist/esm/browser-persistence.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +5 -1
- package/dist/esm/opfs-database.d.ts +4 -0
- package/dist/esm/opfs-database.js +58 -1
- package/dist/esm/opfs-database.js.map +1 -1
- package/dist/esm/opfs-worker.js +1 -1
- package/dist/esm/wa-sqlite-driver.d.ts +3 -3
- package/dist/esm/wa-sqlite-driver.js +39 -15
- package/dist/esm/wa-sqlite-driver.js.map +1 -1
- package/package.json +9 -3
- package/src/browser-coordinator.ts +10 -834
- package/src/browser-persistence.ts +22 -14
- package/src/index.ts +9 -0
- package/src/opfs-database.ts +76 -1
- package/src/opfs-worker.ts +16 -5
- package/src/wa-sqlite-driver.ts +57 -15
- package/src/wa-sqlite-examples.d.ts +1 -0
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Browser SQLite persistence for TanStack DB using `wa-sqlite` + OPFS.
|
|
4
4
|
|
|
5
|
+
Start with the [SQLite Persistence guide](../../docs/guides/sqlite-persistence.md) for Collection setup and lifecycle behavior.
|
|
6
|
+
|
|
5
7
|
Supports both single-tab (default) and multi-tab usage. Multi-tab coordination
|
|
6
8
|
is opt-in by passing a `BrowserCollectionCoordinator`.
|
|
7
9
|
|
|
@@ -9,6 +11,7 @@ is opt-in by passing a `BrowserCollectionCoordinator`.
|
|
|
9
11
|
|
|
10
12
|
- `createBrowserWASQLitePersistence(...)`
|
|
11
13
|
- `openBrowserWASQLiteOPFSDatabase(...)`
|
|
14
|
+
- `BrowserCollectionCoordinator`
|
|
12
15
|
- `persistedCollectionOptions(...)` (re-exported from core)
|
|
13
16
|
|
|
14
17
|
## Quick start (single-tab)
|
|
@@ -97,13 +100,84 @@ export const todosCollection = createCollection(
|
|
|
97
100
|
See [`examples/react/offline-transactions`](../../examples/react/offline-transactions/src/db/persisted-todos.ts)
|
|
98
101
|
for a full multi-tab example.
|
|
99
102
|
|
|
103
|
+
### Committed transaction ownership
|
|
104
|
+
|
|
105
|
+
The persisted sync wrapper sends every source transaction with durable effects
|
|
106
|
+
through the coordinator's required
|
|
107
|
+
`requestApplyCommittedTx(collectionId, tx)` method.
|
|
108
|
+
`BrowserCollectionCoordinator` routes the complete transaction to the current
|
|
109
|
+
leader for that collection. The leader applies it with the adapter registered
|
|
110
|
+
for the same collection id, including that collection's resolved mode and
|
|
111
|
+
`schemaVersion`.
|
|
112
|
+
|
|
113
|
+
The route preserves truncation, row changes, row metadata, collection metadata,
|
|
114
|
+
and stream position as one `PersistedTx`. It does not feature-detect a partial
|
|
115
|
+
route or fall back to row-only mutation RPC. A custom coordinator that omits
|
|
116
|
+
`requestApplyCommittedTx` is rejected while the collection is configured,
|
|
117
|
+
before its sync source can publish rows. An effect-free source commit neither
|
|
118
|
+
publishes nor consumes a coordinator sequence.
|
|
119
|
+
|
|
120
|
+
Single-tab mode uses the same complete transaction contract. Its
|
|
121
|
+
`SingleProcessCoordinator` skips election and channel traffic but still routes
|
|
122
|
+
the transaction to the resolved adapter for that collection.
|
|
123
|
+
|
|
124
|
+
If a mutating RPC loses its response, Browser coordination replays it only
|
|
125
|
+
while the requester still knows the same non-null leader id and term. An
|
|
126
|
+
unknown initial route or any leader/term change rejects with
|
|
127
|
+
`IndeterminateCommitError`; the application must reconcile the outcome. The
|
|
128
|
+
coordinator does not retry that mutation against an unknown or replacement
|
|
129
|
+
leader.
|
|
130
|
+
|
|
131
|
+
### Remote subset requests
|
|
132
|
+
|
|
133
|
+
`BrowserCollectionCoordinator.requestEnsureRemoteSubset(...)` validates and
|
|
134
|
+
projects the request before it chooses the local leader or `BroadcastChannel`
|
|
135
|
+
route. Registered owners receive the exported
|
|
136
|
+
`TransportedLoadSubsetOptions` type. It contains the supported
|
|
137
|
+
structured-clone wire data and excludes live `signal` and `subscription`
|
|
138
|
+
fields. Unsupported nested values fail immediately with
|
|
139
|
+
`RemoteSubsetWireValueError` and the exact value path; no owner callback or
|
|
140
|
+
channel post occurs. See the core package's remote subset wire contract for the
|
|
141
|
+
complete supported domain.
|
|
142
|
+
|
|
143
|
+
Each accepted request is an explicit lease. Retries of the same request object
|
|
144
|
+
reuse its acquisition identity, while distinct equal request objects remain
|
|
145
|
+
independent. Release is routed to the elected collection owner and unloads the
|
|
146
|
+
exact acquired options once. Leadership loss unloads the retiring owner's live
|
|
147
|
+
leases, and requesters replay still-live acquisitions against the next leader.
|
|
148
|
+
Registering a second owner for one collection throws
|
|
149
|
+
`DuplicateRemoteSubsetOwnerError`; no adapter fallback replaces the owner.
|
|
150
|
+
Remote follower transport/admission failures reject and retain demand for its
|
|
151
|
+
normal retry without entering the follower's local owner lifecycle. Terminal
|
|
152
|
+
release identities expire after the existing RPC dedupe horizon while delayed
|
|
153
|
+
duplicates inside that horizon remain idempotent.
|
|
154
|
+
|
|
100
155
|
## Notes
|
|
101
156
|
|
|
102
157
|
- `openBrowserWASQLiteOPFSDatabase(...)` starts a dedicated Web Worker and
|
|
103
158
|
routes SQL operations through it. OPFS sync access handle APIs are used in
|
|
104
159
|
that worker context.
|
|
160
|
+
- Opening has a 30-second deadline by default. `timeoutMs` changes it; `0`
|
|
161
|
+
explicitly disables the deadline. A timed-out open rejects with
|
|
162
|
+
`TimeoutError` and terminates its pending worker, so it cannot acquire the
|
|
163
|
+
database later. Pass an `AbortSignal` to cancel earlier; the signal applies
|
|
164
|
+
only while opening, not to the established connection.
|
|
165
|
+
- On `pagehide`, the connection terminates its worker synchronously and rejects
|
|
166
|
+
pending initialization, queries, and close operations with `AbortError`. This
|
|
167
|
+
also applies when the document enters the back/forward cache. Applications
|
|
168
|
+
restored through
|
|
169
|
+
`pageshow` with `event.persisted` must create fresh database connections and
|
|
170
|
+
persistence/collection instances (or reload the application).
|
|
171
|
+
- Flush application writes and await `database.close()` before navigating when
|
|
172
|
+
possible. The `pagehide` cleanup releases resources; it cannot await pending
|
|
173
|
+
writes or serve as a durability guarantee.
|
|
105
174
|
- Single-tab mode does not require `BroadcastChannel` or Web Locks for
|
|
106
|
-
|
|
175
|
+
election, but committed transactions still go through the collection's
|
|
176
|
+
registered persistence owner.
|
|
107
177
|
- Multi-tab mode requires `BroadcastChannel` and the Web Locks API; both are
|
|
108
178
|
available in all modern browsers.
|
|
109
179
|
- OPFS capability failures are surfaced as `PersistenceUnavailableError`.
|
|
180
|
+
- SQLite open failures include the underlying VFS error name and message when
|
|
181
|
+
wa-sqlite exposes them. Some failures, including native access-handle
|
|
182
|
+
contention, are not currently exposed by wa-sqlite and retain SQLite's
|
|
183
|
+
generic open error.
|
|
@@ -5755,11 +5755,22 @@
|
|
|
5755
5755
|
sqlite3.vfs_register(opfsVfs, true);
|
|
5756
5756
|
const openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI;
|
|
5757
5757
|
const databaseFileUri = `file:${request.databaseName}?vfs=${encodeURIComponent(request.vfsName)}`;
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5758
|
+
let dbHandle;
|
|
5759
|
+
try {
|
|
5760
|
+
dbHandle = await sqlite3.open_v2(
|
|
5761
|
+
databaseFileUri,
|
|
5762
|
+
openFlags,
|
|
5763
|
+
request.vfsName
|
|
5764
|
+
);
|
|
5765
|
+
} catch (error) {
|
|
5766
|
+
const cause = opfsVfs.lastError;
|
|
5767
|
+
if (error instanceof Error && cause instanceof Error) {
|
|
5768
|
+
throw new Error(`${error.message}: ${cause.name}: ${cause.message}`, {
|
|
5769
|
+
cause
|
|
5770
|
+
});
|
|
5771
|
+
}
|
|
5772
|
+
throw error;
|
|
5773
|
+
}
|
|
5763
5774
|
sqlite3Instance = sqlite3;
|
|
5764
5775
|
sqliteDatabaseHandle = dbHandle;
|
|
5765
5776
|
opfsVfsInstance = opfsVfs;
|
|
@@ -5876,4 +5887,4 @@
|
|
|
5876
5887
|
});
|
|
5877
5888
|
});
|
|
5878
5889
|
})();
|
|
5879
|
-
//# sourceMappingURL=opfs-worker-
|
|
5890
|
+
//# sourceMappingURL=opfs-worker-accoEoax.js.map
|