browser-sqlite 1.0.0-rc.3 → 1.0.0-rc.5

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.
Files changed (47) hide show
  1. package/NOTICE +56 -0
  2. package/README.md +112 -104
  3. package/dist/LICENSE +21 -0
  4. package/dist/NOTICE +56 -0
  5. package/dist/abandon.d.ts +77 -0
  6. package/dist/api.d.ts +426 -0
  7. package/dist/bulk.d.ts +57 -0
  8. package/dist/capabilities.d.ts +23 -0
  9. package/dist/client.d.ts +221 -0
  10. package/dist/credits.d.ts +31 -0
  11. package/dist/{esm/src/debug.d.ts → debug.d.ts} +21 -10
  12. package/dist/delete.d.ts +48 -0
  13. package/dist/epochs.d.ts +85 -0
  14. package/dist/errors.d.ts +76 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.js +5 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/inspect.d.ts +96 -0
  19. package/dist/locks.d.ts +172 -0
  20. package/dist/logger.d.ts +24 -0
  21. package/dist/pool.d.ts +191 -0
  22. package/dist/queries.d.ts +65 -0
  23. package/dist/scheduler.d.ts +145 -0
  24. package/dist/sqlite-codes.d.ts +154 -0
  25. package/dist/supervisor.d.ts +17 -0
  26. package/dist/transaction.d.ts +61 -0
  27. package/dist/types.d.ts +642 -0
  28. package/dist/utils.d.ts +156 -0
  29. package/dist/worker/cloneable.d.ts +25 -0
  30. package/dist/worker/probes.d.ts +26 -0
  31. package/dist/worker/sqlite-code.d.ts +9 -0
  32. package/dist/worker/statement-cache.d.ts +36 -0
  33. package/dist/worker/wa-sqlite-async.wasm +0 -0
  34. package/dist/worker/wa-sqlite-jspi.wasm +0 -0
  35. package/dist/worker/wa-sqlite.wasm +0 -0
  36. package/dist/worker/worker.js +11 -0
  37. package/dist/worker/worker.js.map +1 -0
  38. package/package.json +46 -22
  39. package/dist/esm/index.js +0 -424
  40. package/dist/esm/rslib.config.d.ts +0 -2
  41. package/dist/esm/rstest.config.d.ts +0 -2
  42. package/dist/esm/src/client.d.ts +0 -332
  43. package/dist/esm/src/index.d.ts +0 -1
  44. package/dist/esm/src/orchestrator.d.ts +0 -87
  45. package/dist/esm/src/types.d.ts +0 -83
  46. package/dist/esm/src/utils.d.ts +0 -6
  47. /package/dist/{esm/src → worker}/worker.d.ts +0 -0
