@crvouga/sqlite-mem 0.1.0

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 (145) hide show
  1. package/COMPATIBILITY-AUDIT.md +199 -0
  2. package/COMPATIBILITY.md +93 -0
  3. package/LICENSE +21 -0
  4. package/README.md +171 -0
  5. package/compat/coverage.json +21896 -0
  6. package/compat/fts-oracle-surface.json +198 -0
  7. package/compat/gate-report.json +424 -0
  8. package/compat/requirements.json +20929 -0
  9. package/dist/api/database.d.ts +26 -0
  10. package/dist/api/database.d.ts.map +1 -0
  11. package/dist/api/statement.d.ts +27 -0
  12. package/dist/api/statement.d.ts.map +1 -0
  13. package/dist/ast/nodes.d.ts +451 -0
  14. package/dist/ast/nodes.d.ts.map +1 -0
  15. package/dist/constraints/check.d.ts +12 -0
  16. package/dist/constraints/check.d.ts.map +1 -0
  17. package/dist/errors/index.d.ts +12 -0
  18. package/dist/errors/index.d.ts.map +1 -0
  19. package/dist/executor/attach.d.ts +6 -0
  20. package/dist/executor/attach.d.ts.map +1 -0
  21. package/dist/executor/ddl.d.ts +11 -0
  22. package/dist/executor/ddl.d.ts.map +1 -0
  23. package/dist/executor/dml.d.ts +7 -0
  24. package/dist/executor/dml.d.ts.map +1 -0
  25. package/dist/executor/env.d.ts +62 -0
  26. package/dist/executor/env.d.ts.map +1 -0
  27. package/dist/executor/execute.d.ts +5 -0
  28. package/dist/executor/execute.d.ts.map +1 -0
  29. package/dist/executor/pragma.d.ts +5 -0
  30. package/dist/executor/pragma.d.ts.map +1 -0
  31. package/dist/executor/result.d.ts +18 -0
  32. package/dist/executor/result.d.ts.map +1 -0
  33. package/dist/executor/select.d.ts +7 -0
  34. package/dist/executor/select.d.ts.map +1 -0
  35. package/dist/executor/simple-select.d.ts +10 -0
  36. package/dist/executor/simple-select.d.ts.map +1 -0
  37. package/dist/executor/triggers.d.ts +12 -0
  38. package/dist/executor/triggers.d.ts.map +1 -0
  39. package/dist/executor/vtable.d.ts +13 -0
  40. package/dist/executor/vtable.d.ts.map +1 -0
  41. package/dist/expressions/context.d.ts +28 -0
  42. package/dist/expressions/context.d.ts.map +1 -0
  43. package/dist/expressions/eval.d.ts +5 -0
  44. package/dist/expressions/eval.d.ts.map +1 -0
  45. package/dist/expressions/index.d.ts +4 -0
  46. package/dist/expressions/index.d.ts.map +1 -0
  47. package/dist/expressions/like.d.ts +5 -0
  48. package/dist/expressions/like.d.ts.map +1 -0
  49. package/dist/functions/aggregate.d.ts +9 -0
  50. package/dist/functions/aggregate.d.ts.map +1 -0
  51. package/dist/functions/datetime.d.ts +3 -0
  52. package/dist/functions/datetime.d.ts.map +1 -0
  53. package/dist/functions/extensions.d.ts +8 -0
  54. package/dist/functions/extensions.d.ts.map +1 -0
  55. package/dist/functions/index.d.ts +9 -0
  56. package/dist/functions/index.d.ts.map +1 -0
  57. package/dist/functions/json.d.ts +7 -0
  58. package/dist/functions/json.d.ts.map +1 -0
  59. package/dist/functions/math.d.ts +3 -0
  60. package/dist/functions/math.d.ts.map +1 -0
  61. package/dist/functions/registry.d.ts +38 -0
  62. package/dist/functions/registry.d.ts.map +1 -0
  63. package/dist/functions/scalar.d.ts +10 -0
  64. package/dist/functions/scalar.d.ts.map +1 -0
  65. package/dist/functions/table-valued.d.ts +9 -0
  66. package/dist/functions/table-valued.d.ts.map +1 -0
  67. package/dist/functions/window.d.ts +24 -0
  68. package/dist/functions/window.d.ts.map +1 -0
  69. package/dist/index.d.ts +12 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +12204 -0
  72. package/dist/index.js.map +7 -0
  73. package/dist/indexes/index.d.ts +16 -0
  74. package/dist/indexes/index.d.ts.map +1 -0
  75. package/dist/json/index.d.ts +8 -0
  76. package/dist/json/index.d.ts.map +1 -0
  77. package/dist/json/jsonb.d.ts +43 -0
  78. package/dist/json/jsonb.d.ts.map +1 -0
  79. package/dist/json/ops.d.ts +19 -0
  80. package/dist/json/ops.d.ts.map +1 -0
  81. package/dist/json/parse.d.ts +14 -0
  82. package/dist/json/parse.d.ts.map +1 -0
  83. package/dist/json/path.d.ts +27 -0
  84. package/dist/json/path.d.ts.map +1 -0
  85. package/dist/json/stringify.d.ts +5 -0
  86. package/dist/json/stringify.d.ts.map +1 -0
  87. package/dist/json/tvf.d.ts +14 -0
  88. package/dist/json/tvf.d.ts.map +1 -0
  89. package/dist/json/types.d.ts +30 -0
  90. package/dist/json/types.d.ts.map +1 -0
  91. package/dist/lexer/tokenize.d.ts +17 -0
  92. package/dist/lexer/tokenize.d.ts.map +1 -0
  93. package/dist/parser/index.d.ts +5 -0
  94. package/dist/parser/index.d.ts.map +1 -0
  95. package/dist/parser/parser.d.ts +104 -0
  96. package/dist/parser/parser.d.ts.map +1 -0
  97. package/dist/planner/access.d.ts +43 -0
  98. package/dist/planner/access.d.ts.map +1 -0
  99. package/dist/planner/index.d.ts +4 -0
  100. package/dist/planner/index.d.ts.map +1 -0
  101. package/dist/runtime/clock.d.ts +6 -0
  102. package/dist/runtime/clock.d.ts.map +1 -0
  103. package/dist/runtime/index.d.ts +4 -0
  104. package/dist/runtime/index.d.ts.map +1 -0
  105. package/dist/runtime/options.d.ts +19 -0
  106. package/dist/runtime/options.d.ts.map +1 -0
  107. package/dist/runtime/prng.d.ts +20 -0
  108. package/dist/runtime/prng.d.ts.map +1 -0
  109. package/dist/schema/catalog.d.ts +15 -0
  110. package/dist/schema/catalog.d.ts.map +1 -0
  111. package/dist/serialization/codec.d.ts +12 -0
  112. package/dist/serialization/codec.d.ts.map +1 -0
  113. package/dist/serialization/index.d.ts +2 -0
  114. package/dist/serialization/index.d.ts.map +1 -0
  115. package/dist/storage/database-state.d.ts +86 -0
  116. package/dist/storage/database-state.d.ts.map +1 -0
  117. package/dist/storage/index.d.ts +7 -0
  118. package/dist/storage/index.d.ts.map +1 -0
  119. package/dist/storage/row.d.ts +11 -0
  120. package/dist/storage/row.d.ts.map +1 -0
  121. package/dist/storage/table.d.ts +90 -0
  122. package/dist/storage/table.d.ts.map +1 -0
  123. package/dist/transactions/manager.d.ts +20 -0
  124. package/dist/transactions/manager.d.ts.map +1 -0
  125. package/dist/types/collation.d.ts +5 -0
  126. package/dist/types/collation.d.ts.map +1 -0
  127. package/dist/types/value.d.ts +52 -0
  128. package/dist/types/value.d.ts.map +1 -0
  129. package/dist/vtable/fts/options.d.ts +35 -0
  130. package/dist/vtable/fts/options.d.ts.map +1 -0
  131. package/dist/vtable/fts/porter.d.ts +3 -0
  132. package/dist/vtable/fts/porter.d.ts.map +1 -0
  133. package/dist/vtable/fts/query.d.ts +40 -0
  134. package/dist/vtable/fts/query.d.ts.map +1 -0
  135. package/dist/vtable/fts/table.d.ts +80 -0
  136. package/dist/vtable/fts/table.d.ts.map +1 -0
  137. package/dist/vtable/fts/tokenize.d.ts +21 -0
  138. package/dist/vtable/fts/tokenize.d.ts.map +1 -0
  139. package/dist/vtable/fts5.d.ts +2 -0
  140. package/dist/vtable/fts5.d.ts.map +1 -0
  141. package/dist/vtable/index.d.ts +3 -0
  142. package/dist/vtable/index.d.ts.map +1 -0
  143. package/dist/vtable/modules.d.ts +66 -0
  144. package/dist/vtable/modules.d.ts.map +1 -0
  145. package/package.json +107 -0
