@minnowdb/core 0.0.1 → 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 (218) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +27 -1
  3. package/dist/block-format/block.d.ts +46 -0
  4. package/dist/block-format/block.d.ts.map +1 -0
  5. package/dist/block-format/block.js +244 -0
  6. package/dist/block-format/block.js.map +1 -0
  7. package/dist/block-format/checksum.d.ts +7 -0
  8. package/dist/block-format/checksum.d.ts.map +1 -0
  9. package/dist/block-format/checksum.js +56 -0
  10. package/dist/block-format/checksum.js.map +1 -0
  11. package/dist/block-format/codecs.d.ts +24 -0
  12. package/dist/block-format/codecs.d.ts.map +1 -0
  13. package/dist/block-format/codecs.js +102 -0
  14. package/dist/block-format/codecs.js.map +1 -0
  15. package/dist/block-format/column.d.ts +8 -0
  16. package/dist/block-format/column.d.ts.map +1 -0
  17. package/dist/block-format/column.js +166 -0
  18. package/dist/block-format/column.js.map +1 -0
  19. package/dist/block-format/index.d.ts +7 -0
  20. package/dist/block-format/index.d.ts.map +1 -0
  21. package/dist/block-format/index.js +7 -0
  22. package/dist/block-format/index.js.map +1 -0
  23. package/dist/block-format/physical.d.ts +20 -0
  24. package/dist/block-format/physical.d.ts.map +1 -0
  25. package/dist/block-format/physical.js +439 -0
  26. package/dist/block-format/physical.js.map +1 -0
  27. package/dist/block-format/types.d.ts +93 -0
  28. package/dist/block-format/types.d.ts.map +1 -0
  29. package/dist/block-format/types.js +2 -0
  30. package/dist/block-format/types.js.map +1 -0
  31. package/dist/engine/artifact-cache.d.ts +22 -0
  32. package/dist/engine/artifact-cache.d.ts.map +1 -0
  33. package/dist/engine/artifact-cache.js +68 -0
  34. package/dist/engine/artifact-cache.js.map +1 -0
  35. package/dist/engine/batch.d.ts +28 -0
  36. package/dist/engine/batch.d.ts.map +1 -0
  37. package/dist/engine/batch.js +38 -0
  38. package/dist/engine/batch.js.map +1 -0
  39. package/dist/engine/buffered-writer.d.ts +43 -0
  40. package/dist/engine/buffered-writer.d.ts.map +1 -0
  41. package/dist/engine/buffered-writer.js +158 -0
  42. package/dist/engine/buffered-writer.js.map +1 -0
  43. package/dist/engine/catalog.d.ts +82 -0
  44. package/dist/engine/catalog.d.ts.map +1 -0
  45. package/dist/engine/catalog.js +47 -0
  46. package/dist/engine/catalog.js.map +1 -0
  47. package/dist/engine/client.d.ts +211 -0
  48. package/dist/engine/client.d.ts.map +1 -0
  49. package/dist/engine/client.js +538 -0
  50. package/dist/engine/client.js.map +1 -0
  51. package/dist/engine/coordinator.d.ts +17 -0
  52. package/dist/engine/coordinator.d.ts.map +1 -0
  53. package/dist/engine/coordinator.js +60 -0
  54. package/dist/engine/coordinator.js.map +1 -0
  55. package/dist/engine/database.d.ts +661 -0
  56. package/dist/engine/database.d.ts.map +1 -0
  57. package/dist/engine/database.js +10313 -0
  58. package/dist/engine/database.js.map +1 -0
  59. package/dist/engine/defaults.d.ts +33 -0
  60. package/dist/engine/defaults.d.ts.map +1 -0
  61. package/dist/engine/defaults.js +87 -0
  62. package/dist/engine/defaults.js.map +1 -0
  63. package/dist/engine/dsl/db.d.ts +137 -0
  64. package/dist/engine/dsl/db.d.ts.map +1 -0
  65. package/dist/engine/dsl/db.js +161 -0
  66. package/dist/engine/dsl/db.js.map +1 -0
  67. package/dist/engine/dsl/expression.d.ts +172 -0
  68. package/dist/engine/dsl/expression.d.ts.map +1 -0
  69. package/dist/engine/dsl/expression.js +397 -0
  70. package/dist/engine/dsl/expression.js.map +1 -0
  71. package/dist/engine/dsl/index.d.ts +8 -0
  72. package/dist/engine/dsl/index.d.ts.map +1 -0
  73. package/dist/engine/dsl/index.js +7 -0
  74. package/dist/engine/dsl/index.js.map +1 -0
  75. package/dist/engine/dsl/live-query.d.ts +45 -0
  76. package/dist/engine/dsl/live-query.d.ts.map +1 -0
  77. package/dist/engine/dsl/live-query.js +116 -0
  78. package/dist/engine/dsl/live-query.js.map +1 -0
  79. package/dist/engine/dsl/mutations.d.ts +123 -0
  80. package/dist/engine/dsl/mutations.d.ts.map +1 -0
  81. package/dist/engine/dsl/mutations.js +241 -0
  82. package/dist/engine/dsl/mutations.js.map +1 -0
  83. package/dist/engine/dsl/select-query-builder.d.ts +148 -0
  84. package/dist/engine/dsl/select-query-builder.d.ts.map +1 -0
  85. package/dist/engine/dsl/select-query-builder.js +377 -0
  86. package/dist/engine/dsl/select-query-builder.js.map +1 -0
  87. package/dist/engine/dsl/sql-tag.d.ts +46 -0
  88. package/dist/engine/dsl/sql-tag.d.ts.map +1 -0
  89. package/dist/engine/dsl/sql-tag.js +85 -0
  90. package/dist/engine/dsl/sql-tag.js.map +1 -0
  91. package/dist/engine/dsl/types.d.ts +133 -0
  92. package/dist/engine/dsl/types.d.ts.map +1 -0
  93. package/dist/engine/dsl/types.js +9 -0
  94. package/dist/engine/dsl/types.js.map +1 -0
  95. package/dist/engine/errors.d.ts +55 -0
  96. package/dist/engine/errors.d.ts.map +1 -0
  97. package/dist/engine/errors.js +81 -0
  98. package/dist/engine/errors.js.map +1 -0
  99. package/dist/engine/fts.d.ts +93 -0
  100. package/dist/engine/fts.d.ts.map +1 -0
  101. package/dist/engine/fts.js +273 -0
  102. package/dist/engine/fts.js.map +1 -0
  103. package/dist/engine/group-index.d.ts +32 -0
  104. package/dist/engine/group-index.d.ts.map +1 -0
  105. package/dist/engine/group-index.js +366 -0
  106. package/dist/engine/group-index.js.map +1 -0
  107. package/dist/engine/index.d.ts +13 -0
  108. package/dist/engine/index.d.ts.map +1 -0
  109. package/dist/engine/index.js +12 -0
  110. package/dist/engine/index.js.map +1 -0
  111. package/dist/engine/join-index.d.ts +12 -0
  112. package/dist/engine/join-index.d.ts.map +1 -0
  113. package/dist/engine/join-index.js +217 -0
  114. package/dist/engine/join-index.js.map +1 -0
  115. package/dist/engine/live.d.ts +86 -0
  116. package/dist/engine/live.d.ts.map +1 -0
  117. package/dist/engine/live.js +289 -0
  118. package/dist/engine/live.js.map +1 -0
  119. package/dist/engine/memory.d.ts +37 -0
  120. package/dist/engine/memory.d.ts.map +1 -0
  121. package/dist/engine/memory.js +119 -0
  122. package/dist/engine/memory.js.map +1 -0
  123. package/dist/engine/optimizer.d.ts +20 -0
  124. package/dist/engine/optimizer.d.ts.map +1 -0
  125. package/dist/engine/optimizer.js +1170 -0
  126. package/dist/engine/optimizer.js.map +1 -0
  127. package/dist/engine/query-cache.d.ts +10 -0
  128. package/dist/engine/query-cache.d.ts.map +1 -0
  129. package/dist/engine/query-cache.js +58 -0
  130. package/dist/engine/query-cache.js.map +1 -0
  131. package/dist/engine/query.d.ts +844 -0
  132. package/dist/engine/query.d.ts.map +1 -0
  133. package/dist/engine/query.js +7450 -0
  134. package/dist/engine/query.js.map +1 -0
  135. package/dist/engine/schema-wire.d.ts +92 -0
  136. package/dist/engine/schema-wire.d.ts.map +1 -0
  137. package/dist/engine/schema-wire.js +115 -0
  138. package/dist/engine/schema-wire.js.map +1 -0
  139. package/dist/engine/schema.d.ts +394 -0
  140. package/dist/engine/schema.d.ts.map +1 -0
  141. package/dist/engine/schema.js +709 -0
  142. package/dist/engine/schema.js.map +1 -0
  143. package/dist/engine/sort-keys.d.ts +36 -0
  144. package/dist/engine/sort-keys.d.ts.map +1 -0
  145. package/dist/engine/sort-keys.js +60 -0
  146. package/dist/engine/sort-keys.js.map +1 -0
  147. package/dist/engine/sql-json.d.ts +30 -0
  148. package/dist/engine/sql-json.d.ts.map +1 -0
  149. package/dist/engine/sql-json.js +120 -0
  150. package/dist/engine/sql-json.js.map +1 -0
  151. package/dist/engine/sql-semantics.d.ts +31 -0
  152. package/dist/engine/sql-semantics.d.ts.map +1 -0
  153. package/dist/engine/sql-semantics.js +121 -0
  154. package/dist/engine/sql-semantics.js.map +1 -0
  155. package/dist/engine/vector.d.ts +87 -0
  156. package/dist/engine/vector.d.ts.map +1 -0
  157. package/dist/engine/vector.js +4227 -0
  158. package/dist/engine/vector.js.map +1 -0
  159. package/dist/engine/worker-host.d.ts +48 -0
  160. package/dist/engine/worker-host.d.ts.map +1 -0
  161. package/dist/engine/worker-host.js +501 -0
  162. package/dist/engine/worker-host.js.map +1 -0
  163. package/dist/engine/worker.d.ts +2 -0
  164. package/dist/engine/worker.d.ts.map +1 -0
  165. package/dist/engine/worker.js +14 -0
  166. package/dist/engine/worker.js.map +1 -0
  167. package/dist/index.d.ts +2 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +2 -0
  170. package/dist/index.js.map +1 -0
  171. package/dist/plan/index.d.ts +17 -0
  172. package/dist/plan/index.d.ts.map +1 -0
  173. package/dist/plan/index.js +17 -0
  174. package/dist/plan/index.js.map +1 -0
  175. package/dist/storage/fixture-shape.d.ts +42 -0
  176. package/dist/storage/fixture-shape.d.ts.map +1 -0
  177. package/dist/storage/fixture-shape.js +146 -0
  178. package/dist/storage/fixture-shape.js.map +1 -0
  179. package/dist/storage/index.d.ts +5 -0
  180. package/dist/storage/index.d.ts.map +1 -0
  181. package/dist/storage/index.js +5 -0
  182. package/dist/storage/index.js.map +1 -0
  183. package/dist/storage/indexeddb.d.ts +139 -0
  184. package/dist/storage/indexeddb.d.ts.map +1 -0
  185. package/dist/storage/indexeddb.js +3161 -0
  186. package/dist/storage/indexeddb.js.map +1 -0
  187. package/dist/storage/memory.d.ts +121 -0
  188. package/dist/storage/memory.d.ts.map +1 -0
  189. package/dist/storage/memory.js +1455 -0
  190. package/dist/storage/memory.js.map +1 -0
  191. package/dist/storage/snapshot.d.ts +108 -0
  192. package/dist/storage/snapshot.d.ts.map +1 -0
  193. package/dist/storage/snapshot.js +276 -0
  194. package/dist/storage/snapshot.js.map +1 -0
  195. package/dist/storage/types.d.ts +895 -0
  196. package/dist/storage/types.d.ts.map +1 -0
  197. package/dist/storage/types.js +1549 -0
  198. package/dist/storage/types.js.map +1 -0
  199. package/dist/testing/index.d.ts +76 -0
  200. package/dist/testing/index.d.ts.map +1 -0
  201. package/dist/testing/index.js +233 -0
  202. package/dist/testing/index.js.map +1 -0
  203. package/dist/testing/seeds.d.ts +11 -0
  204. package/dist/testing/seeds.d.ts.map +1 -0
  205. package/dist/testing/seeds.js +50 -0
  206. package/dist/testing/seeds.js.map +1 -0
  207. package/dist/transactions/index.d.ts +148 -0
  208. package/dist/transactions/index.d.ts.map +1 -0
  209. package/dist/transactions/index.js +662 -0
  210. package/dist/transactions/index.js.map +1 -0
  211. package/dist/worker-protocol/index.d.ts +84 -0
  212. package/dist/worker-protocol/index.d.ts.map +1 -0
  213. package/dist/worker-protocol/index.js +117 -0
  214. package/dist/worker-protocol/index.js.map +1 -0
  215. package/package.json +66 -16
  216. package/sql-feature-matrix.json +1275 -0
  217. package/index.d.ts +0 -1
  218. package/index.js +0 -1