@@ -0,0 +1,642 @@
1
+ import type { SQLiteErrorCode } from './errors';
2
+ import type { SQLiteResultCode } from './sqlite-codes';
3
+ export type SQLiteWorkerMessageData<_T = unknown> = {
4
+ callId: number;
5
+ terminate?: boolean;
6
+ } & (SQLWorkerResultData[keyof SQLWorkerResultData] | {
7
+ type: 'error';
8
+ message: string;
9
+ });
10
+ export type SQLWorkerResultData<T = unknown> = {
11
+ open: {
12
+ success: boolean;
13
+ };
14
+ sql: {
15
+ type: 'partial';
16
+ result: T[];
17
+ } | {
18
+ type: 'one';
19
+ sizes: number[];
20
+ };
21
+ abort: {
22
+ type: 'done';
23
+ };
24
+ };
25
+ export declare const SharedArrayTypes: {
26
+ INT: number;
27
+ STRING: number;
28
+ OBJECT: number;
29
+ };
30
+ /**
31
+ * The savepoint a transaction asks the worker to handle around one query
32
+ * (spec 2026-09-11, D4/D5). `conclude` settles the savepoint the previous
33
+ * savepointed write left open — `release` keeps that write, `undo` rolls it
34
+ * back first — and `open` starts one for this query's own statement. Both run
35
+ * before the statement, conclusion first. Internal: no consumer sets it.
36
+ */
37
+ export type SavepointOp = {
38
+ conclude?: 'release' | 'undo';
39
+ open?: true;
40
+ };
41
+ type SQLOptions = {
42
+ chunkSize?: number;
43
+ /** Chunks the worker may send before waiting for a credit. Spec §3.2. */
44
+ credits?: number;
45
+ /** When true, the worker installs an async progress handler so an AbortSignal can stop a running step(). */
46
+ abortable?: boolean;
47
+ /** See `SavepointOp`. */
48
+ savepoint?: SavepointOp;
49
+ };
50
+ /**
51
+ * Where a worker fetches its `.wasm` from, when the consumer overrode it.
52
+ *
53
+ * Discriminated rather than a single string because the two forms differ in
54
+ * what they leave to the Emscripten glue. `base` is a directory: the glue
55
+ * supplies the file name (`locateFile('wa-sqlite-async.wasm')`), so nothing
56
+ * here names the three builds' files — and nothing has to be renamed when
57
+ * wa-sqlite renames one. `file` is the whole URL, typically content-hashed by
58
+ * a bundler, so the glue's file name is discarded.
59
+ *
60
+ * Always absolute: `resolveWasmLocation` (`src/utils.ts`) resolves against the
61
+ * page before the `open` message is posted, so the worker applies it without
62
+ * knowing what it was relative to.
63
+ */
64
+ export type WasmLocation = {
65
+ base: string;
66
+ } | {
67
+ file: string;
68
+ };
69
+ export type ClientMessageData = {
70
+ type: 'open';
71
+ file: string;
72
+ vfs: SQLiteVFS;
73
+ build?: SQLiteBuild;
74
+ pragmas?: Record<string, string>;
75
+ /** Statements retained per worker; see `src/client.ts`. Internal. */
76
+ statementCacheSize?: number;
77
+ /** Bytes retained per worker; see `src/client.ts`. Internal. */
78
+ statementCacheBytes?: number;
79
+ wasm?: WasmLocation;
80
+ /** Shared abort slots, one Int32 per worker. Isolated contexts only. */
81
+ abortSlots?: SharedArrayBuffer;
82
+ /** This worker's index into `abortSlots`. */
83
+ abortIndex?: number;
84
+ /**
85
+ * Features this worker must find before opening; it declines instead of
86
+ * opening when one is missing (spec 2026-09-13). Sent to slots of index
87
+ * ≥ 1 only, and only by a VFS that declares `singleConnectionWithout`.
88
+ */
89
+ declineWithout?: readonly PlatformFeature[];
90
+ /**
91
+ * Features worker 0 probes before opening, where the VFS is exclusive
92
+ * without one (spec 2026-09-15, §3.2): it reports them with `probed`,
93
+ * then loads nothing until `proceed`. Sent to slot 0 only, and only by a
94
+ * VFS that declares `exclusiveConnectionWithout`.
95
+ */
96
+ probeFirst?: readonly PlatformFeature[];
97
+ } | {
98
+ type: 'query';
99
+ callId: number;
100
+ sql: string;
101
+ params: unknown[];
102
+ options?: SQLOptions;
103
+ } | {
104
+ type: 'close';
105
+ callId: number;
106
+ } | {
107
+ type: 'credit';
108
+ callId: number;
109
+ n: number;
110
+ } | {
111
+ type: 'stop';
112
+ callId: number;
113
+ }
114
+ /** The client decided the connection lock; worker 0 may open (spec 2026-09-15). */
115
+ | {
116
+ type: 'proceed';
117
+ callId: number;
118
+ } | {
119
+ type: 'delete';
120
+ callId: number;
121
+ file: string;
122
+ vfs: SQLiteVFS;
123
+ build?: SQLiteBuild;
124
+ wasm?: WasmLocation;
125
+ };
126
+ export type WorkerMessageData = {
127
+ type: 'ready';
128
+ callId: number;
129
+ }
130
+ /**
131
+ * The worker found a feature of `declineWithout` missing and opened nothing:
132
+ * the environment caps the pool (spec 2026-09-13).
133
+ */
134
+ | {
135
+ type: 'declined';
136
+ callId: number;
137
+ missing: PlatformFeature;
138
+ }
139
+ /**
140
+ * Worker 0's answer to `probeFirst`: the first feature missing, or null. It
141
+ * opens nothing until the client sends `proceed` (spec 2026-09-15, §3.2).
142
+ */
143
+ | {
144
+ type: 'probed';
145
+ callId: number;
146
+ missing: PlatformFeature | null;
147
+ } | {
148
+ type: 'chunk';
149
+ callId: number;
150
+ data: unknown[];
151
+ } | {
152
+ type: 'done';
153
+ callId: number;
154
+ affected: number;
155
+ /**
156
+ * Statements compiled while serving this query — zero on a cache hit.
157
+ * Rides the same message as `affected` rather than opening a channel:
158
+ * the effect this instruments is a count, not a duration (`mem:lessons`,
159
+ * "for a sub-millisecond effect, count the round trips").
160
+ */
161
+ prepared: number;
162
+ /**
163
+ * Whether the connection is inside a transaction once this query has
164
+ * ended — `sqlite3_get_autocommit() === 0`. SQLite can leave a
165
+ * transaction by itself: an interrupted INSERT/UPDATE/DELETE rolls the
166
+ * whole transaction back. Absent when the worker could not read it.
167
+ */
168
+ inTransaction?: boolean | undefined;
169
+ } | {
170
+ type: 'error';
171
+ callId: number;
172
+ message: string;
173
+ cause?: unknown;
174
+ /** SQLite's numeric result code, when the failure came from SQLite. */
175
+ sqliteCode?: SQLiteResultCode;
176
+ /**
177
+ * SQLite's extended result code, read in the worker where the statement
178
+ * failed (spec 2026-09-14, §5.1). Sent by the query path only, and
179
+ * unfiltered: this is exactly what SQLite reported, including a value
180
+ * equal to `sqliteCode` (no subtype). The client is what drops it in
181
+ * that case (D9); when SQLite does report a subtype,
182
+ * `(sqliteExtendedCode & 0xff) === sqliteCode`.
183
+ */
184
+ sqliteExtendedCode?: number;
185
+ /**
186
+ * A code this library minted, when the worker knows the cause. The
187
+ * generic path by which a worker-side error keeps its code across the
188
+ * boundary — `worker.ts` copies it off any thrown error carrying one, so
189
+ * this is a structural contract and not a hook for one class.
190
+ *
191
+ * **Nothing sets it today.** `WorkerQueryTimeout` was its only producer
192
+ * and it went with the execution budget when `timeout` became a
193
+ * client-side wall-clock deadline. Kept rather than deleted: it is the
194
+ * twin of `sqliteCode` above, which is load-bearing, and rebuilding it
195
+ * would cost the same three sites it occupies.
196
+ */
197
+ errorCode?: SQLiteErrorCode;
198
+ /**
199
+ * Whether the connection is inside a transaction once this query has
200
+ * ended — `sqlite3_get_autocommit() === 0`. SQLite can leave a
201
+ * transaction by itself: an interrupted INSERT/UPDATE/DELETE rolls the
202
+ * whole transaction back. Absent when the worker could not read it.
203
+ */
204
+ inTransaction?: boolean | undefined;
205
+ } | {
206
+ type: 'closed';
207
+ callId: number;
208
+ } | {
209
+ type: 'deleted';
210
+ callId: number;
211
+ }
212
+ /** The delete worker found nothing at that name; deleteDatabase turns it into DATABASE_NOT_FOUND. */
213
+ | {
214
+ type: 'not-found';
215
+ } | {
216
+ type: 'open-error';
217
+ callId: number;
218
+ message: string;
219
+ cause?: unknown;
220
+ /** SQLite's numeric result code, when the failure came from SQLite. */
221
+ sqliteCode?: SQLiteResultCode;
222
+ };
223
+ /** Which wa-sqlite WebAssembly build a worker loads. */
224
+ export type SQLiteBuild = 'sync' | 'async' | 'jspi';
225
+ /**
226
+ * What each build needs from the engine beyond plain WebAssembly.
227
+ *
228
+ * `satisfies Record<SQLiteBuild, …>` and not `SQLiteBuild = keyof typeof …`:
229
+ * the check must run in this direction. Adding a build to the union then fails
230
+ * to compile until its requirements are declared, where `keyof` would let a
231
+ * forgotten entry mean silently that the build does not exist. `VFS_CAPABILITIES`
232
+ * derives `SQLiteVFS` from its keys because it *is* the VFS registry; the build
233
+ * registry is `WA_SQLITE_BUILDS` in the worker, and this table describes one
234
+ * attribute of builds rather than the builds themselves.
235
+ */
236
+ export declare const BUILD_REQUIREMENTS: {
237
+ readonly sync: readonly [];
238
+ readonly async: readonly [];
239
+ readonly jspi: readonly ["jspi"];
240
+ };
241
+ /**
242
+ * Platform features a build USES when present and works without, at a cost —
243
+ * the symmetric of `degradesWithout` on a VFS, at the level where this one
244
+ * actually lives. The `sync` build cannot carry an abort into a running
245
+ * `step()` without a `SharedArrayBuffer`, and there is no SharedArrayBuffer
246
+ * outside a cross-origin isolated context: measured 2026-09-04, it is not
247
+ * restricted there, it is absent. Nothing here names COOP/COEP or
248
+ * Document-Isolation-Policy: any of them satisfies the probe, and one of them
249
+ * is Chrome-only.
250
+ */
251
+ export declare const BUILD_DEGRADES_WITHOUT: {
252
+ readonly sync: readonly ["cross-origin-isolated"];
253
+ readonly async: readonly [];
254
+ readonly jspi: readonly [];
255
+ };
256
+ /**
257
+ * A platform feature a VFS may need. Which browser versions ship each one is
258
+ * documentation data, not runtime data, so it lives in the VFS.md generator
259
+ * (`scripts/render-vfs-matrix.ts`) with its sources — not here, where it would
260
+ * ship to every consumer for nothing.
261
+ */
262
+ export type PlatformFeature = 'opfs' | 'readwrite-unsafe' | 'jspi' | 'writable-stream' | 'cross-origin-isolated';
263
+ /** Where a VFS keeps the database. */
264
+ export type VFSStorage = 'opfs' | 'indexeddb' | 'memory';
265
+ /**
266
+ * How a VFS arranges a database in its storage — which is not the same
267
+ * question as `storage`, and cannot be derived from it: `AccessHandlePoolVFS`
268
+ * is `storage: 'opfs'` yet keeps opaque, randomly named slot files whose
269
+ * association with a SQLite path lives in a header inside each file.
270
+ *
271
+ * `deleteDatabase` reads this to decide whether the database is also an OPFS
272
+ * entry it can remove by name after `jDelete` — the pass that covers the two
273
+ * VFS whose `jDelete` does not delete. A wrong value here is a deletion that
274
+ * reports success over an intact file.
275
+ */
276
+ export type VFSLayout = 'opfs-path' | 'opfs-pool' | 'idb-store' | 'memory';
277
+ /** How much of the database a VFS keeps resident in RAM. */
278
+ export type VFSMemoryModel = 'page-cache' | 'whole-database';
279
+ /** What a VFS can and cannot do. One entry per VFS, and no second table. */
280
+ export type VFSCapability = {
281
+ /** Builds this VFS can run on, most preferred first. */
282
+ readonly builds: readonly [SQLiteBuild, ...SQLiteBuild[]];
283
+ /** Largest pool this VFS supports; `null` when unbounded. */
284
+ readonly maxPoolSize: number | null;
285
+ /** Why the cap exists. Required whenever `maxPoolSize` is not null. */
286
+ readonly poolLimitReason: string | null;
287
+ /** Whether several connections may share one database. */
288
+ readonly multiConnection: boolean;
289
+ /** Whether data outlives `close()`. */
290
+ readonly persistent: boolean;
291
+ /**
292
+ * `page-cache`: only SQLite's page cache is resident, bounded by
293
+ * `PRAGMA cache_size`. `whole-database`: the entire database is resident,
294
+ * and `poolSize` multiplies it.
295
+ */
296
+ readonly memoryModel: VFSMemoryModel;
297
+ /** Where the database actually lives. */
298
+ readonly storage: VFSStorage;
299
+ /** How the database is arranged within that storage. */
300
+ readonly layout: VFSLayout;
301
+ /**
302
+ * Whether this VFS takes its OPFS access handle in the EXCLUSIVE mode —
303
+ * `createSyncAccessHandle()` with no `mode`, rather than
304
+ * `mode: 'readwrite-unsafe'`.
305
+ *
306
+ * It decides whether an acquisition has to be retried. A terminated context
307
+ * releases its Web Locks at once but keeps its OPFS access handles for up to
308
+ * ~2 s on Chromium (HANDLE-CORPSE, `mem:measurements`), so a VFS taking an
309
+ * exclusive handle can meet a file held by something that answers nothing:
310
+ * no lock to wait on, no owner to ask, only time to wait out. Where
311
+ * `readwrite-unsafe` is used a second handle is granted regardless, and a
312
+ * dead holder blocks nobody.
313
+ *
314
+ * Declared rather than detected, because the error is not available where the
315
+ * decision has to be made: wa-sqlite's `jOpen` swallows it (measured
316
+ * 2026-09-18) and SQLite reports a bare `SQLITE_CANTOPEN`. Where the error IS
317
+ * available — VFS instantiation — `createVfsInstance` tests it directly and
318
+ * needs no declaration.
319
+ *
320
+ * NOT declared for `OPFSAdaptiveVFS` and `OPFSWriteAheadVFS`, which ask for
321
+ * `readwrite-unsafe` and fall back to an exclusive handle only on an engine
322
+ * that lacks it. That combination is real but out of reach: Firefox releases
323
+ * a dead worker's handle in 1-6 ms (HANDLE-ORPHAN), a window nothing loses.
324
+ */
325
+ readonly exclusiveFileHandle: boolean;
326
+ /**
327
+ * Platform features without which this VFS cannot work at all.
328
+ *
329
+ * `readwrite-unsafe` is the one that bites: WebIDL ignores the unknown
330
+ * dictionary member on engines that do not implement it, so the handle
331
+ * silently opens exclusive, and a second connection then waits or fails
332
+ * depending on the VFS — see `degradesWithout` and `singleConnectionWithout`.
333
+ * Declaring it is what lets the conformance suite probe for it and skip,
334
+ * instead of leaving it to surface as a 60-second timeout.
335
+ */
336
+ readonly requires: readonly PlatformFeature[];
337
+ /**
338
+ * Platform features this VFS uses when present and works without, at a cost.
339
+ *
340
+ * `OPFSAdaptiveVFS` is the case this field exists for. Without
341
+ * `readwrite-unsafe` it rotates a single exclusive access handle between
342
+ * connections instead of holding one each. That works — Firefox is the engine
343
+ * the browser suite exercises it on — but a connection in a long
344
+ * uninterruptible statement holds the handle, and every other connection to
345
+ * the database, in another client or tab, waits for it. Within one client it
346
+ * runs a single worker there: see `singleConnectionWithout`.
347
+ *
348
+ * Without this distinction, a support table derived from browser specs would
349
+ * mark that VFS broken everywhere outside Chromium, when it merely degrades.
350
+ */
351
+ readonly degradesWithout: readonly PlatformFeature[];
352
+ /**
353
+ * Platform features without which a pool of more than one worker buys this
354
+ * VFS nothing, so it runs on one (spec 2026-09-13, §3 and §10). Either the
355
+ * VFS holds its database file exclusively for a connection's whole life and
356
+ * a second worker cannot open at all (`OPFSWriteAheadVFS`), or it rotates one
357
+ * exclusive access handle between connections and a second worker only waits
358
+ * its turn (`OPFSAdaptiveVFS` — measured 2026-09-14 on Firefox: a pool of one
359
+ * was faster at startup and on bursts of reads, and equal everywhere else).
360
+ * The pool's surplus workers probe the feature before loading anything and
361
+ * decline (`src/worker/probes.ts`); every feature listed needs a probe there.
362
+ */
363
+ readonly singleConnectionWithout: readonly PlatformFeature[];
364
+ /**
365
+ * Files this VFS keeps beside the database, by suffix, beyond the three every
366
+ * layout may have (`''`, `-journal`, `-wal`). `deleteDatabase` removes them
367
+ * with the rest; a file missing from this list outlives its database.
368
+ *
369
+ * `OPFSWriteAheadVFS` keeps its write-ahead log in two files of its own,
370
+ * `-wa0` and `-wa1` (wa-sqlite's `#getWriteAheadNameFromDbName`) — measured
371
+ * left behind by every deletion until 2026-09-14.
372
+ */
373
+ readonly extraFileSuffixes: readonly string[];
374
+ /**
375
+ * Whether every statement on this VFS must hand its worker back to the event
376
+ * loop while it runs, abortable or not.
377
+ *
378
+ * `IDBBatchAtomicVFS` is why it exists. Its `jLock` opens a readwrite
379
+ * IndexedDB transaction on reaching SHARED, and IndexedDB commits a
380
+ * transaction only once its thread returns to the event loop. A worker inside
381
+ * one long statement never did, so every other connection's read queued
382
+ * behind it until the statement ended — measured 2026-09-14 on both engines
383
+ * (`mem:measurements`, IDB-SIGNAL). The worker then runs its progress handler
384
+ * on every statement, a task turn every `PROGRESS_OPS` VM ops, which measured
385
+ * no cost. The `sync` build cannot yield and ignores it.
386
+ */
387
+ readonly yieldsDuringStatements: boolean;
388
+ /**
389
+ * PRAGMAs this library applies on open for this VFS.
390
+ *
391
+ * Merged UNDER the consumer's `pragmas`, so any key they set wins and they
392
+ * never lose a default by setting an unrelated one — `foreign_keys` is the
393
+ * common case, and replacing rather than merging would silently disable
394
+ * everything below it.
395
+ *
396
+ * The bar is deliberately high, and almost nothing clears it: **more
397
+ * performance without less reliability, sourced rather than guessed.** Three
398
+ * things were weighed and rejected. `journal_mode=wal` universally, because
399
+ * no VFS here implements `xShmMap` and upstream gives write-ahead logging to
400
+ * `OPFSWriteAheadVFS` alone, inside the VFS and unreachable by pragma.
401
+ * `synchronous=normal`, because relaxing durability spends the consumer's
402
+ * data, not their milliseconds. And `cache_size`, because raising it changes
403
+ * a mode without a measurable gain — Firefox showed none at all, and the
404
+ * heap it can then reach is never given back (measured 2026-09-02).
405
+ */
406
+ readonly defaultPragmas: Readonly<Record<string, string>>;
407
+ /**
408
+ * Whether this VFS enforces an origin-wide exclusive connection lock for the
409
+ * client's lifetime.
410
+ *
411
+ * When `true`, `createSQLiteClient` acquires a `bsq:conn:…` Web Lock on first
412
+ * use. A second client that attempts to open the same database receives `DATABASE_IN_USE`
413
+ * immediately on its first query instead of silently reading a frozen, broken
414
+ * view. This field is the only thing standing between a consumer and an
415
+ * unfalsifiable silent failure — `SELECT 1` and even
416
+ * `SELECT count(*) FROM sqlite_master` pass on a broken second client.
417
+ *
418
+ * `true` only for `AccessHandlePoolVFS`, whose OPFS access-handle pool is not
419
+ * sharable across connections (measured AHP-2TAB, 2026-09-01).
420
+ * `false` for `IDBMirrorVFS` — despite `multiConnection: false` — because two
421
+ * clients on that VFS DO share data over its origin-wide `BroadcastChannel`
422
+ * (measured 2026-09-01, 3/3 both engines). `multiConnection: false` there marks
423
+ * concurrent-writer unsafety, not isolation.
424
+ * `false` for the memory VFS, which are isolated by construction and have
425
+ * nothing to exclude.
426
+ *
427
+ * `VFS_CAPABILITIES` is the single source of truth the client guard, the
428
+ * conformance suite, the VFS.md generator and the benchmark page all read.
429
+ * The gate is by this declaration, not by VFS name.
430
+ */
431
+ readonly exclusiveConnection: boolean;
432
+ /**
433
+ * Platform features without which this VFS holds its database file
434
+ * exclusively for a connection's whole life, across the origin — so the
435
+ * client takes `bsq:conn` exclusively, as for `exclusiveConnection`, and a
436
+ * second client gets `DATABASE_IN_USE` (spec 2026-09-15).
437
+ *
438
+ * `OPFSWriteAheadVFS` without `readwrite-unsafe`: upstream's VFS requires the
439
+ * mode and keeps its three access handles for the connection's life, so
440
+ * nothing else can open the file — every query of a second client failed
441
+ * with WORKER_CRASHED on Firefox, 20/20 per shape (2026-09-15).
442
+ *
443
+ * The page cannot probe these features, so worker 0 probes them before
444
+ * opening (`src/worker/probes.ts`): every feature listed needs a probe there,
445
+ * and must also be in `singleConnectionWithout`, whose surplus workers
446
+ * decline before they touch the file.
447
+ */
448
+ readonly exclusiveConnectionWithout: readonly PlatformFeature[];
449
+ };
450
+ /**
451
+ * The single source of truth for VFS selection. `SQLiteVFS` is derived from its
452
+ * keys, `worker/worker.ts` must supply a loader for every key, the guards in
453
+ * `client.ts` read it, the conformance suite gates its scenarios on it, and the
454
+ * VFS.md table is generated from it. Nothing may hold a second copy.
455
+ *
456
+ * Build order is a decision per VFS, not a rule: `sync` is both the fastest and
457
+ * the most portable build, so it leads wherever supported; `OPFSAdaptiveVFS`
458
+ * cannot use it and leads with `async` because `jspi` is Chromium-only.
459
+ *
460
+ * Every declared build combination is verified by running it against the pinned
461
+ * wa-sqlite v1.1.2, never copied from upstream's table.
462
+ */
463
+ export declare const VFS_CAPABILITIES: {
464
+ readonly OPFSWriteAheadVFS: {
465
+ readonly builds: readonly ["sync", "async", "jspi"];
466
+ readonly maxPoolSize: null;
467
+ readonly poolLimitReason: null;
468
+ readonly multiConnection: true;
469
+ readonly persistent: true;
470
+ readonly memoryModel: 'page-cache';
471
+ readonly storage: 'opfs';
472
+ readonly layout: 'opfs-path';
473
+ readonly exclusiveFileHandle: false;
474
+ readonly requires: readonly ["opfs"];
475
+ readonly degradesWithout: readonly ["readwrite-unsafe"];
476
+ readonly singleConnectionWithout: readonly ["readwrite-unsafe"];
477
+ readonly extraFileSuffixes: readonly ["-wa0", "-wa1"];
478
+ readonly yieldsDuringStatements: false;
479
+ readonly exclusiveConnection: false;
480
+ readonly exclusiveConnectionWithout: readonly ["readwrite-unsafe"];
481
+ readonly defaultPragmas: {};
482
+ };
483
+ readonly OPFSAdaptiveVFS: {
484
+ readonly builds: readonly ["async", "jspi"];
485
+ readonly maxPoolSize: null;
486
+ readonly poolLimitReason: null;
487
+ readonly multiConnection: true;
488
+ readonly persistent: true;
489
+ readonly memoryModel: 'page-cache';
490
+ readonly storage: 'opfs';
491
+ readonly layout: 'opfs-path';
492
+ readonly exclusiveFileHandle: false;
493
+ readonly requires: readonly ["opfs"];
494
+ readonly degradesWithout: readonly ["readwrite-unsafe"];
495
+ readonly singleConnectionWithout: readonly ["readwrite-unsafe"];
496
+ readonly extraFileSuffixes: readonly [];
497
+ readonly yieldsDuringStatements: false;
498
+ readonly exclusiveConnection: false;
499
+ readonly exclusiveConnectionWithout: readonly [];
500
+ readonly defaultPragmas: {};
501
+ };
502
+ readonly OPFSCoopSyncVFS: {
503
+ readonly builds: readonly ["sync", "async", "jspi"];
504
+ readonly maxPoolSize: 1;
505
+ readonly poolLimitReason: 'it rotates one exclusive access handle between connections, so another worker only waits its turn';
506
+ readonly multiConnection: true;
507
+ readonly persistent: true;
508
+ readonly memoryModel: 'page-cache';
509
+ readonly storage: 'opfs';
510
+ readonly layout: 'opfs-path';
511
+ readonly exclusiveFileHandle: true;
512
+ readonly requires: readonly ["opfs"];
513
+ readonly degradesWithout: readonly [];
514
+ readonly singleConnectionWithout: readonly [];
515
+ readonly extraFileSuffixes: readonly [];
516
+ readonly yieldsDuringStatements: false;
517
+ readonly exclusiveConnection: false;
518
+ readonly exclusiveConnectionWithout: readonly [];
519
+ readonly defaultPragmas: {};
520
+ };
521
+ readonly AccessHandlePoolVFS: {
522
+ readonly builds: readonly ["sync", "async", "jspi"];
523
+ readonly maxPoolSize: 1;
524
+ readonly poolLimitReason: 'it cannot share access handles between connections';
525
+ readonly multiConnection: false;
526
+ readonly persistent: true;
527
+ readonly memoryModel: 'page-cache';
528
+ readonly storage: 'opfs';
529
+ readonly layout: 'opfs-pool';
530
+ readonly exclusiveFileHandle: true;
531
+ readonly requires: readonly ["opfs"];
532
+ readonly degradesWithout: readonly [];
533
+ readonly singleConnectionWithout: readonly [];
534
+ readonly extraFileSuffixes: readonly [];
535
+ readonly yieldsDuringStatements: false;
536
+ readonly exclusiveConnection: true;
537
+ readonly exclusiveConnectionWithout: readonly [];
538
+ readonly defaultPragmas: {
539
+ readonly locking_mode: 'exclusive';
540
+ readonly journal_mode: 'wal';
541
+ };
542
+ };
543
+ readonly IDBBatchAtomicVFS: {
544
+ readonly builds: readonly ["async", "jspi"];
545
+ readonly maxPoolSize: null;
546
+ readonly poolLimitReason: null;
547
+ readonly multiConnection: true;
548
+ readonly persistent: true;
549
+ readonly memoryModel: 'page-cache';
550
+ readonly storage: 'indexeddb';
551
+ readonly layout: 'idb-store';
552
+ readonly exclusiveFileHandle: false;
553
+ readonly requires: readonly [];
554
+ readonly degradesWithout: readonly [];
555
+ readonly singleConnectionWithout: readonly [];
556
+ readonly extraFileSuffixes: readonly [];
557
+ readonly yieldsDuringStatements: true;
558
+ readonly exclusiveConnection: false;
559
+ readonly exclusiveConnectionWithout: readonly [];
560
+ readonly defaultPragmas: {};
561
+ };
562
+ readonly IDBMirrorVFS: {
563
+ readonly builds: readonly ["async", "jspi"];
564
+ readonly maxPoolSize: 1;
565
+ readonly poolLimitReason: 'its pages are mirrored per worker and commits propagate asynchronously, so a larger pool reads stale data or fails outright';
566
+ readonly multiConnection: false;
567
+ readonly persistent: true;
568
+ readonly memoryModel: 'whole-database';
569
+ readonly storage: 'indexeddb';
570
+ readonly layout: 'idb-store';
571
+ readonly exclusiveFileHandle: false;
572
+ readonly requires: readonly [];
573
+ readonly degradesWithout: readonly [];
574
+ readonly singleConnectionWithout: readonly [];
575
+ readonly extraFileSuffixes: readonly [];
576
+ readonly yieldsDuringStatements: false;
577
+ readonly exclusiveConnection: false;
578
+ readonly exclusiveConnectionWithout: readonly [];
579
+ readonly defaultPragmas: {};
580
+ };
581
+ readonly OPFSAnyContextVFS: {
582
+ readonly builds: readonly ["async", "jspi"];
583
+ readonly maxPoolSize: null;
584
+ readonly poolLimitReason: null;
585
+ readonly multiConnection: true;
586
+ readonly persistent: true;
587
+ readonly memoryModel: 'page-cache';
588
+ readonly storage: 'opfs';
589
+ readonly layout: 'opfs-path';
590
+ readonly exclusiveFileHandle: false;
591
+ readonly requires: readonly ["opfs", "writable-stream"];
592
+ readonly degradesWithout: readonly [];
593
+ readonly singleConnectionWithout: readonly [];
594
+ readonly extraFileSuffixes: readonly [];
595
+ readonly yieldsDuringStatements: false;
596
+ readonly exclusiveConnection: false;
597
+ readonly exclusiveConnectionWithout: readonly [];
598
+ readonly defaultPragmas: {};
599
+ };
600
+ readonly MemoryVFS: {
601
+ readonly builds: readonly ["sync", "async", "jspi"];
602
+ readonly maxPoolSize: 1;
603
+ readonly poolLimitReason: 'its pages live in the worker that opened them, so a larger pool would open independent databases that diverge silently';
604
+ readonly multiConnection: false;
605
+ readonly persistent: false;
606
+ readonly memoryModel: 'whole-database';
607
+ readonly storage: 'memory';
608
+ readonly layout: 'memory';
609
+ readonly exclusiveFileHandle: false;
610
+ readonly requires: readonly [];
611
+ readonly degradesWithout: readonly [];
612
+ readonly singleConnectionWithout: readonly [];
613
+ readonly extraFileSuffixes: readonly [];
614
+ readonly yieldsDuringStatements: false;
615
+ readonly exclusiveConnection: false;
616
+ readonly exclusiveConnectionWithout: readonly [];
617
+ readonly defaultPragmas: {};
618
+ };
619
+ readonly MemoryAsyncVFS: {
620
+ readonly builds: readonly ["async", "jspi"];
621
+ readonly maxPoolSize: 1;
622
+ readonly poolLimitReason: 'its pages live in the worker that opened them, so a larger pool would open independent databases that diverge silently';
623
+ readonly multiConnection: false;
624
+ readonly persistent: false;
625
+ readonly memoryModel: 'whole-database';
626
+ readonly storage: 'memory';
627
+ readonly layout: 'memory';
628
+ readonly exclusiveFileHandle: false;
629
+ readonly requires: readonly [];
630
+ readonly degradesWithout: readonly [];
631
+ readonly singleConnectionWithout: readonly [];
632
+ readonly extraFileSuffixes: readonly [];
633
+ readonly yieldsDuringStatements: false;
634
+ readonly exclusiveConnection: false;
635
+ readonly exclusiveConnectionWithout: readonly [];
636
+ readonly defaultPragmas: {};
637
+ };
638
+ };
639
+ export type SQLiteVFS = keyof typeof VFS_CAPABILITIES;
640
+ /** The build used when the caller does not name one. */
641
+ export declare const defaultBuildFor: (vfs: SQLiteVFS) => SQLiteBuild;
642
+ export {};