@@ -0,0 +1,199 @@
1
+ # SQLite3 Compatibility Audit
2
+
3
+ ```text
4
+ SQLite3 Compatibility Audit
5
+ ===========================
6
+
7
+ Reference SQLite version:
8
+ bun:sqlite (SQLite 3.51.0)
9
+
10
+ Reference SQLite compile options:
11
+ ENABLE_MATH_FUNCTIONS, ENABLE_FTS3/4/5, ENABLE_RTREE, ENABLE_DBSTAT_VTAB,
12
+ ENABLE_BYTECODE_VTAB, JSON builtin (not OMIT_JSON), plus Bun/SEE codec flags.
13
+ Full list: `bun run inventory`
14
+
15
+ sqlite-mem version:
16
+ 0.1.0
17
+
18
+ Scope:
19
+ Scope 3 — every oracle-exposed SQL builtin/module is in-scope except
20
+ NOT APPLICABLE (C API, on-disk format, VFS/pager/WAL).
21
+
22
+ SQLite requirements reviewed:
23
+ 3487 (from sqlite.org requirements matrix → compat/requirements.json)
24
+
25
+ SQLite requirements classification:
26
+ NOT APPLICABLE: see compat/coverage.json counts.notApplicable
27
+ SQL_BEHAVIOR: see counts.sqlBehavior
28
+ unknown: 0 (gate fails if non-zero)
29
+
30
+ Coverage statuses (SQL_BEHAVIOR):
31
+ VERIFIED / PARTIALLY_VERIFIED / UNSUPPORTED — see `bun run requirements`
32
+ Regenerated via scripts/sqlite-requirements.ts + coverage upgrades.
33
+
34
+ SQL grammar / operators / expressions:
35
+ VERIFIED — contracts + row-value comparisons + ->/->> precedence
36
+
37
+ Types / affinity / NULL:
38
+ VERIFIED
39
+
40
+ Functions (oracle surface):
41
+ VERIFIED — inventory missingOracleFunctions = 0 (163 names covered)
42
+
43
+ JSON / JSONB:
44
+ VERIFIED
45
+
46
+ Aggregates / windows:
47
+ VERIFIED — includes string_agg, ntile, cume_dist, percent_rank
48
+ (window EXCLUDE still thinner)
49
+
50
+ CTEs / transactions / savepoints / constraints / FK / triggers:
51
+ VERIFIED (deferred FK thinner → PARTIAL edges)
52
+
53
+ Indexes / views / generated / STRICT / WITHOUT ROWID:
54
+ VERIFIED / PARTIAL per COMPATIBILITY.md
55
+
56
+ PRAGMAs:
57
+ PARTIALLY VERIFIED — schema/FK; storage pragmas N/A or :memory: no-op
58
+
59
+ ATTACH/DETACH:
60
+ VERIFIED (in-memory schemas; temp.schema = main state)
61
+
62
+ Virtual tables / extensions:
63
+ VERIFIED for oracle modules: fts3/4/5, fts5vocab, rtree/rtree_i32,
64
+ dbstat, bytecode, tables_used (bytecode/tables_used empty cursors)
65
+
66
+ ANALYZE / REINDEX / VACUUM:
67
+ VERIFIED (:memory: observable parity)
68
+
69
+ Prepared statements / errors / snapshot:
70
+ PARTIAL / VERIFIED — schema invalidation thin; SQLM logical round-trip VERIFIED
71
+
72
+ Differential tests:
73
+ Total: 656 under `bun test` (contract + fuzz + harness)
74
+ Passed: 656
75
+ Failed: 0
76
+
77
+ Stateful / fuzz:
78
+ Seeds: 0x5a17e0e1 (+ SQLITE_MEM_FUZZ_SEED override)
79
+ Combination fuzz: tests/fuzz/combinations-scope3.test.ts
80
+ FTS fuzz: tests/fuzz/fts.test.ts
81
+ Mismatches: 0
82
+
83
+ New incompatibilities found & fixed (this pass):
84
+ 1. Missing ~85 oracle builtins (math/string/date/window/uuid/ieee754/…)
85
+ 2. Missing modules FTS3/4, RTREE, dbstat, bytecode, tables_used, fts5vocab
86
+ 3. ANALYZE/REINDEX/VACUUM not executed
87
+ 4. Row-value comparisons threw misuse instead of SQLite semantics
88
+ 5. Inventory asserted builtins absent (Scope-3 inverted)
89
+ 6. No requirements-matrix ingest / no test:sqlite-compat gate
90
+
91
+ Remaining known differences:
92
+ Custom SQLM snapshots; deterministic random()/'now';
93
+ EXPLAIN/INDEXED BY stubs/no-ops; some PRAGMA storage no-ops;
94
+ Window EXCLUDE / deferred FK / STRICT / prepared invalidation thinner;
95
+ BigInt beyond Number.MAX_SAFE_INTEGER without bun safeIntegers;
96
+ NOT APPLICABLE C API / on-disk / VFS surfaces.
97
+
98
+ Final assessment:
99
+ Verified against SQLite 3.51.0 (bun:sqlite). Oracle function/module
100
+ inventory is closed (0 missing). Requirements matrix ingested with
101
+ zero unknown statuses. Gate: `bun run test:sqlite-compat`.
102
+ ```
103
+
104
+ ---
105
+
106
+ ## SQLite Full-Text Search Compatibility Audit
107
+
108
+ ```text
109
+ SQLite Full-Text Search Compatibility Audit
110
+ ==========================================
111
+
112
+ Reference SQLite:
113
+ version: 3.51.0 (bun:sqlite)
114
+ source_id: 2025-06-12 13:14:41 f0ca7bba1c5e232e5d279fad6338121ab55af0c8c68c84cdfb18ba5114dcaapl
115
+ compile options: ENABLE_FTS3, ENABLE_FTS3_PARENTHESIS, ENABLE_FTS3_TOKENIZER,
116
+ ENABLE_FTS4, ENABLE_FTS5
117
+ inventory: compat/fts-oracle-surface.json (bun run scripts/fts-oracle-surface.ts)
118
+
119
+ FTS3: PARTIALLY VERIFIED (MATCH, snippet, offsets; matchinfo formats thinner)
120
+ FTS4: PARTIALLY VERIFIED (same surface as FTS3 for tested paths)
121
+ FTS5: PARTIALLY VERIFIED overall — core MATCH/tokenizers/ranking/aux VERIFIED;
122
+ external-content + full matchinfo format strings still thinner
123
+
124
+ Tokenizers verified:
125
+ unicode61 (incl. remove_diacritics 0/1/2), ascii, porter,
126
+ porter unicode61, porter ascii, trigram
127
+
128
+ MATCH grammar verified:
129
+ terms, AND/OR/NOT, implicit AND, phrases, prefix *, column filters
130
+ (col : term / {cols} :), NEAR / NEAR(…, N), parentheses, NEAR-as-term
131
+
132
+ Ranking verified:
133
+ bm25() / rank column — order + scores vs oracle (1e-15 abs epsilon for ULP)
134
+
135
+ Auxiliary functions verified:
136
+ bm25, highlight, snippet (FTS5); snippet, offsets (FTS3/4);
137
+ matchinfo present (default format PARTIAL)
138
+
139
+ Content modes verified:
140
+ normal content tables: VERIFIED
141
+ contentless (content=''): VERIFIED
142
+ external content: PARTIALLY VERIFIED (CREATE accepted; sync/triggers thinner)
143
+
144
+ Special commands verified:
145
+ optimize, rebuild, integrity-check (success + post-command MATCH)
146
+ delete-all / merge / automerge: error parity with oracle where probed
147
+
148
+ Differential tests:
149
+ Passed: 656 (contract + fuzz + harness)
150
+ Failed: 0
151
+ FTS contract: tests/contract/fts/basic.test.ts,
152
+ tests/contract/fts/comprehensive.test.ts
153
+
154
+ Fuzz cases:
155
+ Generated: fast-check seed 0x5a17e0e1 (override SQLITE_MEM_FUZZ_SEED)
156
+ Files: tests/fuzz/fts.test.ts (MATCH queries, tokenizers, stateful DML)
157
+ Mismatches: 0 (after trigram phrase expansion + NEAR-as-term fixes)
158
+
159
+ Stateful cases:
160
+ Operations: INSERT/UPDATE/DELETE/MATCH sequences + txn/savepoint contracts
161
+ Mismatches: 0
162
+
163
+ Compatibility gaps found:
164
+ 1. Toy AND-token matcher (replaced)
165
+ 2. Aux functions always threw (wired MATCH cursor + real bm25/highlight/snippet)
166
+ 3. No CREATE option parsing (tokenize=/content=/prefix=/UNINDEXED)
167
+ 4. No FTS5 query language / NEAR / phrases / column filters
168
+ 5. False VERIFIED status on fts5.html / fts3.html (downgraded then re-evidenced)
169
+
170
+ Compatibility gaps fixed:
171
+ Positional inverted index; unicode61/ascii/porter/trigram tokenizers;
172
+ FTS5 query parser; BM25 with SQLite IDF floor 1e-6; highlight/snippet;
173
+ contentless mode; special commands; FTS3/4 MATCH + snippet/offsets;
174
+ comparator realEpsilon for ranking ULP only; FTS fuzz suites
175
+
176
+ Regression tests added:
177
+ tests/contract/fts/comprehensive.test.ts
178
+ tests/fuzz/fts.test.ts
179
+ tests/harness/fts-compare.ts
180
+ scripts/fts-oracle-surface.ts
181
+
182
+ Remaining unsupported / thinner functionality:
183
+ - SQLite FTS shadow tables not mirrored (change counters diverge; documented)
184
+ - External-content sync/stale-index edge cases thinner
185
+ - FTS3 matchinfo format-string variants not exhaustively verified
186
+ - fts3tokenize / fts4aux still thin CREATE stubs
187
+ - locale / tokendata / detail=none advanced options accepted but lightly tested
188
+ ```
189
+
190
+ Verification commands:
191
+
192
+ ```bash
193
+ bun run test:sqlite-compat
194
+ bun run scripts/fts-oracle-surface.ts
195
+ bun test tests/contract/fts tests/fuzz/fts.test.ts
196
+ bun run inventory
197
+ bun run requirements
198
+ bun run typecheck
199
+ ```
@@ -0,0 +1,93 @@
1
+ # Compatibility
2
+
3
+ Goal: **full SQLite3 SQL dialect behavioral parity** as a drop-in for the same statements against the reference oracle. Compatibility is proven by the differential contract suite and the fail-closed gate:
4
+
5
+ ```bash
6
+ bun run test:sqlite-compat
7
+ ```
8
+
9
+ See [COMPATIBILITY-AUDIT.md](COMPATIBILITY-AUDIT.md) for the latest evidence-based audit report.
10
+
11
+ Reference oracle: **SQLite 3.51.0** (`bun:sqlite`). Inventory: `bun run inventory`. Requirements matrix: `bun run requirements` → `compat/requirements.json` + `compat/coverage.json`.
12
+
13
+ ## Status vocabulary
14
+
15
+ | Status | Meaning |
16
+ | --- | --- |
17
+ | **VERIFIED** | Differential contracts (+ fuzz where applicable) cover happy path **and** meaningful edges vs oracle |
18
+ | **PARTIALLY VERIFIED** | Implemented; coverage thin or known edges remain |
19
+ | **UNSUPPORTED** | Missing from SQL surface (must fail loud; gate fails if oracle-exposed) |
20
+ | **NOT APPLICABLE** | Outside the in-memory dialect surface (C API, on-disk `.sqlite`, VFS/pager/WAL) |
21
+
22
+ ## Scope 3 bound
23
+
24
+ Anything a SQLite application can invoke through SQL against this Bun/SQLite **3.51.0** build must match oracle observable behavior, except:
25
+
26
+ 1. **Snapshot format** — custom binary codec (`SQLM`), not the on-disk SQLite database file format (logical state still round-trips).
27
+ 2. **Deterministic `random()` / `'now'`** — seeded PRNG and fixed clock by default (injectable).
28
+ 3. **NOT APPLICABLE** rows in `compat/coverage.json` (C API, VFS, pager, file locking, etc.).
29
+
30
+ Oracle builtins (math, string extras, uuid, ieee754, …) and modules (FTS3/4/5, RTREE, dbstat, bytecode, tables_used) are **in scope**.
31
+
32
+ ## Feature matrix (summary)
33
+
34
+ | Area | Status | Notes |
35
+ | --- | --- | --- |
36
+ | Core DML / SELECT / joins / CTE / UPSERT / RETURNING | VERIFIED | Contract + fuzz |
37
+ | Expressions / operators / `->` `->>` / row values | VERIFIED | Row-value + precedence contracts |
38
+ | Affinity / NULL / COLLATE | VERIFIED | |
39
+ | Constraints / FK / triggers / views / ATTACH | VERIFIED | Deferred FK thinner → PARTIAL edges |
40
+ | Windows (incl. ntile/cume_dist/percent_rank) | VERIFIED | EXCLUDE still thinner |
41
+ | JSON1 / JSONB / TVFs | VERIFIED | |
42
+ | Math / string / date extras / uuid / ieee754 | VERIFIED | Scope-3 inventory |
43
+ | FTS3 / FTS4 / FTS5 + MATCH | PARTIALLY VERIFIED | Differential FTS suite + fuzz vs 3.51.0; see FTS matrix below. Shadow-table change counters intentionally diverge. |
44
+
45
+ ## FTS compatibility matrix
46
+
47
+ Reference: **SQLite 3.51.0** (`bun:sqlite`). Inventory: `bun run scripts/fts-oracle-surface.ts` → `compat/fts-oracle-surface.json`.
48
+
49
+ | Feature | Status |
50
+ | --- | --- |
51
+ | FTS3 | PARTIALLY VERIFIED |
52
+ | FTS4 | PARTIALLY VERIFIED |
53
+ | FTS5 | PARTIALLY VERIFIED |
54
+ | Virtual table creation (options/tokenizers) | VERIFIED |
55
+ | Tokenizers (unicode61/ascii/porter/trigram) | VERIFIED |
56
+ | MATCH grammar (AND/OR/NOT/phrase/prefix/NEAR/columns) | VERIFIED |
57
+ | Boolean operators | VERIFIED |
58
+ | Phrases | VERIFIED |
59
+ | Prefix queries | VERIFIED |
60
+ | NEAR | VERIFIED |
61
+ | Column filters | VERIFIED |
62
+ | Ranking / bm25 / rank | VERIFIED |
63
+ | highlight / snippet | VERIFIED |
64
+ | matchinfo / offsets (FTS3/4) | PARTIALLY VERIFIED |
65
+ | Contentless tables | VERIFIED |
66
+ | External content | PARTIALLY VERIFIED |
67
+ | Content tables | VERIFIED |
68
+ | Triggers + FTS | PARTIALLY VERIFIED |
69
+ | Special commands (optimize/rebuild/integrity-check) | VERIFIED |
70
+ | Prefix indexes | VERIFIED |
71
+ | Unicode / adversarial corpus | VERIFIED |
72
+ | Transactions / savepoints | VERIFIED |
73
+ | Error behavior | VERIFIED |
74
+ | FTS differential fuzz | VERIFIED |
75
+ | FTS stateful fuzz | VERIFIED |
76
+ | RTREE / dbstat / bytecode / tables_used | VERIFIED | dbstat synthetic pages; bytecode empty cursor |
77
+ | ANALYZE / REINDEX / VACUUM | VERIFIED | `:memory:` observable parity |
78
+ | EXPLAIN / INDEXED BY | PARTIALLY VERIFIED | Stub shapes / no-ops |
79
+ | Prepared stmt schema invalidation | PARTIALLY VERIFIED | Thin |
80
+ | On-disk file format / C API | NOT APPLICABLE | |
81
+
82
+ ## How to verify
83
+
84
+ ```bash
85
+ bun run test:sqlite-compat # requirements + gate + contract/fuzz/harness
86
+ bun run inventory # oracle function/module inventory
87
+ bun run requirements # refresh SQLite.org requirements + coverage
88
+ bun run test:browser # Playwright smoke (not the SQL oracle)
89
+ ```
90
+
91
+ Do not treat isolated unit tests of internal modules as proof of SQLite compatibility. The differential matrix runner is authoritative for SQL behavior; `test:sqlite-compat` is the release gate.
92
+
93
+ **Parity claim:** Verified against **SQLite 3.51.0** (`bun:sqlite`). Features marked **VERIFIED** are oracle-proven. **PARTIALLY VERIFIED** rows must not be marketed as complete. **NOT APPLICABLE** is the only allowed permanent omission from the SQL drop-in claim.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Vouga
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/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # sqlite-mem
2
+
3
+ Pure TypeScript, completely in-memory SQLite implementation aiming for **full SQLite3 SQL dialect parity** (same statements → same results).
4
+
5
+ - Runs in modern browsers and Node.js / Bun
6
+ - **Zero** WASM, native bindings, workers, or filesystem dependencies
7
+ - Entire database stored in memory
8
+ - **Verified against SQLite 3.51.0** (`bun:sqlite`) via differential contracts + fail-closed gate
9
+ - Intentional differences: deterministic `random()` / `'now'` by default, and a custom snapshot format (not `.sqlite` files)
10
+
11
+ See [COMPATIBILITY.md](COMPATIBILITY.md) for the matrix and [COMPATIBILITY-AUDIT.md](COMPATIBILITY-AUDIT.md) for the audit report.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ bun add @crvouga/sqlite-mem
17
+ # or
18
+ npm install @crvouga/sqlite-mem
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```ts
24
+ import { Database } from "@crvouga/sqlite-mem";
25
+
26
+ const db = new Database();
27
+
28
+ db.exec(`
29
+ CREATE TABLE users (
30
+ id INTEGER PRIMARY KEY,
31
+ name TEXT NOT NULL
32
+ )
33
+ `);
34
+
35
+ db.exec(`INSERT INTO users (name) VALUES (?)`, ["Alice"]);
36
+
37
+ const users = db.query<{ id: number; name: string }>(`SELECT * FROM users`);
38
+ console.log(users);
39
+
40
+ const snap = db.snapshot();
41
+ const db2 = new Database();
42
+ db2.restore(snap);
43
+ ```
44
+
45
+ ## API
46
+
47
+ ```ts
48
+ interface Database {
49
+ // seed default 1; now default 2000-01-01T00:00:00.000Z
50
+ constructor(options?: { seed?: number | bigint; now?: Date | (() => Date) });
51
+ exec(sql: string, params?: unknown[]): void;
52
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[];
53
+ prepare(sql: string): Statement;
54
+ transaction<T>(fn: () => T): T;
55
+ snapshot(): Uint8Array;
56
+ restore(snapshot: Uint8Array): void;
57
+ close(): void;
58
+ }
59
+
60
+ interface Statement {
61
+ bind(...params: unknown[]): Statement;
62
+ run(...params: unknown[]): { changes: number; lastInsertRowid: number | bigint };
63
+ all<T = Record<string, unknown>>(...params: unknown[]): T[];
64
+ get<T = Record<string, unknown>>(...params: unknown[]): T | undefined;
65
+ }
66
+ ```
67
+
68
+ ## Determinism
69
+
70
+ The engine is deterministic by default. Invariants:
71
+
72
+ | Source | Default | Override / notes |
73
+ | --- | --- | --- |
74
+ | `random()` / `randomblob()` | Seeded xorshift64* (`seed: 1`) | `new Database({ seed })` or `{ prng }` |
75
+ | `date('now')` / friends | Fixed `2000-01-01T00:00:00.000Z` | `new Database({ now: Date \| (() => Date) })` |
76
+ | Table scans | Rowid order | Same order after `snapshot`/`restore` |
77
+ | Snapshots | Sorted schema/rows + PRNG state + clock | Restored into PRNG and `now` |
78
+ | Transactions | PRNG rolls back with `ROLLBACK`/`SAVEPOINT` | Matches data rollback |
79
+ | Numbers | IEEE `-0` canonicalized to `+0` | Bind, affinity, and arithmetic |
80
+
81
+ Fuzz / property tests use a fixed seed (`0x5a17e0e1`) and print it on failure:
82
+
83
+ ```bash
84
+ bun test tests/fuzz
85
+ SQLITE_MEM_FUZZ_SEED=12345 bun test tests/fuzz
86
+ SQLITE_MEM_FUZZ_SEED=12345 SQLITE_MEM_FUZZ_PATH='0:1' bun test tests/fuzz # exact replay
87
+ ```
88
+
89
+ ## Development
90
+
91
+ Requires [Bun](https://bun.sh).
92
+
93
+ ```bash
94
+ bun install
95
+ bun run check # format + lint + typecheck + sqlite-compat suite
96
+ bun run format # write Biome formatting
97
+ bun run lint # Biome lint
98
+ bun run typecheck
99
+ bun run test:sqlite-compat # requirements + inventory gate + differential suite
100
+ bun test # contract + fuzz + harness
101
+ bun run build
102
+ bun run test:browser # Playwright smoke (Chrome/Firefox/Safari)
103
+ ```
104
+
105
+ Contract tests compare the pure TypeScript engine against real SQLite (`bun:sqlite`). See [COMPATIBILITY.md](./COMPATIBILITY.md).
106
+
107
+ ## Releasing
108
+
109
+ Publishing is fully automated. You never bump `version` or run `npm publish` by hand.
110
+
111
+ ### How a release happens
112
+
113
+ 1. Push or merge to `main` with [Conventional Commits](https://www.conventionalcommits.org/).
114
+ 2. CI runs commitlint, format/lint/typecheck, build, package verification, tests, browser smoke, and benchmarks.
115
+ 3. If every gate is green, [semantic-release](https://semantic-release.gitbook.io/) analyzes commits since the last git tag, bumps semver, publishes to npm, and creates a GitHub Release.
116
+
117
+ | Commit | Version bump |
118
+ | --- | --- |
119
+ | `fix: …` | patch (`0.1.0` → `0.1.1`) |
120
+ | `feat: …` | minor (`0.1.0` → `0.2.0`) |
121
+ | `feat!: …` or `BREAKING CHANGE:` footer | major (`0.2.0` → `1.0.0`) |
122
+ | `docs:`, `chore:`, `refactor:`, `test:`, … | no release |
123
+
124
+ Examples:
125
+
126
+ ```text
127
+ feat: add window function support
128
+ fix: handle NULL in UNIQUE constraints
129
+ feat!: rename snapshot() return type
130
+
131
+ chore: tweak CI timeouts
132
+ docs: clarify determinism table
133
+ ```
134
+
135
+ PR titles must also follow Conventional Commits (enforced in CI). Prefer squash merges with a conventional title.
136
+
137
+ Local checks:
138
+
139
+ ```bash
140
+ bunx commitlint --last --verbose
141
+ bun run build && bun run verify-package
142
+ # dry-run needs a GitHub token for API calls; CI publish uses Trusted Publishing (no NPM_TOKEN)
143
+ bun run release:dry-run
144
+ ```
145
+
146
+ `package.json` version is `0.0.0-development` on purpose — **git tags** (`v0.1.0`, …) are the source of truth.
147
+
148
+ ### One-time setup (maintainers)
149
+
150
+ Do this once so CI can publish. Full checklist: **[docs/SECRETS.md](./docs/SECRETS.md)**.
151
+
152
+ 1. **Create the package on npm (once), then Trusted Publishing.** If https://www.npmjs.com/package/@crvouga/sqlite-mem 404s:
153
+
154
+ ```bash
155
+ npm login --auth-type=web
156
+ bun run npm:seed -- --yes
157
+ ```
158
+
159
+ npm does not email a publish code — complete 2FA in the browser or authenticator app.
160
+
161
+ Then on [package Access](https://www.npmjs.com/package/@crvouga/sqlite-mem/access) → Trusted Publisher → GitHub Actions (`crvouga/sqlite-mem`, workflow `ci.yml`). Do **not** create an Automation / granular access token for CI.
162
+ 2. Confirm GitHub Actions is enabled and can create releases (default `GITHUB_TOKEN` is enough with this workflow’s permissions). No `NPM_TOKEN` repo secret.
163
+ 3. Ensure the baseline tag exists and is pushed: `v0.1.0` (semver continues from there; the next `feat` publishes `0.2.0`).
164
+
165
+ Validate the checklist anytime with `bun run secrets:doctor`.
166
+
167
+ After that, every green push to `main` with releasable commits updates npm automatically.
168
+
169
+ ## License
170
+
171
+ MIT