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.
- package/NOTICE +56 -0
- package/README.md +112 -104
- package/dist/LICENSE +21 -0
- package/dist/NOTICE +56 -0
- package/dist/abandon.d.ts +77 -0
- package/dist/api.d.ts +426 -0
- package/dist/bulk.d.ts +57 -0
- package/dist/capabilities.d.ts +23 -0
- package/dist/client.d.ts +221 -0
- package/dist/credits.d.ts +31 -0
- package/dist/{esm/src/debug.d.ts → debug.d.ts} +21 -10
- package/dist/delete.d.ts +48 -0
- package/dist/epochs.d.ts +85 -0
- package/dist/errors.d.ts +76 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +96 -0
- package/dist/locks.d.ts +172 -0
- package/dist/logger.d.ts +24 -0
- package/dist/pool.d.ts +191 -0
- package/dist/queries.d.ts +65 -0
- package/dist/scheduler.d.ts +145 -0
- package/dist/sqlite-codes.d.ts +154 -0
- package/dist/supervisor.d.ts +17 -0
- package/dist/transaction.d.ts +61 -0
- package/dist/types.d.ts +642 -0
- package/dist/utils.d.ts +156 -0
- package/dist/worker/cloneable.d.ts +25 -0
- package/dist/worker/probes.d.ts +26 -0
- package/dist/worker/sqlite-code.d.ts +9 -0
- package/dist/worker/statement-cache.d.ts +36 -0
- package/dist/worker/wa-sqlite-async.wasm +0 -0
- package/dist/worker/wa-sqlite-jspi.wasm +0 -0
- package/dist/worker/wa-sqlite.wasm +0 -0
- package/dist/worker/worker.js +11 -0
- package/dist/worker/worker.js.map +1 -0
- package/package.json +46 -22
- package/dist/esm/index.js +0 -424
- package/dist/esm/rslib.config.d.ts +0 -2
- package/dist/esm/rstest.config.d.ts +0 -2
- package/dist/esm/src/client.d.ts +0 -332
- package/dist/esm/src/index.d.ts +0 -1
- package/dist/esm/src/orchestrator.d.ts +0 -87
- package/dist/esm/src/types.d.ts +0 -83
- package/dist/esm/src/utils.d.ts +0 -6
- /package/dist/{esm/src → worker}/worker.d.ts +0 -0
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { type SQLiteBuild, type SQLiteVFS, type WasmLocation } from './types';
|
|
2
|
+
export declare const sqlParams: () => {
|
|
3
|
+
addParam: (v: unknown) => string;
|
|
4
|
+
addParamArray: (values: unknown[]) => string;
|
|
5
|
+
params: unknown[];
|
|
6
|
+
};
|
|
7
|
+
export declare const isReadQuery: (sql: string) => boolean;
|
|
8
|
+
export declare const isWriteQuery: (sql: string) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Whether `sql` manages the transaction or its savepoints rather than data
|
|
11
|
+
* (spec 2026-09-11, D8). Never wrapped in the library's savepoint: there is
|
|
12
|
+
* nothing to undo, and a `RELEASE u` run inside it would pop it along with
|
|
13
|
+
* `u`. The leading keyword decides: these statements are never compound.
|
|
14
|
+
*/
|
|
15
|
+
export declare const isTransactionControl: (sql: string) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Combines two abort signals into one that fires with the reason of whichever
|
|
18
|
+
* source aborted first, plus the `release()` that unsubscribes it.
|
|
19
|
+
*
|
|
20
|
+
* NOT `AbortSignal.any()`. That is Chrome 116 / Firefox 124 / Safari 17.4, far
|
|
21
|
+
* above this library's floor (Chrome 92 / Firefox 95 / Safari 15.4), and
|
|
22
|
+
* adopting it would raise every row of the generated VFS.md matrix for every
|
|
23
|
+
* consumer.
|
|
24
|
+
*
|
|
25
|
+
* The common case allocates nothing: with one side absent, or one side already
|
|
26
|
+
* aborted, the surviving signal is returned as itself — no listener, no
|
|
27
|
+
* teardown owed, and the caller sees the original `reason` rather than a copy.
|
|
28
|
+
*/
|
|
29
|
+
export declare const mergeSignals: (a: AbortSignal | undefined, b: AbortSignal | undefined) => {
|
|
30
|
+
signal: AbortSignal | undefined;
|
|
31
|
+
release: () => void;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The `timeout` option: a wall-clock budget in milliseconds, counted from the
|
|
35
|
+
* call. Returns the signal the call should actually use — the caller's own,
|
|
36
|
+
* merged with one this library owns and aborts when the budget is spent.
|
|
37
|
+
*
|
|
38
|
+
* The abort reason IS the error the caller receives. Every abort path in this
|
|
39
|
+
* library rejects with `signal.reason`, and `mergeSignals` relays a reason
|
|
40
|
+
* verbatim, so nothing downstream has to ask which signal fired. That is why
|
|
41
|
+
* this is an AbortController and a setTimeout rather than
|
|
42
|
+
* `AbortSignal.timeout()`, which offers no way to set the reason.
|
|
43
|
+
*
|
|
44
|
+
* `release()` is owed exactly once, however the call ends.
|
|
45
|
+
*/
|
|
46
|
+
export declare const withDeadline: (options: {
|
|
47
|
+
signal?: AbortSignal | undefined;
|
|
48
|
+
timeout?: number | undefined;
|
|
49
|
+
} | undefined, method: string) => {
|
|
50
|
+
signal: AbortSignal | undefined;
|
|
51
|
+
release: () => void;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Routing guard for the read-shaped methods (`read`, `chunk`, `stream`, `first`).
|
|
55
|
+
* Throws before a lease is taken, so a rejected statement costs no pool capacity.
|
|
56
|
+
*
|
|
57
|
+
* A bare read pragma (`PRAGMA journal_mode`) is accepted; a pragma that assigns
|
|
58
|
+
* (`PRAGMA journal_mode=WAL`), takes an argument, or is followed by anything
|
|
59
|
+
* else must go through `write()`.
|
|
60
|
+
*/
|
|
61
|
+
export declare const assertReadable: (sql: string, method: string) => void;
|
|
62
|
+
/**
|
|
63
|
+
* Quotes an SQL identifier so it can never be read as anything but a name.
|
|
64
|
+
*
|
|
65
|
+
* The library interpolates table, column and index names into generated SQL —
|
|
66
|
+
* `bulkWrite`, `output` and their indexes. wa-sqlite's `statements()` executes
|
|
67
|
+
* `;`-separated statements, so an unquoted name is a stacked-query injection
|
|
68
|
+
* (B4). Quoting is what makes `t"; DROP TABLE users; --` one identifier.
|
|
69
|
+
*
|
|
70
|
+
* Note that quoting preserves case in `sqlite_master`; SQLite still resolves
|
|
71
|
+
* names case-insensitively.
|
|
72
|
+
*/
|
|
73
|
+
export declare const quoteIdent: (name: string) => string;
|
|
74
|
+
/**
|
|
75
|
+
* A column type is not an identifier and cannot be quoted — it is an SQL
|
|
76
|
+
* fragment the caller writes. It is validated by shape instead: this is the
|
|
77
|
+
* narrowed, not closed, channel documented in the spec (§1.2).
|
|
78
|
+
*/
|
|
79
|
+
export declare const assertColumnType: (type: string, column: string) => string;
|
|
80
|
+
/**
|
|
81
|
+
* A GENERATED ALWAYS AS expression is caller-authored SQL. It must at least be
|
|
82
|
+
* parenthesised and free of statement separators, so it cannot escape its slot.
|
|
83
|
+
*/
|
|
84
|
+
export declare const assertGeneratedExpression: (expr: string, column: string) => string;
|
|
85
|
+
/**
|
|
86
|
+
* Renders the client's `pragmas` option into executable statements, rejecting
|
|
87
|
+
* anything that is not provably a name and a scalar value (B4).
|
|
88
|
+
*
|
|
89
|
+
* Validation is syntactic rather than a closed list of the ~60 SQLite pragmas:
|
|
90
|
+
* a fixed list makes every legitimate pragma outside it unreachable and drifts
|
|
91
|
+
* with SQLite versions, for no additional protection — no ";", no parenthesis
|
|
92
|
+
* and no comment marker survives these three shapes either.
|
|
93
|
+
*
|
|
94
|
+
* Called twice: by the client at construction, so a bad configuration fails at
|
|
95
|
+
* `createSQLiteClient()` rather than inside an unrelated query, and by the
|
|
96
|
+
* worker at open, which is the only place the statements actually run.
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* The PRAGMAs a client actually applies: the VFS's declared defaults with the
|
|
100
|
+
* consumer's own layered over them.
|
|
101
|
+
*
|
|
102
|
+
* **Merged, never replaced.** A consumer who passes one pragma is answering a
|
|
103
|
+
* question of their own — `foreign_keys` is the usual one — not declining the
|
|
104
|
+
* VFS's defaults, and replacing would silently drop every default the moment
|
|
105
|
+
* they set anything at all. A key they DO set always wins, which is how a
|
|
106
|
+
* default is refused: pass `journal_mode` yourself and yours is what runs.
|
|
107
|
+
*
|
|
108
|
+
* Order matters and is the whole function: spread the defaults first.
|
|
109
|
+
*/
|
|
110
|
+
export declare const resolvePragmas: (vfs: SQLiteVFS, pragmas: Record<string, string> | undefined) => Record<string, string>;
|
|
111
|
+
export declare const renderPragmas: (pragmas: Record<string, string>) => string[];
|
|
112
|
+
/**
|
|
113
|
+
* The single definition of database identity — one string used everywhere:
|
|
114
|
+
* the worker open call, the VFS, the epoch registry and every lock name.
|
|
115
|
+
*
|
|
116
|
+
* The form is **relative** (no leading `/`). `URL.pathname` is absolute by
|
|
117
|
+
* construction, so stripping the slash is necessary: SQLite core checks
|
|
118
|
+
* `nPathname + 8 > mxPathname` (64, `node_modules/wa-sqlite/src/VFS.js:10`)
|
|
119
|
+
* before `xOpen`, and a leading `/` costs a character the budget cannot spare —
|
|
120
|
+
* measured at task 1: it broke all 96 browser tests on 56-char names. The
|
|
121
|
+
* strip gives that character back, so a 56-char name that the caller wrote
|
|
122
|
+
* still fits after normalization. The VFS re-parse (`new URL(zName, 'file://')`
|
|
123
|
+
* for four of five; `AccessHandlePoolVFS` via `'file://localhost/'`) produces
|
|
124
|
+
* identical `pathname` whether the open call receives `'data'` or `'/data'`,
|
|
125
|
+
* so the opened OPFS file is the same regardless.
|
|
126
|
+
*
|
|
127
|
+
* Idempotent: the VFS re-parse of an already-normalized name is a no-op.
|
|
128
|
+
*/
|
|
129
|
+
export declare const normalizeDatabaseFile: (file: string) => string;
|
|
130
|
+
/**
|
|
131
|
+
* Turns the `wasmUrl` client option into the absolute location posted in the
|
|
132
|
+
* `open` message, or `undefined` when the option was not given.
|
|
133
|
+
*
|
|
134
|
+
* `undefined` is the load-bearing case: the worker sets Emscripten's
|
|
135
|
+
* `locateFile` only when it receives a location, and `findWasmBinary` takes its
|
|
136
|
+
* `new URL('wa-sqlite.wasm', import.meta.url)` branch whenever `locateFile` is
|
|
137
|
+
* absent. So an omitted option leaves resolution byte-for-byte as it was
|
|
138
|
+
* before this option existed — which is the entire contract of the escape
|
|
139
|
+
* hatch.
|
|
140
|
+
*
|
|
141
|
+
* Resolution happens **here**, on the client, against the page: what the
|
|
142
|
+
* consumer writes means what it means from the page they wrote it on, not from
|
|
143
|
+
* the worker's own directory one level down. The callback is therefore called
|
|
144
|
+
* once, at client construction, before any worker exists — its result is
|
|
145
|
+
* reused by every worker in the pool and by every restart.
|
|
146
|
+
*
|
|
147
|
+
* A string is a **directory** and gets its missing trailing slash back before
|
|
148
|
+
* resolution: URL resolution treats a last segment without a slash as a
|
|
149
|
+
* document and replaces it, so `'/static/wasm'` would otherwise silently mean
|
|
150
|
+
* `/static/`. A callback names a **file**, so nothing is appended to it.
|
|
151
|
+
*
|
|
152
|
+
* @throws `SQLiteError('INVALID_OPTION')` when the value cannot be parsed as a
|
|
153
|
+
* URL — synchronously, at construction, rather than as an opaque open failure
|
|
154
|
+
* from a worker that could not fetch its module.
|
|
155
|
+
*/
|
|
156
|
+
export declare const resolveWasmLocation: (wasmUrl: string | ((build: SQLiteBuild) => string) | undefined, build: SQLiteBuild, baseHref: string) => WasmLocation | undefined;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Makes a value safe to hand to `postMessage`.
|
|
3
|
+
*
|
|
4
|
+
* The whole point is a failure the caller cannot recover from: a cause that
|
|
5
|
+
* cannot be structured-cloned makes `postMessage` itself throw, and every call
|
|
6
|
+
* site here is already inside a `catch` building an error reply. The throw
|
|
7
|
+
* would replace that reply with nothing, and the client would wait for ever on
|
|
8
|
+
* a request that was answered by no message at all.
|
|
9
|
+
*
|
|
10
|
+
* Pure, and in its own module for the reason `statement-cache.ts` is: the
|
|
11
|
+
* remainder of `worker.ts` only runs in a browser, and this decides something
|
|
12
|
+
* worth testing in Node against a value that is deliberately unclonable.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Returns `value` when it survives the structured-clone algorithm, and its
|
|
16
|
+
* string form when it does not.
|
|
17
|
+
*
|
|
18
|
+
* `MessageChannel` rather than `structuredClone()`: the two run the same
|
|
19
|
+
* algorithm and throw the same `DataCloneError`, but `structuredClone` lands at
|
|
20
|
+
* Chrome 98 where `MessageChannel` is Chrome 2 / Firefox 41 / Safari 5. Using
|
|
21
|
+
* it would have raised this library's floor by six Chrome versions to protect
|
|
22
|
+
* an error *cause* — see `scripts/render-vfs-matrix.ts`, which computes that
|
|
23
|
+
* floor from the APIs named here.
|
|
24
|
+
*/
|
|
25
|
+
export declare const cloneable: (value: unknown) => unknown;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform features a worker can probe for itself, synchronously, before it
|
|
3
|
+
* loads anything. Pure, and tested in Node for the reason `cloneable.ts` is.
|
|
4
|
+
*
|
|
5
|
+
* `readwrite-unsafe` cannot be probed from the page: `FileSystemSyncAccessHandle`
|
|
6
|
+
* is exposed to dedicated workers only, which is why `capabilities.ts` lists
|
|
7
|
+
* it as unprobeable. A worker can, and without opening a file: the engines that
|
|
8
|
+
* implement the mode also ship the handle's `mode` ATTRIBUTE. That is not the
|
|
9
|
+
* trap `capabilities.ts` warns about — WebIDL ignores an unknown DICTIONARY
|
|
10
|
+
* member, so passing the option proves nothing, but an attribute an engine does
|
|
11
|
+
* not implement is simply absent from the prototype. Measured 2026-09-13 in a
|
|
12
|
+
* dedicated worker: Chromium true, Firefox false, Safari false
|
|
13
|
+
* (spec 2026-09-13, §3.1).
|
|
14
|
+
*/
|
|
15
|
+
import type { PlatformFeature } from '../types';
|
|
16
|
+
/** The globals a probe reads; `globalThis` in a worker, a stub in tests. */
|
|
17
|
+
export type ProbeScope = {
|
|
18
|
+
FileSystemSyncAccessHandle?: unknown;
|
|
19
|
+
};
|
|
20
|
+
export declare const WORKER_PROBES: Partial<Record<PlatformFeature, (scope: ProbeScope) => boolean>>;
|
|
21
|
+
/**
|
|
22
|
+
* The first feature of `features` this worker lacks, or null. A feature with
|
|
23
|
+
* no probe here is never reported missing: declining on something unprobeable
|
|
24
|
+
* would shrink every pool on every engine.
|
|
25
|
+
*/
|
|
26
|
+
export declare const firstMissing: (features: readonly PlatformFeature[], scope?: ProbeScope) => PlatformFeature | null;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SQLiteResultCode } from '../sqlite-codes';
|
|
2
|
+
/**
|
|
3
|
+
* SQLite's result code on a thrown value, or undefined when SQLite did not
|
|
4
|
+
* raise it (spec 2026-09-14, final review). wa-sqlite raises its own
|
|
5
|
+
* `SQLiteError(message, code)` for every result code. Anything else carrying a
|
|
6
|
+
* numeric `code` — a DOMException's legacy code, 18 for SecurityError — is
|
|
7
|
+
* not SQLite's and must not be published as `sqliteCode`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const sqliteCodeOf: (e: unknown) => SQLiteResultCode | undefined;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A per-worker LRU of prepared statements, keyed by the exact SQL string.
|
|
3
|
+
*
|
|
4
|
+
* Pure bookkeeping: this module prepares nothing and finalises nothing.
|
|
5
|
+
* `worker.ts` owns every effect, which is what lets the policy be tested in
|
|
6
|
+
* Node against plain integers in a subsystem whose remainder only runs in a
|
|
7
|
+
* browser — the role `mem:architecture` describes for `scheduler.ts` and
|
|
8
|
+
* `supervisor.ts`.
|
|
9
|
+
*/
|
|
10
|
+
/** A `sqlite3_stmt` pointer. Opaque here: the cache only files it. */
|
|
11
|
+
export type StatementHandle = number;
|
|
12
|
+
/**
|
|
13
|
+
* The two bounds, both active. `maxEntries` answers the churn that generated
|
|
14
|
+
* SQL produces; `maxBytes` answers the footprint of a `bulkWrite` template,
|
|
15
|
+
* which is three orders of magnitude heavier than an ordinary statement
|
|
16
|
+
* (`mem:measurements`).
|
|
17
|
+
*/
|
|
18
|
+
export type StatementCacheBounds = {
|
|
19
|
+
maxEntries: number;
|
|
20
|
+
maxBytes: number;
|
|
21
|
+
};
|
|
22
|
+
export type StatementCache = {
|
|
23
|
+
get: (sql: string) => StatementHandle | 'uncacheable' | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the handles evicted by this insertion; the caller finalises them.
|
|
26
|
+
* `weight` is `SQLITE_STMTSTATUS_MEMUSED` and is required on purpose: an
|
|
27
|
+
* optional one would silently account a statement as free.
|
|
28
|
+
*/
|
|
29
|
+
set: (sql: string, handle: StatementHandle, weight: number) => StatementHandle[];
|
|
30
|
+
/** Returns the handles evicted by this marking; the caller finalises them. */
|
|
31
|
+
markUncacheable: (sql: string) => StatementHandle[];
|
|
32
|
+
delete: (sql: string) => StatementHandle | undefined;
|
|
33
|
+
/** Empties the cache and returns every live handle, for close. */
|
|
34
|
+
drain: () => StatementHandle[];
|
|
35
|
+
};
|
|
36
|
+
export declare const createStatementCache: ({ maxEntries, maxBytes, }: StatementCacheBounds) => StatementCache;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|