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
package/NOTICE ADDED
@@ -0,0 +1,56 @@
1
+ THIRD-PARTY NOTICES
2
+ ===================
3
+
4
+ browser-sqlite is distributed under the MIT License; see LICENSE.
5
+
6
+ Its published worker artifact (dist/worker/worker.js) has third-party code
7
+ bundled into it, and ships compiled WebAssembly built from third-party
8
+ sources (dist/worker/wa-sqlite.wasm, wa-sqlite-async.wasm, wa-sqlite-jspi.wasm).
9
+ The notices below travel with those files and must be preserved in any
10
+ redistribution.
11
+
12
+
13
+ -------------------------------------------------------------------------------
14
+ wa-sqlite — https://github.com/rhashimoto/wa-sqlite
15
+ -------------------------------------------------------------------------------
16
+
17
+ The JavaScript glue and the VFS implementations bundled into
18
+ dist/worker/worker.js, and the .wasm binaries beside it, are produced by
19
+ wa-sqlite.
20
+
21
+ MIT License
22
+
23
+ Copyright (c) 2023 Roy T. Hashimoto
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining a copy
26
+ of this software and associated documentation files (the "Software"), to deal
27
+ in the Software without restriction, including without limitation the rights
28
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
+ copies of the Software, and to permit persons to whom the Software is
30
+ furnished to do so, subject to the following conditions:
31
+
32
+ The above copyright notice and this permission notice shall be included in all
33
+ copies or substantial portions of the Software.
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41
+ SOFTWARE.
42
+
43
+
44
+ -------------------------------------------------------------------------------
45
+ SQLite — https://sqlite.org
46
+ -------------------------------------------------------------------------------
47
+
48
+ The .wasm binaries are builds of SQLite. SQLite is in the public domain and
49
+ requires no attribution; the customary blessing is reproduced here.
50
+
51
+ The author disclaims copyright to this source code. In place of
52
+ a legal notice, here is a blessing:
53
+
54
+ May you do good and not evil.
55
+ May you find forgiveness for yourself and forgive others.
56
+ May you share freely, never taking more than you give.
package/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  A persistent SQLite database that lives in your browser — yes, for real. Powered by [wa-sqlite](https://github.com/rhashimoto/wa-sqlite) (WebAssembly), built for (read) concurrency.
4
4
 
5
+ A client stores its data through a wa-sqlite VFS, which decides where that data lives.
6
+ **[Read the VFS page](VFS.md)** to compare them, then
7
+ **[run the benchmarks in your own browser](https://lalexdotcom.github.io/browser-sqlite/)**.
8
+
5
9
  ## Install
6
10
 
7
11
  ```bash
@@ -10,152 +14,156 @@ npm install browser-sqlite
10
14
  pnpm add browser-sqlite
11
15
  ```
12
16
 
13
- Requires a bundler that supports Web Workers with dynamic imports (Rsbuild, webpack 5, Vite 3+).
17
+ Requires a bundler that supports Web Workers with dynamic imports or no bundler at all.
18
+
19
+ <details>
20
+ <summary><b>Bundler Configuration</b></summary>
14
21
 
15
- ## VFS Selection
22
+ Works with no configuration under **rsbuild 1+**, **rspack 1+**, **Parcel 2+**, **Vite 8+**, **webpack 5.101+** — and with no bundler at all.
16
23
 
17
- browser-sqlite delegates storage to a wa-sqlite Virtual File System (VFS). Choose based on browser support and storage requirements:
24
+ Works under **Vite 6.1 to 7** with the following config, which only the dev server needs:
18
25
 
19
- | VFS | Storage | Constraint | When to use |
20
- |-----|---------|------------|-------------|
21
- | `OPFSPermutedVFS` **(default)** | OPFS | None — supports `poolSize >= 1` | General purpose. Best choice for most applications. |
22
- | `OPFSAdaptiveVFS` | OPFS | Requires JSPI (Chromium 126+) | When JSPI is available and adaptive sync strategy is desired. |
23
- | `OPFSCoopSyncVFS` | OPFS | None — cooperative sync, no JSPI required | Broader browser compatibility fallback when JSPI is unavailable. |
24
- | `AccessHandlePoolVFS` | OPFS | **`poolSize` must be `1`** — throws otherwise | Single-connection scenarios requiring access handle pool semantics. |
25
- | `IDBBatchAtomicVFS` | IndexedDB | None | Fallback when OPFS is unavailable (older browsers, some mobile environments). |
26
+ ```typescript
27
+ // vite.config.ts
28
+ export default defineConfig({
29
+ optimizeDeps: { exclude: ['browser-sqlite'] },
30
+ });
31
+ ```
26
32
 
27
- When `vfs` is omitted, `OPFSPermutedVFS` is used.
33
+ Another bundler will likely work — the worker and its `.wasm` are reached through plain, statically analysable URLs — but may need configuration of its own.
28
34
 
29
- For a detailed VFS comparison, see the [wa-sqlite VFS comparison](https://github.com/rhashimoto/wa-sqlite/tree/master/src/examples#vfs-comparison).
35
+ The `.wasm` are read from beside `worker.js`. If a build separates them, or you move them by hand, point at them with [`wasmUrl`](API.md#options).
36
+ </details>
37
+
38
+ ## Browser support
39
+
40
+ | Chrome | Firefox | Safari |
41
+ |---|---|---|
42
+ | 92+ | 95+ | 15.4+ |
43
+
44
+ Cross-origin isolation is worth adding where you control your headers: it is what lets an
45
+ aborted call stop a running statement when using a VFS with `sync` build. See
46
+ [Aborting a call](#aborting-a-call).
30
47
 
31
48
  ## Usage
32
49
 
33
- ### Initialize
50
+ Read the [detailed API documentation](API.md) for the full description.
34
51
 
35
52
  ```typescript
36
53
  import { createSQLiteClient } from 'browser-sqlite';
37
54
 
38
- const db = createSQLiteClient('myapp.sqlite', {
39
- poolSize: 2, // number of worker threads (default: 2)
40
- vfs: 'OPFSPermutedVFS', // VFS selection (default: 'OPFSPermutedVFS')
41
- pragmas: { // SQLite PRAGMAs applied on open
42
- journal_mode: 'WAL',
43
- synchronous: 'NORMAL',
44
- },
45
- });
46
- ```
55
+ const db = createSQLiteClient('myapp.sqlite', { vfs: 'OPFSAdaptiveVFS' });
47
56
 
48
- `createSQLiteClient` spawns `poolSize` Web Worker threads immediately. Workers reach READY state asynchronously queries made before workers are ready are queued automatically.
57
+ await db.write('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)');
58
+ await db.write('INSERT INTO users (name) VALUES (?)', ['Alice']);
49
59
 
50
- ### Read
60
+ const users = await db.read<{ id: number; name: string }>('SELECT id, name FROM users');
51
61
 
52
- ```typescript
53
- type User = { id: number; name: string };
62
+ for await (const row of db.stream<{ id: number; name: string }>('SELECT * FROM users')) {
63
+ process(row);
64
+ }
54
65
 
55
- const users = await db.read<User>(
56
- 'SELECT id, name FROM users WHERE active = ?',
57
- [1],
58
- );
59
- // users: User[]
66
+ await db.close();
60
67
  ```
61
68
 
62
- Read queries are dispatched to any available worker, enabling concurrent reads.
69
+ [*client*.id](API.md#clientid) · [*client*.name](API.md#clientname) · [*client*.file](API.md#clientfile) · [*client*.vfs](API.md#clientvfs) · [*client*.build](API.md#clientbuild) · [*client*.poolSize](API.md#clientpoolsize)
63
70
 
64
- ### Write
71
+ [createSQLiteClient()](API.md#createsqliteclient) · [*client*.read()](API.md#clientread) · [*client*.write()](API.md#clientwrite) · [*client*.stream()](API.md#clientstream) · [*client*.chunk()](API.md#clientchunk) · [*client*.first()](API.md#clientfirst) · [*client*.transaction()](API.md#clienttransaction) · [*client*.bulkWrite()](API.md#clientbulkwrite) · [*client*.output()](API.md#clientoutput) · [*client*.inspect()](API.md#clientinspect) · [*client*.close()](API.md#clientclose) · [deleteDatabase()](API.md#deletedatabase) · [inspectDatabase()](API.md#inspectdatabase)
65
72
 
66
- ```typescript
67
- const { affected } = await db.write(
68
- 'INSERT INTO users (name, email) VALUES (?, ?)',
69
- ['Alice', 'alice@example.com'],
70
- );
71
- // affected: number of rows inserted
72
- ```
73
+ ## Storage
73
74
 
74
- Write queries are serialized through a dedicated writer worker — only one write executes at a time.
75
+ The VFS decides *where* your database is written.
76
+ [See every available VFS on the dedicated page](VFS.md), with their pros, their cons, their
77
+ limitations and their browser compatibility.
75
78
 
76
- ### Stream (large result sets)
79
+ `OPFSWriteAheadVFS` and `OPFSAdaptiveVFS` are the recommended options.
77
80
 
78
- ```typescript
79
- // Worker is held for the full generator lifetime — always exhaust or break.
80
- for await (const chunk of db.stream<User>(
81
- 'SELECT * FROM large_table',
82
- [],
83
- { chunkSize: 100 },
84
- )) {
85
- processChunk(chunk); // chunk is User[]
86
- }
87
- ```
81
+ [`OPFSWriteAheadVFS`](VFS.md#opfswriteaheadvfs) · [`OPFSAdaptiveVFS`](VFS.md#opfsadaptivevfs) · [`OPFSCoopSyncVFS`](VFS.md#opfscoopsyncvfs) · [`AccessHandlePoolVFS`](VFS.md#accesshandlepoolvfs) · [`IDBBatchAtomicVFS`](VFS.md#idbbatchatomicvfs) · [`IDBMirrorVFS`](VFS.md#idbmirrorvfs) · [`OPFSAnyContextVFS`](VFS.md#opfsanycontextvfs) · [`MemoryVFS`](VFS.md#memoryvfs) · [`MemoryAsyncVFS`](VFS.md#memoryasyncvfs)
88
82
 
89
- `stream()` yields rows in chunks without buffering the full result set in memory.
83
+ ## Guarantees
90
84
 
91
- ### One (first row)
85
+ ### Reads run concurrently
92
86
 
93
- ```typescript
94
- const user = await db.one<User>(
95
- 'SELECT * FROM users WHERE id = ?',
96
- [42],
97
- );
98
- // user: User | undefined
99
- ```
87
+ Every read is dispatched to whichever worker in the pool is free, so several run at once.
88
+ Writes take a dedicated writer worker instead, one at a time.
100
89
 
101
- `one()` automatically aborts after the first result row. Use it for lookups by primary key or unique field.
90
+ ### Read-your-own-writes
102
91
 
103
- ### Advanced
92
+ It holds within a tab and across tabs. Once a write has resolved, any read issued afterwards
93
+ observes it — from that client, from any other client in the same tab, and from any other tab
94
+ on the same database, whatever the pool size. A worker that has not yet observed the latest
95
+ commit runs one discarded statement that opens a real read transaction before it serves the
96
+ query; that costs one extra worker round-trip on each worker's first statement after a write,
97
+ and nothing under read-only load. `poolSize: 1` and reading inside the same `transaction()`
98
+ remain valid, they are no longer required.
104
99
 
105
- For batch inserts, schema-driven table replacement, or explicit transactions, see:
106
- - `db.bulkWrite(table, keys)` — batches inserts within `SQLITE_MAX_VARS` limit
107
- - `db.output(table, schema, options)` — drops, recreates, and populates a table from a schema definition
108
- - `db.transaction(callback, options)` — wraps operations in a SQLite transaction with auto-commit and rollback
100
+ The one exception is [`IDBMirrorVFS`](VFS.md#idbmirrorvfs), which does not hold it across
101
+ tabs.
109
102
 
110
- ### Close
103
+ ### Writes are serialized
111
104
 
112
- ```typescript
113
- db.close();
114
- ```
105
+ A write, a write transaction, and each batch of a `bulkWrite` take one lock per database
106
+ across the whole origin, so a second writer **waits** rather than failing — between clients
107
+ and between tabs alike. The wait is unbounded and first-come-first-served: pass a `signal` if
108
+ you would rather fail than wait. A write transaction holds that lock for the whole of its
109
+ callback, so a callback that never returns blocks every other writer in the origin, not only
110
+ its own client. **A `bulkWrite` takes the lock per batch and commits per batch**, so another
111
+ client's write can land between two of its batches — use `tx.bulkWrite` where you need all or
112
+ nothing.
115
113
 
116
- Terminates all worker threads.
114
+ ## Known Limitations
117
115
 
118
- ## Requirements
116
+ Some VFS have limitations of their own — see [the detailed VFS page](VFS.md#vfs-reference).
117
+ What follows holds on all of them.
119
118
 
120
- > **These HTTP headers are mandatory.** Without them, `new SharedArrayBuffer()` throws a `SecurityError` and browser-sqlite cannot initialize.
119
+ ### Aborting a call
121
120
 
122
- browser-sqlite uses a `SharedArrayBuffer` to coordinate worker pool state. Browsers require [cross-origin isolation](https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated) to create `SharedArrayBuffer` instances. Your page must be served with:
121
+ An abort does not always stop the work, and your hosting decides. On the `sync` build, a
122
+ `signal` or a `timeout` rejects your promise straight away, but the statement runs to its
123
+ end on its worker, which stays unavailable until it does.
123
124
 
124
- ```http
125
- Cross-Origin-Opener-Policy: same-origin
126
- Cross-Origin-Embedder-Policy: require-corp
127
- ```
125
+ Two ways out — serving the page cross-origin isolated, or `build: 'async'` — and what each
126
+ one costs are under [Interrupting a call](API.md#interrupting-a-call).
127
+
128
+ ### Deleting a database
128
129
 
129
- ### Server configuration examples
130
+ A database that any client still holds cannot be deleted, in this tab or another, on every
131
+ VFS. More on the dedicated [`deleteDatabase`](API.md#deletedatabase) API entry.
130
132
 
131
- **Nginx**
132
- ```nginx
133
- add_header Cross-Origin-Opener-Policy "same-origin";
134
- add_header Cross-Origin-Embedder-Policy "require-corp";
133
+ ## Development
134
+
135
+ ```bash
136
+ pnpm install
137
+ pnpm build # rslib → dist/
138
+ pnpm test # unit (Node) + browser (Playwright/Chromium)
139
+ pnpm check # biome, with --write
135
140
  ```
136
141
 
137
- **Express**
138
- ```javascript
139
- app.use((req, res, next) => {
140
- res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
141
- res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
142
- next();
143
- });
142
+ Two suites run on demand rather than on every change:
143
+
144
+ ```bash
145
+ pnpm test:conformance # every declared (vfs, build) pair through six invariants
146
+ pnpm test:consumer # packs the tarball and drives four bundler modes
144
147
  ```
145
148
 
146
- **Rsbuild / Vite dev server**
147
- ```typescript
148
- // rsbuild.config.ts or vite.config.ts
149
- server: {
150
- headers: {
151
- 'Cross-Origin-Opener-Policy': 'same-origin',
152
- 'Cross-Origin-Embedder-Policy': 'require-corp',
153
- },
154
- },
149
+ ### The benchmark page
150
+
151
+ `scripts/bench/html/index.html` is the page published above. It is one self-contained file
152
+ served beside a verbatim copy of `dist/`, so it exercises the library exactly as
153
+ a consumer would with no bundler at all.
154
+
155
+ ```bash
156
+ pnpm bench:dev # build, serve on http://127.0.0.1:8099, rebuild on change
157
+ pnpm bench:serve # same without the watch
158
+ pnpm bench:build # assemble _site/ only
155
159
  ```
156
160
 
157
- ## Known Limitations
161
+ `http://127.0.0.1` is a secure context, so OPFS works with no certificate — no
162
+ TLS setup is needed to develop against it. A phone on the LAN is a different
163
+ matter: it is not a secure context, so OPFS is unavailable there and a tunnel
164
+ (or the published page) is the way to test a real device.
158
165
 
159
- - **`AccessHandlePoolVFS` requires `poolSize: 1`.** Passing `poolSize > 1` with this VFS throws synchronously at client creation time.
160
- - **`SharedArrayBuffer` requires cross-origin isolation.** See the [Requirements](#requirements) section. Omitting COOP/COEP headers causes a `SecurityError` at runtime with no fallback.
161
- - **`OPFSAdaptiveVFS` requires Chromium 126+.** This VFS uses JavaScript Promise Integration (JSPI), which is not available in Firefox or Safari as of 2025.
166
+ `node scripts/bench/check.mjs [chromium|firefox] [--all]` drives the page under
167
+ Playwright and asserts that it still works it is run by hand and deliberately
168
+ not wired into CI. It checks the *page*, never that a VFS passes: a red cell can
169
+ be a correct report about the engine you are on.
package/dist/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lalexdotcom
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/NOTICE ADDED
@@ -0,0 +1,56 @@
1
+ THIRD-PARTY NOTICES
2
+ ===================
3
+
4
+ browser-sqlite is distributed under the MIT License; see LICENSE.
5
+
6
+ Its published worker artifact (dist/worker/worker.js) has third-party code
7
+ bundled into it, and ships compiled WebAssembly built from third-party
8
+ sources (dist/worker/wa-sqlite.wasm, wa-sqlite-async.wasm, wa-sqlite-jspi.wasm).
9
+ The notices below travel with those files and must be preserved in any
10
+ redistribution.
11
+
12
+
13
+ -------------------------------------------------------------------------------
14
+ wa-sqlite — https://github.com/rhashimoto/wa-sqlite
15
+ -------------------------------------------------------------------------------
16
+
17
+ The JavaScript glue and the VFS implementations bundled into
18
+ dist/worker/worker.js, and the .wasm binaries beside it, are produced by
19
+ wa-sqlite.
20
+
21
+ MIT License
22
+
23
+ Copyright (c) 2023 Roy T. Hashimoto
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining a copy
26
+ of this software and associated documentation files (the "Software"), to deal
27
+ in the Software without restriction, including without limitation the rights
28
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
+ copies of the Software, and to permit persons to whom the Software is
30
+ furnished to do so, subject to the following conditions:
31
+
32
+ The above copyright notice and this permission notice shall be included in all
33
+ copies or substantial portions of the Software.
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41
+ SOFTWARE.
42
+
43
+
44
+ -------------------------------------------------------------------------------
45
+ SQLite — https://sqlite.org
46
+ -------------------------------------------------------------------------------
47
+
48
+ The .wasm binaries are builds of SQLite. SQLite is in the public domain and
49
+ requires no attribution; the customary blessing is reproduced here.
50
+
51
+ The author disclaims copyright to this source code. In place of
52
+ a legal notice, here is a blessing:
53
+
54
+ May you do good and not evil.
55
+ May you find forgiveness for yourself and forgive others.
56
+ May you share freely, never taking more than you give.
@@ -0,0 +1,77 @@
1
+ import type { PoolWorker } from './pool';
2
+ /**
3
+ * Whether this cleanup has already run.
4
+ *
5
+ * A plain object rather than a boolean because the held value must observe a
6
+ * change the generator makes after registration. Three routes reach the
7
+ * cleanup — the registry, the abort listener and the generator's own `finally`
8
+ * — and whichever arrives first closes the door on the other two.
9
+ *
10
+ * What it deliberately does NOT record is whether the query ever started. That
11
+ * answers "did this generator run", where the only question that matters is
12
+ * "is the worker still serving this query" — and the worker is the one that
13
+ * knows, which is why `interrupt()` is asked rather than told.
14
+ */
15
+ export type AbandonState = {
16
+ done: boolean;
17
+ };
18
+ /**
19
+ * What the cleanup needs, and all it may hold.
20
+ *
21
+ * **It must never refer to the registered generator.** A `FinalizationRegistry`
22
+ * held value that reaches its own target keeps the target alive and the
23
+ * callback then never fires. Every field here points downward or sideways: the
24
+ * worker and the transport iterator are reachable from the pool anyway, `state`
25
+ * is a plain flag, `detach` closes over the caller's signal and its listener,
26
+ * and `release` is the owning layer's teardown.
27
+ */
28
+ export type Abandoned = {
29
+ worker: Pick<PoolWorker, 'interrupt'>;
30
+ iterator: {
31
+ return: (value?: undefined) => Promise<unknown>;
32
+ };
33
+ state: AbandonState;
34
+ /**
35
+ * Removes the abort listener that carries this very cleanup. Without it a
36
+ * listener stays armed on a signal the CALLER owns, long after the query it
37
+ * belonged to has ended — and fires against whatever the worker is doing
38
+ * then.
39
+ */
40
+ detach: () => void;
41
+ release?: (() => void) | undefined;
42
+ };
43
+ /**
44
+ * What the `finally` of `queries.chunk` would have done, for a generator that
45
+ * will never run it.
46
+ *
47
+ * The order is that `finally`'s and for its reason: `interrupt()` first, so the
48
+ * queued `return()` is not parked behind a `next()` that will not settle.
49
+ *
50
+ * **Nothing here may assume the worker is still ours.** This runs at a moment
51
+ * nobody chose — a collection, or the caller tidying up its own controller —
52
+ * and by then the worker may be serving a query that has nothing to do with
53
+ * this one. So the transport is named in both calls: `interrupt(iterator)` is a
54
+ * no-op unless the worker is still serving it, and `iterator.return()` resumes
55
+ * a transport whose own `finally` makes the same check. `return()` on a
56
+ * generator whose body never ran is a no-op besides, the body having never
57
+ * entered its `try`.
58
+ *
59
+ * `release` is the exception and runs unconditionally: it is the owning layer's
60
+ * resource — a lease, a timer, a merge teardown — and it is owed whatever the
61
+ * worker has since moved on to.
62
+ */
63
+ export declare const reclaim: ({ worker, iterator, state, detach, release, }: Abandoned) => void;
64
+ export type AbandonRegistry = {
65
+ /** Watch `target`; `held` is what the cleanup receives, `token` unregisters. */
66
+ watch: (target: object, held: Abandoned, token: object) => void;
67
+ /** The generator ended by an ordinary route — there is nothing to reclaim. */
68
+ forget: (token: object) => void;
69
+ };
70
+ /**
71
+ * `run` is injected so that tests drive the cleanup without a collection.
72
+ * Nothing else here is observable: a `FinalizationRegistry` fires when the
73
+ * engine decides, which is not a schedule a test can assert against.
74
+ */
75
+ export declare const createAbandonRegistry: (run?: (held: Abandoned) => void) => AbandonRegistry;
76
+ /** The one this library uses. */
77
+ export declare const abandonRegistry: AbandonRegistry;