@@ -0,0 +1,366 @@
1
+ const INITIAL_ENTRY_CAPACITY = 4;
2
+ const INITIAL_BUCKET_CAPACITY = 8;
3
+ const INITIAL_KEY_CAPACITY = 32;
4
+ const INDEX_FIELDS = 4;
5
+ const UINT32_BYTES = Uint32Array.BYTES_PER_ELEMENT;
6
+ const INITIAL_SCRATCH_CAPACITY = 64;
7
+ const REPLACEMENT_CHARACTER_BYTES = [0xef, 0xbf, 0xbd];
8
+ // Every probe encodes its key into this shared scratch arena instead of allocating a fresh buffer
9
+ // per row. Encoding is synchronous and the bytes are consumed before the next probe begins, so a
10
+ // single arena serves every index; the miss path copies out of it before any caller code runs.
11
+ let scratch = new Uint8Array(INITIAL_SCRATCH_CAPACITY);
12
+ let scratchView = new DataView(scratch.buffer);
13
+ // The arena grows to fit the largest key ever encoded, so a single pathological key (a
14
+ // multi-megabyte string) would otherwise pin that memory for the life of the process — hostile
15
+ // to low-end devices. Each fresh encoding starts by shedding anything beyond the retention cap;
16
+ // ordinary keys never reach it, so the check is one branch per operation.
17
+ const SCRATCH_RETAIN_BYTES = 1024 * 1024;
18
+ function reclaimScratch() {
19
+ if (scratch.byteLength <= SCRATCH_RETAIN_BYTES)
20
+ return;
21
+ scratch = new Uint8Array(SCRATCH_RETAIN_BYTES);
22
+ scratchView = new DataView(scratch.buffer);
23
+ }
24
+ /** Byte-addressable, insertion-ordered grouping index with fully reserved typed storage. */
25
+ export class ByteGroupIndex {
26
+ #memory;
27
+ #values = [];
28
+ #buckets = new Int32Array(0);
29
+ #hashes = new Uint32Array(0);
30
+ #offsets = new Uint32Array(0);
31
+ #lengths = new Uint32Array(0);
32
+ #next = new Int32Array(0);
33
+ #keys = new Uint8Array(0);
34
+ #keyLength = 0;
35
+ #entryReservation;
36
+ #bucketReservation;
37
+ #keyReservation;
38
+ constructor(memory) {
39
+ this.#memory = memory;
40
+ }
41
+ get size() {
42
+ return this.#values.length;
43
+ }
44
+ get(keys) {
45
+ const length = encodeGroupKey(keys);
46
+ const index = this.#find(length, hashScratch(length));
47
+ return index < 0 ? undefined : this.#values[index];
48
+ }
49
+ getEmpty() {
50
+ return this.get([]);
51
+ }
52
+ getOne(key) {
53
+ const length = encodeSingleGroupKey(key);
54
+ const index = this.#find(length, hashScratch(length));
55
+ return index < 0 ? undefined : this.#values[index];
56
+ }
57
+ set(keys, value) {
58
+ const length = encodeGroupKey(keys);
59
+ const hash = hashScratch(length);
60
+ const existing = this.#find(length, hash);
61
+ if (existing >= 0) {
62
+ this.#values[existing] = value;
63
+ return;
64
+ }
65
+ this.#insert(scratch.slice(0, length), hash, value);
66
+ }
67
+ getOrInsert(keys, create) {
68
+ const length = encodeGroupKey(keys);
69
+ return this.#getOrInsertScratch(length, create);
70
+ }
71
+ getOrInsertOne(key, create) {
72
+ const length = encodeSingleGroupKey(key);
73
+ return this.#getOrInsertScratch(length, create);
74
+ }
75
+ /**
76
+ * Resolves the key currently held in the scratch arena. A hit touches no allocation at all; a
77
+ * miss — at most one per distinct group — copies the key out before `create` runs, so caller
78
+ * code can never observe or disturb the shared arena.
79
+ */
80
+ #getOrInsertScratch(length, create) {
81
+ const hash = hashScratch(length);
82
+ const existing = this.#find(length, hash);
83
+ if (existing >= 0)
84
+ return this.#values[existing];
85
+ const encoded = scratch.slice(0, length);
86
+ const value = create();
87
+ this.#insert(encoded, hash, value);
88
+ return value;
89
+ }
90
+ #insert(encoded, hash, value) {
91
+ const index = this.#values.length;
92
+ this.#ensureEntryCapacity(index + 1);
93
+ this.#ensureBucketCapacity(index + 1);
94
+ this.#ensureKeyCapacity(encoded.byteLength);
95
+ const offset = this.#keyLength;
96
+ this.#keys.set(encoded, offset);
97
+ this.#keyLength += encoded.byteLength;
98
+ this.#hashes[index] = hash;
99
+ this.#offsets[index] = offset;
100
+ this.#lengths[index] = encoded.byteLength;
101
+ const bucket = hash & (this.#buckets.length - 1);
102
+ this.#next[index] = this.#buckets[bucket] ?? -1;
103
+ this.#buckets[bucket] = index;
104
+ this.#values.push(value);
105
+ }
106
+ setEmpty(value) {
107
+ this.set([], value);
108
+ }
109
+ setOne(key, value) {
110
+ this.set([key], value);
111
+ }
112
+ values() {
113
+ return this.#values;
114
+ }
115
+ /** Matches the scratch arena's first `length` bytes against stored keys without copying them. */
116
+ #find(length, hash) {
117
+ if (this.#buckets.length === 0)
118
+ return -1;
119
+ let index = this.#buckets[hash & (this.#buckets.length - 1)] ?? -1;
120
+ while (index >= 0) {
121
+ if (this.#hashes[index] === hash &&
122
+ this.#lengths[index] === length &&
123
+ equalsScratch(this.#keys, this.#offsets[index] ?? 0, length)) {
124
+ return index;
125
+ }
126
+ index = this.#next[index] ?? -1;
127
+ }
128
+ return -1;
129
+ }
130
+ #ensureEntryCapacity(required) {
131
+ if (required <= this.#hashes.length)
132
+ return;
133
+ let capacity = Math.max(INITIAL_ENTRY_CAPACITY, this.#hashes.length * 2);
134
+ while (capacity < required)
135
+ capacity = safeDouble(capacity, "Group index entries");
136
+ const reservation = this.#memory.reserve(safeProduct(capacity, INDEX_FIELDS * UINT32_BYTES, "Group index entry storage"), "Group index entry storage");
137
+ try {
138
+ const hashes = new Uint32Array(capacity);
139
+ const offsets = new Uint32Array(capacity);
140
+ const lengths = new Uint32Array(capacity);
141
+ const next = new Int32Array(capacity);
142
+ next.fill(-1);
143
+ hashes.set(this.#hashes);
144
+ offsets.set(this.#offsets);
145
+ lengths.set(this.#lengths);
146
+ next.set(this.#next);
147
+ this.#hashes = hashes;
148
+ this.#offsets = offsets;
149
+ this.#lengths = lengths;
150
+ this.#next = next;
151
+ this.#entryReservation?.release();
152
+ this.#entryReservation = reservation;
153
+ }
154
+ catch (error) {
155
+ reservation.release();
156
+ throw error;
157
+ }
158
+ }
159
+ #ensureBucketCapacity(requiredEntries) {
160
+ let capacity = this.#buckets.length;
161
+ if (capacity === 0)
162
+ capacity = INITIAL_BUCKET_CAPACITY;
163
+ while (requiredEntries * 4 > capacity * 3) {
164
+ capacity = safeDouble(capacity, "Group index buckets");
165
+ }
166
+ if (capacity === this.#buckets.length)
167
+ return;
168
+ const reservation = this.#memory.reserve(safeProduct(capacity, Int32Array.BYTES_PER_ELEMENT, "Group index bucket storage"), "Group index bucket storage");
169
+ try {
170
+ const buckets = new Int32Array(capacity);
171
+ buckets.fill(-1);
172
+ for (let index = 0; index < this.#values.length; index += 1) {
173
+ const bucket = (this.#hashes[index] ?? 0) & (capacity - 1);
174
+ this.#next[index] = buckets[bucket] ?? -1;
175
+ buckets[bucket] = index;
176
+ }
177
+ this.#buckets = buckets;
178
+ this.#bucketReservation?.release();
179
+ this.#bucketReservation = reservation;
180
+ }
181
+ catch (error) {
182
+ reservation.release();
183
+ throw error;
184
+ }
185
+ }
186
+ #ensureKeyCapacity(additionalBytes) {
187
+ const required = this.#keyLength + additionalBytes;
188
+ if (!Number.isSafeInteger(required))
189
+ throw new RangeError("Group key arena is too large");
190
+ if (required > 0xffff_ffff)
191
+ throw new RangeError("Group key arena exceeds uint32 offsets");
192
+ if (required <= this.#keys.byteLength)
193
+ return;
194
+ let capacity = Math.max(INITIAL_KEY_CAPACITY, this.#keys.byteLength * 2);
195
+ while (capacity < required)
196
+ capacity = safeDouble(capacity, "Group key arena");
197
+ const reservation = this.#memory.reserve(capacity, "Group key arena");
198
+ try {
199
+ const keys = new Uint8Array(capacity);
200
+ keys.set(this.#keys.subarray(0, this.#keyLength));
201
+ this.#keys = keys;
202
+ this.#keyReservation?.release();
203
+ this.#keyReservation = reservation;
204
+ }
205
+ catch (error) {
206
+ reservation.release();
207
+ throw error;
208
+ }
209
+ }
210
+ }
211
+ /**
212
+ * Writes the canonical tagged encoding of `keys` into the scratch arena and returns its byte
213
+ * length. The byte layout is unchanged from the allocating encoder it replaces — a one-byte tag
214
+ * per key, little-endian float64 numbers, and length-prefixed UTF-8 strings — so stored keys and
215
+ * their hashes stay comparable across both paths.
216
+ */
217
+ function encodeGroupKey(keys) {
218
+ reclaimScratch();
219
+ let offset = 0;
220
+ for (const key of keys)
221
+ offset = writeGroupKey(key, offset);
222
+ return offset;
223
+ }
224
+ /**
225
+ * Encodes one scalar key into the shared scratch arena and returns its byte length. Exported for
226
+ * the join index, which shares the arena and byte layout: both consume the encoding synchronously
227
+ * before any other key operation can run, so a single arena serves every index. NaN is the one
228
+ * excluded number — group callers canonicalize non-finite to null, join callers skip NaN keys —
229
+ * while ±Infinity encodes as an ordinary float64 so computed join keys can overflow and still match.
230
+ */
231
+ export function encodeSingleScalarKey(key) {
232
+ reclaimScratch();
233
+ return writeGroupKey(key, 0);
234
+ }
235
+ function encodeSingleGroupKey(key) {
236
+ reclaimScratch();
237
+ return writeGroupKey(key, 0);
238
+ }
239
+ function writeGroupKey(key, offset) {
240
+ if (key === null) {
241
+ ensureScratchCapacity(offset + 1);
242
+ scratch[offset] = 0;
243
+ return offset + 1;
244
+ }
245
+ if (typeof key === "boolean") {
246
+ ensureScratchCapacity(offset + 1);
247
+ scratch[offset] = key ? 2 : 1;
248
+ return offset + 1;
249
+ }
250
+ if (typeof key === "number") {
251
+ if (Number.isNaN(key))
252
+ throw new TypeError("Scalar index keys cannot be NaN");
253
+ ensureScratchCapacity(offset + 1 + Float64Array.BYTES_PER_ELEMENT);
254
+ scratch[offset] = 3;
255
+ scratchView.setFloat64(offset + 1, key === 0 ? 0 : key, true);
256
+ return offset + 1 + Float64Array.BYTES_PER_ELEMENT;
257
+ }
258
+ // A UTF-16 code unit never expands past three UTF-8 bytes, and a surrogate pair yields four
259
+ // across two units, so reserving three bytes per unit lets the encode loop skip bounds checks.
260
+ const bound = safeSum(offset + 5, safeProduct(key.length, 3, "Encoded group key"), "Encoded group key");
261
+ if (bound > 0xffff_ffff)
262
+ throw new RangeError("Encoded group key is too large");
263
+ ensureScratchCapacity(bound);
264
+ scratch[offset] = 4;
265
+ const payloadStart = offset + 5;
266
+ const payloadEnd = writeUtf8(key, payloadStart);
267
+ scratchView.setUint32(offset + 1, payloadEnd - payloadStart, true);
268
+ return payloadEnd;
269
+ }
270
+ /**
271
+ * Encodes `value` as UTF-8 at `offset`, which the caller has already sized. Unpaired surrogates
272
+ * become U+FFFD, matching `TextEncoder` so two distinct strings never collapse to one key.
273
+ */
274
+ function writeUtf8(value, offset) {
275
+ let write = offset;
276
+ for (let index = 0; index < value.length; index += 1) {
277
+ let code = value.charCodeAt(index);
278
+ if (code < 0x80) {
279
+ scratch[write] = code;
280
+ write += 1;
281
+ continue;
282
+ }
283
+ if (code < 0x800) {
284
+ scratch[write] = 0xc0 | (code >>> 6);
285
+ scratch[write + 1] = 0x80 | (code & 0x3f);
286
+ write += 2;
287
+ continue;
288
+ }
289
+ if (code >= 0xd800 && code <= 0xdbff) {
290
+ const low = index + 1 < value.length ? value.charCodeAt(index + 1) : 0;
291
+ if (low >= 0xdc00 && low <= 0xdfff) {
292
+ code = 0x10000 + ((code - 0xd800) << 10) + (low - 0xdc00);
293
+ index += 1;
294
+ scratch[write] = 0xf0 | (code >>> 18);
295
+ scratch[write + 1] = 0x80 | ((code >>> 12) & 0x3f);
296
+ scratch[write + 2] = 0x80 | ((code >>> 6) & 0x3f);
297
+ scratch[write + 3] = 0x80 | (code & 0x3f);
298
+ write += 4;
299
+ continue;
300
+ }
301
+ }
302
+ if (code >= 0xd800 && code <= 0xdfff) {
303
+ scratch[write] = REPLACEMENT_CHARACTER_BYTES[0];
304
+ scratch[write + 1] = REPLACEMENT_CHARACTER_BYTES[1];
305
+ scratch[write + 2] = REPLACEMENT_CHARACTER_BYTES[2];
306
+ write += 3;
307
+ continue;
308
+ }
309
+ scratch[write] = 0xe0 | (code >>> 12);
310
+ scratch[write + 1] = 0x80 | ((code >>> 6) & 0x3f);
311
+ scratch[write + 2] = 0x80 | (code & 0x3f);
312
+ write += 3;
313
+ }
314
+ return write;
315
+ }
316
+ function ensureScratchCapacity(required) {
317
+ if (required <= scratch.byteLength)
318
+ return;
319
+ let capacity = scratch.byteLength;
320
+ while (capacity < required)
321
+ capacity = safeDouble(capacity, "Group key scratch arena");
322
+ const grown = new Uint8Array(capacity);
323
+ // Earlier keys of a compound encoding already occupy the arena, so growth carries them over.
324
+ grown.set(scratch);
325
+ scratch = grown;
326
+ scratchView = new DataView(scratch.buffer);
327
+ }
328
+ /** FNV-1a over the scratch arena's first `length` bytes. Exported for the join index. */
329
+ export function hashScratch(length) {
330
+ let hash = 0x811c9dc5;
331
+ for (let index = 0; index < length; index += 1) {
332
+ hash = Math.imul(hash ^ (scratch[index] ?? 0), 0x01000193) >>> 0;
333
+ }
334
+ return hash;
335
+ }
336
+ /** Matches `arena[offset..offset+length)` against the scratch arena. Exported for the join index. */
337
+ export function equalsScratch(arena, offset, length) {
338
+ for (let index = 0; index < length; index += 1) {
339
+ if (arena[offset + index] !== scratch[index])
340
+ return false;
341
+ }
342
+ return true;
343
+ }
344
+ /** Copies the scratch arena's first `length` bytes into owned storage. Exported for the join index. */
345
+ export function copyScratchKey(length) {
346
+ return scratch.slice(0, length);
347
+ }
348
+ function safeDouble(value, label) {
349
+ const doubled = value * 2;
350
+ if (!Number.isSafeInteger(doubled))
351
+ throw new RangeError(`${label} exceeds the safe integer range`);
352
+ return doubled;
353
+ }
354
+ function safeProduct(left, right, label) {
355
+ const product = left * right;
356
+ if (!Number.isSafeInteger(product))
357
+ throw new RangeError(`${label} exceeds the safe integer range`);
358
+ return product;
359
+ }
360
+ function safeSum(left, right, label) {
361
+ const sum = left + right;
362
+ if (!Number.isSafeInteger(sum))
363
+ throw new RangeError(`${label} exceeds the safe integer range`);
364
+ return sum;
365
+ }
366
+ //# sourceMappingURL=group-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-index.js","sourceRoot":"","sources":["../../src/engine/group-index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export * from "./catalog.js";
2
+ export * from "./client.js";
3
+ export * from "./coordinator.js";
4
+ export * from "./database.js";
5
+ export * from "./schema-wire.js";
6
+ export * from "./worker-host.js";
7
+ export { bindPlanParameters, bindStatementParameters, compileQuery, compileStatement, executeQuery, referencedColumns, type InsertValue, type CompiledQuery, type CompiledStatement, type QueryResult, type QueryRow, type QueryExecutionOptions, type QueryValue, type SqlColumnSchema, type SqlColumnType, } from "./query.js";
8
+ export { QueryMemoryBudgetError, type QueryMemoryUsage } from "./memory.js";
9
+ export { optimizePlan, renderPlan } from "./optimizer.js";
10
+ export * from "./schema.js";
11
+ export * from "./live.js";
12
+ export type { AsyncQueryExecutionOptions, QuerySpillStore } from "./vector.js";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,YAAY,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,12 @@
1
+ export * from "./catalog.js";
2
+ export * from "./client.js";
3
+ export * from "./coordinator.js";
4
+ export * from "./database.js";
5
+ export * from "./schema-wire.js";
6
+ export * from "./worker-host.js";
7
+ export { bindPlanParameters, bindStatementParameters, compileQuery, compileStatement, executeQuery, referencedColumns, } from "./query.js";
8
+ export { QueryMemoryBudgetError } from "./memory.js";
9
+ export { optimizePlan, renderPlan } from "./optimizer.js";
10
+ export * from "./schema.js";
11
+ export * from "./live.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAUlB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,sBAAsB,EAAyB,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { QueryMemoryContext } from "./memory.js";
2
+ export type JoinIndexKey = boolean | number | string | Date;
3
+ /** Collision-checked scalar-key hash index with typed duplicate row chains. */
4
+ export declare class ByteJoinIndex {
5
+ #private;
6
+ constructor(memory: QueryMemoryContext, rowCapacity: number);
7
+ get unique(): boolean;
8
+ add(value: unknown, row: number): void;
9
+ firstRow(value: unknown): number;
10
+ nextRow(row: number): number;
11
+ }
12
+ //# sourceMappingURL=join-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"join-index.d.ts","sourceRoot":"","sources":["../../src/engine/join-index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAA+B,MAAM,aAAa,CAAC;AAQ9E,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAE5D,+EAA+E;AAC/E,qBAAa,aAAa;;gBAkBZ,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM;IAa3D,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAoCtC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAOhC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CA0G7B"}
@@ -0,0 +1,217 @@
1
+ import { copyScratchKey, encodeSingleScalarKey, equalsScratch, hashScratch, } from "./group-index.js";
2
+ const INITIAL_ENTRY_CAPACITY = 4;
3
+ const INITIAL_BUCKET_CAPACITY = 8;
4
+ const INITIAL_KEY_CAPACITY = 32;
5
+ const ENTRY_FIELDS = 6;
6
+ const UINT32_BYTES = Uint32Array.BYTES_PER_ELEMENT;
7
+ /** Collision-checked scalar-key hash index with typed duplicate row chains. */
8
+ export class ByteJoinIndex {
9
+ #memory;
10
+ #rowNext;
11
+ #buckets = new Int32Array(0);
12
+ #hashes = new Uint32Array(0);
13
+ #offsets = new Uint32Array(0);
14
+ #lengths = new Uint32Array(0);
15
+ #bucketNext = new Int32Array(0);
16
+ #rowHeads = new Int32Array(0);
17
+ #rowTails = new Int32Array(0);
18
+ #keys = new Uint8Array(0);
19
+ #keyLength = 0;
20
+ #entryCount = 0;
21
+ #unique = true;
22
+ #entryReservation;
23
+ #bucketReservation;
24
+ #keyReservation;
25
+ constructor(memory, rowCapacity) {
26
+ if (!Number.isSafeInteger(rowCapacity) || rowCapacity < 0) {
27
+ throw new RangeError("Join index row capacity must be a non-negative safe integer");
28
+ }
29
+ this.#memory = memory;
30
+ memory.reserve(safeProduct(rowCapacity, Int32Array.BYTES_PER_ELEMENT, "Join duplicate row chains"), "Join duplicate row chains");
31
+ this.#rowNext = new Int32Array(rowCapacity);
32
+ this.#rowNext.fill(-1);
33
+ }
34
+ get unique() {
35
+ return this.#unique;
36
+ }
37
+ add(value, row) {
38
+ if (!Number.isSafeInteger(row) || row < 0 || row >= this.#rowNext.length) {
39
+ throw new RangeError("Join index row is outside its declared capacity");
40
+ }
41
+ const length = encodeJoinKey(value);
42
+ if (length < 0)
43
+ return;
44
+ const hash = hashScratch(length);
45
+ const existing = this.#find(length, hash);
46
+ if (existing >= 0) {
47
+ const tail = this.#rowTails[existing] ?? -1;
48
+ if (tail < 0)
49
+ throw new Error("Join index row chain is corrupt");
50
+ this.#rowNext[tail] = row;
51
+ this.#rowTails[existing] = row;
52
+ this.#unique = false;
53
+ return;
54
+ }
55
+ const encoded = copyScratchKey(length);
56
+ const index = this.#entryCount;
57
+ this.#ensureEntryCapacity(index + 1);
58
+ this.#ensureBucketCapacity(index + 1);
59
+ this.#ensureKeyCapacity(encoded.byteLength);
60
+ const offset = this.#keyLength;
61
+ this.#keys.set(encoded, offset);
62
+ this.#keyLength += encoded.byteLength;
63
+ this.#hashes[index] = hash;
64
+ this.#offsets[index] = offset;
65
+ this.#lengths[index] = encoded.byteLength;
66
+ this.#rowHeads[index] = row;
67
+ this.#rowTails[index] = row;
68
+ const bucket = hash & (this.#buckets.length - 1);
69
+ this.#bucketNext[index] = this.#buckets[bucket] ?? -1;
70
+ this.#buckets[bucket] = index;
71
+ this.#entryCount += 1;
72
+ }
73
+ firstRow(value) {
74
+ const length = encodeJoinKey(value);
75
+ if (length < 0)
76
+ return -1;
77
+ const index = this.#find(length, hashScratch(length));
78
+ return index < 0 ? -1 : (this.#rowHeads[index] ?? -1);
79
+ }
80
+ nextRow(row) {
81
+ return row < 0 || row >= this.#rowNext.length ? -1 : (this.#rowNext[row] ?? -1);
82
+ }
83
+ /** Matches the scratch arena's first `length` bytes against stored keys without copying them. */
84
+ #find(length, hash) {
85
+ if (this.#buckets.length === 0)
86
+ return -1;
87
+ let index = this.#buckets[hash & (this.#buckets.length - 1)] ?? -1;
88
+ while (index >= 0) {
89
+ if (this.#hashes[index] === hash &&
90
+ this.#lengths[index] === length &&
91
+ equalsScratch(this.#keys, this.#offsets[index] ?? 0, length)) {
92
+ return index;
93
+ }
94
+ index = this.#bucketNext[index] ?? -1;
95
+ }
96
+ return -1;
97
+ }
98
+ #ensureEntryCapacity(required) {
99
+ if (required <= this.#hashes.length)
100
+ return;
101
+ let capacity = Math.max(INITIAL_ENTRY_CAPACITY, this.#hashes.length * 2);
102
+ while (capacity < required)
103
+ capacity = safeDouble(capacity, "Join index entries");
104
+ const reservation = this.#memory.reserve(safeProduct(capacity, ENTRY_FIELDS * UINT32_BYTES, "Join index entry storage"), "Join index entry storage");
105
+ try {
106
+ const hashes = new Uint32Array(capacity);
107
+ const offsets = new Uint32Array(capacity);
108
+ const lengths = new Uint32Array(capacity);
109
+ const bucketNext = new Int32Array(capacity);
110
+ const rowHeads = new Int32Array(capacity);
111
+ const rowTails = new Int32Array(capacity);
112
+ bucketNext.fill(-1);
113
+ rowHeads.fill(-1);
114
+ rowTails.fill(-1);
115
+ hashes.set(this.#hashes);
116
+ offsets.set(this.#offsets);
117
+ lengths.set(this.#lengths);
118
+ bucketNext.set(this.#bucketNext);
119
+ rowHeads.set(this.#rowHeads);
120
+ rowTails.set(this.#rowTails);
121
+ this.#hashes = hashes;
122
+ this.#offsets = offsets;
123
+ this.#lengths = lengths;
124
+ this.#bucketNext = bucketNext;
125
+ this.#rowHeads = rowHeads;
126
+ this.#rowTails = rowTails;
127
+ this.#entryReservation?.release();
128
+ this.#entryReservation = reservation;
129
+ }
130
+ catch (error) {
131
+ reservation.release();
132
+ throw error;
133
+ }
134
+ }
135
+ #ensureBucketCapacity(requiredEntries) {
136
+ let capacity = this.#buckets.length;
137
+ if (capacity === 0)
138
+ capacity = INITIAL_BUCKET_CAPACITY;
139
+ while (requiredEntries * 4 > capacity * 3) {
140
+ capacity = safeDouble(capacity, "Join index buckets");
141
+ }
142
+ if (capacity === this.#buckets.length)
143
+ return;
144
+ const reservation = this.#memory.reserve(safeProduct(capacity, Int32Array.BYTES_PER_ELEMENT, "Join index bucket storage"), "Join index bucket storage");
145
+ try {
146
+ const buckets = new Int32Array(capacity);
147
+ buckets.fill(-1);
148
+ for (let index = 0; index < this.#entryCount; index += 1) {
149
+ const bucket = (this.#hashes[index] ?? 0) & (capacity - 1);
150
+ this.#bucketNext[index] = buckets[bucket] ?? -1;
151
+ buckets[bucket] = index;
152
+ }
153
+ this.#buckets = buckets;
154
+ this.#bucketReservation?.release();
155
+ this.#bucketReservation = reservation;
156
+ }
157
+ catch (error) {
158
+ reservation.release();
159
+ throw error;
160
+ }
161
+ }
162
+ #ensureKeyCapacity(additionalBytes) {
163
+ const required = this.#keyLength + additionalBytes;
164
+ if (!Number.isSafeInteger(required))
165
+ throw new RangeError("Join key arena is too large");
166
+ if (required > 0xffff_ffff)
167
+ throw new RangeError("Join key arena exceeds uint32 offsets");
168
+ if (required <= this.#keys.byteLength)
169
+ return;
170
+ let capacity = Math.max(INITIAL_KEY_CAPACITY, this.#keys.byteLength * 2);
171
+ while (capacity < required)
172
+ capacity = safeDouble(capacity, "Join key arena");
173
+ const reservation = this.#memory.reserve(capacity, "Join key arena");
174
+ try {
175
+ const keys = new Uint8Array(capacity);
176
+ keys.set(this.#keys.subarray(0, this.#keyLength));
177
+ this.#keys = keys;
178
+ this.#keyReservation?.release();
179
+ this.#keyReservation = reservation;
180
+ }
181
+ catch (error) {
182
+ reservation.release();
183
+ throw error;
184
+ }
185
+ }
186
+ }
187
+ /**
188
+ * Encodes one join key into the shared scratch arena and returns its byte length, or -1 for keys
189
+ * SQL equality can never match (null, undefined, NaN). Dates coerce to their epoch milliseconds,
190
+ * so a Date and its number representation join as the same key.
191
+ */
192
+ function encodeJoinKey(value) {
193
+ const key = value instanceof Date ? value.getTime() : value;
194
+ if (key === null || key === undefined)
195
+ return -1;
196
+ if (typeof key === "number" && Number.isNaN(key))
197
+ return -1;
198
+ if (typeof key === "boolean" || typeof key === "number" || typeof key === "string") {
199
+ return encodeSingleScalarKey(key);
200
+ }
201
+ throw new TypeError("Join keys must be SQL scalar values");
202
+ }
203
+ function safeDouble(value, label) {
204
+ const doubled = value * 2;
205
+ if (!Number.isSafeInteger(doubled)) {
206
+ throw new RangeError(`${label} exceeds the safe integer range`);
207
+ }
208
+ return doubled;
209
+ }
210
+ function safeProduct(left, right, label) {
211
+ const product = left * right;
212
+ if (!Number.isSafeInteger(product)) {
213
+ throw new RangeError(`${label} exceeds the safe integer range`);
214
+ }
215
+ return product;
216
+ }
217
+ //# sourceMappingURL=join-index.js.map