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

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 (42) hide show
  1. package/NOTICE +56 -0
  2. package/README.md +435 -63
  3. package/dist/LICENSE +21 -0
  4. package/dist/NOTICE +56 -0
  5. package/dist/api.d.ts +376 -0
  6. package/dist/bulk.d.ts +42 -0
  7. package/dist/capabilities.d.ts +23 -0
  8. package/dist/client.d.ts +198 -0
  9. package/dist/credits.d.ts +31 -0
  10. package/dist/{esm/src/debug.d.ts → debug.d.ts} +21 -10
  11. package/dist/delete.d.ts +42 -0
  12. package/dist/epochs.d.ts +55 -0
  13. package/dist/errors.d.ts +37 -0
  14. package/dist/index.d.ts +6 -0
  15. package/dist/index.js +5 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/locks.d.ts +54 -0
  18. package/dist/logger.d.ts +24 -0
  19. package/dist/pool.d.ts +98 -0
  20. package/dist/queries.d.ts +36 -0
  21. package/dist/scheduler.d.ts +131 -0
  22. package/dist/supervisor.d.ts +17 -0
  23. package/dist/transaction.d.ts +38 -0
  24. package/dist/types.d.ts +348 -0
  25. package/dist/utils.d.ts +116 -0
  26. package/dist/worker/cloneable.d.ts +25 -0
  27. package/dist/worker/statement-cache.d.ts +22 -0
  28. package/dist/worker/wa-sqlite-async.wasm +0 -0
  29. package/dist/worker/wa-sqlite-jspi.wasm +0 -0
  30. package/dist/worker/wa-sqlite.wasm +0 -0
  31. package/dist/worker/worker.js +11 -0
  32. package/dist/worker/worker.js.map +1 -0
  33. package/package.json +36 -20
  34. package/dist/esm/index.js +0 -424
  35. package/dist/esm/rslib.config.d.ts +0 -2
  36. package/dist/esm/rstest.config.d.ts +0 -2
  37. package/dist/esm/src/client.d.ts +0 -332
  38. package/dist/esm/src/index.d.ts +0 -1
  39. package/dist/esm/src/orchestrator.d.ts +0 -87
  40. package/dist/esm/src/types.d.ts +0 -83
  41. package/dist/esm/src/utils.d.ts +0 -6
  42. /package/dist/{esm/src → worker}/worker.d.ts +0 -0
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.
package/dist/api.d.ts ADDED
@@ -0,0 +1,376 @@
1
+ /**
2
+ * The public type layer. Everything here is part of the package's API, which is
3
+ * why `index.ts` re-exports this module wholesale: a name list is what let
4
+ * `SQLiteQueryOptions` and `TransactionDB` end up in the shipped `.d.ts`
5
+ * without a consumer being able to name either.
6
+ *
7
+ * `types.ts` keeps the wire protocol and the VFS capability table.
8
+ * `CreateSQLiteClientOptions` stays in `client.ts`, beside the constructor that
9
+ * validates it: this module is the querying surface and its satellites — what a
10
+ * caller passes to a query, and what comes back.
11
+ */
12
+ import type { ClientDebugState } from './debug';
13
+ /**
14
+ * Marks an options type as carrying an abort signal.
15
+ *
16
+ * The name is the point. `options?: OptionsWithSignal<…>` says at the signature
17
+ * that the method can be abandoned, where a bare alias would make a reader open
18
+ * the type to find out. Every abortable option type in this file is built from
19
+ * it, so `signal` is documented once and cannot drift between them.
20
+ *
21
+ * Not the bare `Abortable` that `@types/node` uses: this reads as an options
22
+ * bag augmented with one member — `PropsWithChildren`, not an adjective — which
23
+ * is what it is both wrapped, `OptionsWithSignal<{ chunkSize?: number }>`, and
24
+ * alone, `options?: OptionsWithSignal`.
25
+ *
26
+ * `T = unknown` rather than `Record<string, never>`: intersecting with the
27
+ * latter collapses `signal` to `never` and makes it unassignable.
28
+ */
29
+ export type OptionsWithSignal<T = unknown> = T & {
30
+ /**
31
+ * Aborts the work. Rejects with `signal.reason` — your reason, not an error
32
+ * of this library's making.
33
+ *
34
+ * On `bulkWrite()` and `output()` the abort lands **between** batches, never
35
+ * inside one: a multi-row INSERT is statement-atomic, so stopping inside a
36
+ * batch would either waste it whole or let it commit whole. An aborted
37
+ * `bulkWrite()` leaves the batches already written in place; an aborted
38
+ * `output()` is observationally a no-op, dropping its staging table and
39
+ * touching nothing else.
40
+ */
41
+ signal?: AbortSignal | undefined;
42
+ };
43
+ /** Options every query method accepts. */
44
+ export type SQLiteQueryOptions = OptionsWithSignal;
45
+ /**
46
+ * Options for the methods that cross the worker boundary in chunks.
47
+ *
48
+ * `chunkSize` is not only a transport detail: back-pressure grants credits per
49
+ * chunk with a window of 2, so the worker may run up to `2 × chunkSize` rows
50
+ * ahead of the consumer. On `stream()` that is the only lever on how many rows
51
+ * are in flight.
52
+ */
53
+ export type SQLiteChunkOptions = OptionsWithSignal<{
54
+ /** Rows per chunk. Defaults to 500. */
55
+ chunkSize?: number;
56
+ }>;
57
+ export type SQLiteWriteResult<T extends Record<string, unknown>> = {
58
+ result: T[];
59
+ affected: number;
60
+ };
61
+ /**
62
+ * Options for `transaction()`.
63
+ *
64
+ * `signal` abandons the transaction at every stage: while it waits for a
65
+ * worker, once it holds one, and from inside the callback — every statement
66
+ * issued through `tx` inherits it, and a statement that carries a signal of its
67
+ * own can be aborted by either. An abandoned transaction rolls back and rejects
68
+ * with `signal.reason`; it never commits, not even when the callback catches
69
+ * its statement's rejection and returns normally.
70
+ *
71
+ * The callback itself cannot be interrupted — it is your code — but it can no
72
+ * longer reach the database: every statement it issues after the abort rejects
73
+ * without a worker round trip.
74
+ *
75
+ * One window is not abortable: `BEGIN`, `COMMIT` and `ROLLBACK` never carry the
76
+ * signal. Their completion is what decides whether a rollback is owed, so a
77
+ * client-side abort of one of them would risk leaving the transaction open on
78
+ * the connection. The abort lands as soon as such a statement settles.
79
+ *
80
+ * That window is short on a VFS holding one access handle per connection, and
81
+ * it is not on a VFS rotating a single exclusive one: there such a statement
82
+ * waits for whichever client holds the file, and your signal cannot shorten
83
+ * that wait. See the reduced mode described under VFS Selection.
84
+ */
85
+ export type SQLiteTransactionOptions = OptionsWithSignal<{
86
+ /** Rejects write statements with `READ_ONLY_TRANSACTION`. Defaults to false. */
87
+ readOnly?: boolean;
88
+ /** Commits when the callback resolves. Defaults to true. */
89
+ autoCommit?: boolean;
90
+ }>;
91
+ /** Column definitions for `output()`. */
92
+ export type Schema = Record<string, string | {
93
+ type: string;
94
+ generated?: string;
95
+ required?: boolean;
96
+ unique?: boolean;
97
+ }>;
98
+ export type Index<SCHEMA extends Schema> = keyof SCHEMA | (keyof SCHEMA)[] | ({
99
+ unique?: boolean;
100
+ } & ({
101
+ column: keyof SCHEMA;
102
+ } | {
103
+ columns: (keyof SCHEMA)[];
104
+ }));
105
+ export type SQLiteOutputOptions<SCHEMA extends Schema> = OptionsWithSignal<{
106
+ indexes?: Index<SCHEMA>[];
107
+ /** Rows queued for writing above which `enqueue()` defers. See `SQLiteBulkWriteOptions`. */
108
+ queueSize?: number | undefined;
109
+ }>;
110
+ /**
111
+ * Options `bulkWrite()` accepts.
112
+ *
113
+ * `queueSize` bounds how far the producer may run ahead of the database. Rows
114
+ * are handed over in batches of at most 32 766 bound values; a batch that has
115
+ * been handed over but not yet written is held in memory until it is, and
116
+ * nothing caps how many of those accumulate unless you await `enqueue()`.
117
+ *
118
+ * It is a number of rows, and nothing else: it says nothing about what those
119
+ * rows weigh. A table whose columns carry blobs holds far more per row than a
120
+ * table of integers, and only you know which one you are loading — set the
121
+ * value yourself when the rows are heavy.
122
+ *
123
+ * The default is two batches' worth, derived from the column count: about
124
+ * 13 100 rows for 5 columns, 2 180 for 30. A value smaller than one batch is legal
125
+ * and means one INSERT in flight, the least the batching allows. Anything below
126
+ * 1 is raised to 1: a batch always holds at least one row, so a lower cap could
127
+ * never be satisfied.
128
+ */
129
+ export type SQLiteBulkWriteOptions = OptionsWithSignal<{
130
+ /** Rows queued for writing above which `enqueue()` defers. */
131
+ queueSize?: number | undefined;
132
+ }>;
133
+ /** A row for `output()`: generated columns are computed, never supplied. */
134
+ export type SQLiteOutputRow<SCHEMA extends Schema> = {
135
+ [K in keyof SCHEMA as SCHEMA[K] extends {
136
+ generated: string;
137
+ } ? never : K]: any;
138
+ };
139
+ /**
140
+ * Buffers a row, flushing automatically when the buffer fills.
141
+ *
142
+ * Awaiting the returned promise applies back-pressure: it is already resolved
143
+ * while fewer than `queueSize` rows are queued for writing, and resolves once
144
+ * a batch settles when they are not. Ignoring it is legal, and leaves the load
145
+ * unbounded exactly as it was before the option existed — the bound is an
146
+ * offer, not a guarantee.
147
+ *
148
+ * It never rejects. A failed batch surfaces at the next `enqueue()`, which
149
+ * throws, and at `close()`, which rejects.
150
+ */
151
+ type EnqueueRow<ROW> = (data: ROW) => Promise<void>;
152
+ export type SQLiteBulkWriter<KEYS extends string> = {
153
+ enqueue: EnqueueRow<Record<KEYS, any>>;
154
+ /** Flushes what remains and resolves with the total affected row count. */
155
+ close: () => Promise<number>;
156
+ };
157
+ export type SQLiteOutputWriter<SCHEMA extends Schema> = {
158
+ enqueue: EnqueueRow<SQLiteOutputRow<SCHEMA>>;
159
+ close: () => Promise<number>;
160
+ };
161
+ /**
162
+ * The querying surface, shared by the client and by a transaction.
163
+ *
164
+ * It exists so the two cannot drift: they had already done so, one taking
165
+ * `any[]` where the other took `unknown[]`, and two different option types on
166
+ * `chunk`. A method added to one is now added to both by construction.
167
+ *
168
+ * @remarks
169
+ * **The row type parameter is a claim, not a check.** `read<T>`, `first<T>`,
170
+ * `chunk<T>` and `stream<T>` cast SQLite's output to `T` and validate nothing:
171
+ * a column that is missing, renamed or of another type reaches you typed as if
172
+ * it were not. SQLite is dynamically typed and a query's shape is only known at
173
+ * runtime, so the alternative would be a schema the caller declares twice.
174
+ * Validate at the boundary if you need the guarantee — this is `as`, not a
175
+ * parser.
176
+ */
177
+ export type SQLiteQueryAPI = {
178
+ /**
179
+ * Executes a SELECT query and returns all matching rows as an array.
180
+ *
181
+ * Read queries are dispatched to any available worker in the pool,
182
+ * enabling concurrent execution across multiple readers.
183
+ *
184
+ * @param sql - SQL query string. Must be a SELECT (or equivalent read) statement.
185
+ * @param params - Positional parameters bound to `?` placeholders.
186
+ * @param options - Optional query options (`chunkSize`, `signal`).
187
+ * @returns Promise resolving to an array of typed rows (`T[]`). Returns `[]` for empty results.
188
+ */
189
+ read: <T extends Record<string, unknown>>(sql: string, params?: unknown[], options?: SQLiteChunkOptions) => Promise<T[]>;
190
+ /**
191
+ * Executes a DML or DDL statement (INSERT, UPDATE, DELETE, CREATE, DROP, etc.)
192
+ * and returns both any result rows and the number of affected rows.
193
+ *
194
+ * Write queries are serialized through a single dedicated writer worker.
195
+ * Concurrent writes queue behind each other — only one write executes at a time.
196
+ *
197
+ * @param sql - SQL statement. Any statement not classified as a read by `isReadQuery`.
198
+ * @param params - Positional parameters bound to `?` placeholders.
199
+ * @param options - Optional query options (`signal`).
200
+ * @returns Promise resolving to `{ result: T[], affected: number }` where
201
+ * `affected` is the SQLite `changes()` count for the statement.
202
+ */
203
+ write: <T extends Record<string, unknown>>(sql: string, params?: unknown[], options?: OptionsWithSignal) => Promise<SQLiteWriteResult<T>>;
204
+ /**
205
+ * Executes a query and yields result rows in chunks via an async generator.
206
+ * Memory-efficient for large result sets — rows are not buffered in full.
207
+ *
208
+ * @remarks
209
+ * **Worker held for full generator lifetime.** A pool worker is acquired when
210
+ * the generator is created and released only when the generator is fully
211
+ * exhausted or the caller uses `break`. Failing to exhaust the generator
212
+ * starves the pool. Always use `for await...of` to completion or `break` to exit.
213
+ *
214
+ * **`NOT_A_READ_QUERY` timing.** Because `chunk()` is an async generator, its
215
+ * body does not run until the first `next()` call. Passing a write statement
216
+ * does not throw at the call site — the `SQLiteError` arrives on the first
217
+ * `await gen.next()` (or the first iteration of `for await...of`).
218
+ *
219
+ * @param sql - SQL query string. Must be a SELECT (or equivalent read) statement.
220
+ * @param params - Positional parameters bound to `?` placeholders.
221
+ * @param options - Optional options including `chunkSize` (default `500`),
222
+ * `signal` (AbortSignal to cancel).
223
+ * @returns AsyncGenerator yielding `T[]` chunks of at most `chunkSize` rows.
224
+ */
225
+ chunk: <T extends Record<string, unknown>>(sql: string, params?: unknown[], options?: SQLiteChunkOptions) => AsyncGenerator<T[]>;
226
+ /**
227
+ * Executes a query and yields individual result rows via an async generator.
228
+ * Flattens chunk boundaries — each iteration yields one `T` row, not a chunk.
229
+ * Use `chunk()` when you need the rows grouped by chunk.
230
+ *
231
+ * @remarks
232
+ * **`NOT_A_READ_QUERY` timing.** Because `stream()` is an async generator, its
233
+ * body does not run until the first `next()` call. Passing a write statement
234
+ * does not throw at the call site — the `SQLiteError` arrives on the first
235
+ * `await gen.next()` (or the first iteration of `for await...of`).
236
+ *
237
+ * @param sql - SQL query string. Must be a SELECT (or equivalent read) statement.
238
+ * @param params - Positional parameters bound to `?` placeholders.
239
+ * @param options - Optional query options (`chunkSize`, `signal`).
240
+ * @returns AsyncGenerator yielding individual rows of type `T`.
241
+ */
242
+ stream: <T extends Record<string, unknown>>(sql: string, params?: unknown[], options?: SQLiteChunkOptions) => AsyncGenerator<T>;
243
+ /**
244
+ * Executes a query and returns the first row, or `undefined` if no rows match.
245
+ *
246
+ * Internally uses `chunkSize: 1` and asks the worker to stop after the first
247
+ * row. Because the worker runs in a separate thread it may race ahead between
248
+ * the break and the stop signal, so early termination is best-effort on small
249
+ * result sets. A hard bound will arrive with back-pressure in a future wave.
250
+ *
251
+ * @param sql - SQL query string.
252
+ * @param params - Positional parameters bound to `?` placeholders.
253
+ * @param options - Optional query options (`signal`).
254
+ * @returns Promise resolving to the first row as `T`, or `undefined` if no rows.
255
+ */
256
+ first: <T extends Record<string, unknown>>(sql: string, params?: unknown[], options?: OptionsWithSignal) => Promise<T | undefined>;
257
+ /**
258
+ * Creates a buffered bulk-insert utility that batches rows to stay within
259
+ * SQLite's variable limit (`SQLITE_MAX_VARS = 32766`).
260
+ *
261
+ * Call `enqueue()` for each row to insert, then `close()` to flush the
262
+ * remaining buffer and await completion.
263
+ *
264
+ * @remarks
265
+ * **`bulkWrite()` is not atomic:** batches are committed as they flush, so a
266
+ * failure leaves the rows already written in place. Call it on a `tx` if you
267
+ * need all-or-nothing.
268
+ *
269
+ * That commit per batch is also what it costs: measured at ~3.4 ms
270
+ * (synchronous build) and ~5.3 ms (Asyncify build) per commit on Chromium.
271
+ * A load wrapped in `transaction()` commits once and buys the rest back.
272
+ *
273
+ * @param table - Target table name.
274
+ * @param keys - Column names for the INSERT statement.
275
+ * @param options - `signal` aborts the load between batches. `close()` then
276
+ * rejects with `signal.reason`. **The batches already flushed stay
277
+ * written** — `bulkWrite()` is not atomic outside a transaction, so an
278
+ * abort stops the load, it does not undo it. Run it inside `transaction()`
279
+ * when abandoning must mean rolling back.
280
+ * @returns Object with:
281
+ * - `enqueue(data)` — buffers a row, flushing automatically when the buffer fills.
282
+ * - `close()` — flushes remaining rows and resolves with total affected row count.
283
+ */
284
+ bulkWrite: <KEYS extends string>(table: string, keys: KEYS[], options?: SQLiteBulkWriteOptions) => SQLiteBulkWriter<KEYS>;
285
+ /**
286
+ * Schema-driven table replacement: drops the existing table, creates a new one
287
+ * from the provided schema, bulk-inserts all enqueued rows, then creates indexes.
288
+ *
289
+ * Useful for full-refresh ETL patterns where a table is rebuilt from scratch.
290
+ *
291
+ * @remarks
292
+ * **Inside a transaction, `output()` costs more than it looks.** On its own it
293
+ * loads rows outside any transaction and holds the write lock only for the
294
+ * final swap. Called on a `tx`, the entire load runs inside your transaction —
295
+ * every other write, in this tab and in others, waits for it to finish.
296
+ *
297
+ * @param table - Table name to drop and recreate.
298
+ * @param schema - Column definition map. Values are SQL type strings or
299
+ * objects with `{ type, required?, unique?, generated? }`.
300
+ * @param options - `indexes` array for index creation after the swap, and
301
+ * `signal` to abort the load. An aborted `output()` leaves the previous
302
+ * target intact and untouched.
303
+ * @returns Object with `enqueue(data)` and `close()` following the same
304
+ * contract as {@link SQLiteQueryAPI.bulkWrite}.
305
+ */
306
+ output: <SCHEMA extends Schema>(table: string, schema: SCHEMA, options?: SQLiteOutputOptions<SCHEMA>) => SQLiteOutputWriter<SCHEMA>;
307
+ };
308
+ export type SQLiteDB = SQLiteQueryAPI & {
309
+ /**
310
+ * Executes a callback within a SQLite transaction, providing a scoped
311
+ * `SQLiteTransactionDB` with `read`, `write`, `chunk`, `stream`, `first`,
312
+ * `bulkWrite`, `output`, `commit`, and `rollback` methods.
313
+ *
314
+ * The worker is held exclusively for the transaction's duration.
315
+ * On callback success: auto-commits if `autoCommit` is `true` (default).
316
+ * On callback error: rolls back automatically.
317
+ * The callback may call `db.commit()` or `db.rollback()` manually.
318
+ *
319
+ * @remarks
320
+ * **Worker crash mid-transaction.** If the worker dies while the callback is
321
+ * running, the transaction rejects with a `WORKER_CRASHED` error. The
322
+ * database engine inside the terminated worker handles its own rollback, but
323
+ * any OPFS file lock the worker held is not released until the browser
324
+ * reclaims the terminated worker's file handles — the timing of that
325
+ * reclamation is outside this library's control.
326
+ *
327
+ * @param callback - Async function receiving a `SQLiteTransactionDB` instance.
328
+ * @param options - `readOnly` (default `false`) prevents write statements;
329
+ * `autoCommit` (default `true`) commits on callback success.
330
+ * @returns Promise resolving to the value returned by `callback`.
331
+ */
332
+ transaction: <T = void>(callback: (db: SQLiteTransactionDB) => Promise<T>, options?: SQLiteTransactionOptions) => Promise<T>;
333
+ /**
334
+ * Drains in-flight work, rejects queued work, closes each database connection,
335
+ * then terminates all workers in the pool.
336
+ *
337
+ * The returned promise settles once every worker has posted `closed` and been
338
+ * terminated, or once `drainTimeout` milliseconds have elapsed (whichever
339
+ * comes first). Calling `close()` a second time returns the **same** promise
340
+ * object — the operation runs exactly once.
341
+ *
342
+ * @remarks
343
+ * **Stored data is NOT deleted.** `close()` releases workers and connections;
344
+ * it removes nothing. What a database leaves behind, and how to remove it,
345
+ * depends on the VFS — and this library does not yet expose a deletion that
346
+ * routes through the VFS itself.
347
+ *
348
+ * Deleting files under `navigator.storage.getDirectory()` is only correct for
349
+ * the plain OPFS VFS, on a database that is already closed, and even there it
350
+ * leaves SQLite's `-journal` and `-wal` siblings unless you remove them too.
351
+ * It is wrong elsewhere:
352
+ *
353
+ * - `AccessHandlePoolVFS` keeps every database inside one directory named
354
+ * after the VFS, in a fixed set of pre-allocated files with opaque names.
355
+ * Removing a file does not free its slot — it takes capacity away from the
356
+ * pool, and once capacity runs out no further database opens.
357
+ * - `IDBBatchAtomicVFS` and `IDBMirrorVFS` store nothing in OPFS at all;
358
+ * their data lives in an IndexedDB database named after the VFS class, so
359
+ * an OPFS deletion is a no-op.
360
+ *
361
+ * Until a `deleteDatabase` exists here, treat removal as VFS-specific and
362
+ * check what your chosen VFS actually writes.
363
+ */
364
+ close: () => Promise<void>;
365
+ /**
366
+ * Internal diagnostic handle. Not part of the stable public API.
367
+ * Shape is subject to change without notice.
368
+ * @internal
369
+ */
370
+ debug?: ClientDebugState;
371
+ };
372
+ export type SQLiteTransactionDB = SQLiteQueryAPI & {
373
+ commit: () => Promise<void>;
374
+ rollback: () => Promise<void>;
375
+ };
376
+ export {};
package/dist/bulk.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import type { Schema, SQLiteBulkWriteOptions, SQLiteOutputOptions, SQLiteOutputRow, SQLiteTransactionOptions } from './api';
2
+ import { type Locks } from './locks';
3
+ import type { Logger } from './logger';
4
+ /**
5
+ * The options these three actually pass is a signal and nothing else, so that
6
+ * is what they ask for. `any` here accepted a misspelt option in silence, which
7
+ * is the one thing a narrow type was never meant to buy.
8
+ */
9
+ type BulkCallOptions = {
10
+ signal?: AbortSignal | undefined;
11
+ };
12
+ export type WriteFn = (sql: string, params?: unknown[], options?: BulkCallOptions) => Promise<{
13
+ result: unknown[];
14
+ affected: number;
15
+ }>;
16
+ export type ReadFn = (sql: string, params?: unknown[], options?: BulkCallOptions) => Promise<unknown[]>;
17
+ export type TransactionFn = <T>(callback: (db: {
18
+ write: (sql: string, params?: unknown[], options?: BulkCallOptions) => Promise<{
19
+ result: unknown[];
20
+ affected: number;
21
+ }>;
22
+ }) => Promise<T>, options?: SQLiteTransactionOptions) => Promise<T>;
23
+ export declare const createBulk: (shared: {
24
+ file: string;
25
+ locks: Locks;
26
+ logger: Logger;
27
+ maxVariables?: number;
28
+ }) => (target: {
29
+ read: ReadFn;
30
+ write: WriteFn;
31
+ transaction: TransactionFn;
32
+ }) => {
33
+ bulkWrite: <KEYS extends string>(table: string, keys: KEYS[], options?: SQLiteBulkWriteOptions, before?: Promise<unknown>) => {
34
+ enqueue: (data: { [K in KEYS]: any; }) => Promise<void>;
35
+ close: () => Promise<number>;
36
+ };
37
+ output: <SCHEMA extends Schema>(table: string, schema: SCHEMA, options?: SQLiteOutputOptions<SCHEMA>) => {
38
+ enqueue: (data: SQLiteOutputRow<SCHEMA>) => Promise<void>;
39
+ close: () => Promise<number>;
40
+ };
41
+ };
42
+ export {};
@@ -0,0 +1,23 @@
1
+ import { type PlatformFeature, type SQLiteBuild, type SQLiteVFS } from './types';
2
+ /**
3
+ * Every feature this module can decide: probed, or explicitly exempt. A
4
+ * feature declared in a capability table and absent here is a mistake, and
5
+ * tests/unit/capabilities.test.ts is what says so.
6
+ */
7
+ export declare const KNOWN_FEATURES: ReadonlySet<PlatformFeature>;
8
+ /** What this engine can do, probed once by the caller. */
9
+ export declare const detectFeatures: () => ReadonlySet<PlatformFeature>;
10
+ /**
11
+ * The first feature this pair needs and this engine lacks, or null.
12
+ *
13
+ * Pure, and takes `available` rather than probing, because the branches worth
14
+ * testing are the negative ones and they are unreachable in a real browser:
15
+ * JSPI cannot be taken away from Chromium.
16
+ */
17
+ export declare const missingFeature: (vfs: SQLiteVFS, build: SQLiteBuild, available: ReadonlySet<PlatformFeature>) => PlatformFeature | null;
18
+ /**
19
+ * The message for a missing feature, derived from the capability tables so it
20
+ * cannot drift from them. Names an alternative build when the build is at
21
+ * fault, and VFS that do not need the feature when the VFS is.
22
+ */
23
+ export declare const describeMissing: (vfs: SQLiteVFS, build: SQLiteBuild, feature: PlatformFeature) => string;