@minnowdb/core 0.0.1 → 0.1.1

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 (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -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/errors.d.ts +55 -0
  64. package/dist/engine/errors.d.ts.map +1 -0
  65. package/dist/engine/errors.js +81 -0
  66. package/dist/engine/errors.js.map +1 -0
  67. package/dist/engine/fts.d.ts +93 -0
  68. package/dist/engine/fts.d.ts.map +1 -0
  69. package/dist/engine/fts.js +273 -0
  70. package/dist/engine/fts.js.map +1 -0
  71. package/dist/engine/group-index.d.ts +32 -0
  72. package/dist/engine/group-index.d.ts.map +1 -0
  73. package/dist/engine/group-index.js +366 -0
  74. package/dist/engine/group-index.js.map +1 -0
  75. package/dist/engine/index.d.ts +13 -0
  76. package/dist/engine/index.d.ts.map +1 -0
  77. package/dist/engine/index.js +12 -0
  78. package/dist/engine/index.js.map +1 -0
  79. package/dist/engine/join-index.d.ts +12 -0
  80. package/dist/engine/join-index.d.ts.map +1 -0
  81. package/dist/engine/join-index.js +217 -0
  82. package/dist/engine/join-index.js.map +1 -0
  83. package/dist/engine/live.d.ts +86 -0
  84. package/dist/engine/live.d.ts.map +1 -0
  85. package/dist/engine/live.js +289 -0
  86. package/dist/engine/live.js.map +1 -0
  87. package/dist/engine/memory.d.ts +37 -0
  88. package/dist/engine/memory.d.ts.map +1 -0
  89. package/dist/engine/memory.js +119 -0
  90. package/dist/engine/memory.js.map +1 -0
  91. package/dist/engine/optimizer.d.ts +20 -0
  92. package/dist/engine/optimizer.d.ts.map +1 -0
  93. package/dist/engine/optimizer.js +1170 -0
  94. package/dist/engine/optimizer.js.map +1 -0
  95. package/dist/engine/query-cache.d.ts +10 -0
  96. package/dist/engine/query-cache.d.ts.map +1 -0
  97. package/dist/engine/query-cache.js +58 -0
  98. package/dist/engine/query-cache.js.map +1 -0
  99. package/dist/engine/query.d.ts +844 -0
  100. package/dist/engine/query.d.ts.map +1 -0
  101. package/dist/engine/query.js +7450 -0
  102. package/dist/engine/query.js.map +1 -0
  103. package/dist/engine/schema-wire.d.ts +92 -0
  104. package/dist/engine/schema-wire.d.ts.map +1 -0
  105. package/dist/engine/schema-wire.js +115 -0
  106. package/dist/engine/schema-wire.js.map +1 -0
  107. package/dist/engine/schema.d.ts +394 -0
  108. package/dist/engine/schema.d.ts.map +1 -0
  109. package/dist/engine/schema.js +709 -0
  110. package/dist/engine/schema.js.map +1 -0
  111. package/dist/engine/sort-keys.d.ts +36 -0
  112. package/dist/engine/sort-keys.d.ts.map +1 -0
  113. package/dist/engine/sort-keys.js +60 -0
  114. package/dist/engine/sort-keys.js.map +1 -0
  115. package/dist/engine/sql-json.d.ts +30 -0
  116. package/dist/engine/sql-json.d.ts.map +1 -0
  117. package/dist/engine/sql-json.js +120 -0
  118. package/dist/engine/sql-json.js.map +1 -0
  119. package/dist/engine/sql-semantics.d.ts +31 -0
  120. package/dist/engine/sql-semantics.d.ts.map +1 -0
  121. package/dist/engine/sql-semantics.js +121 -0
  122. package/dist/engine/sql-semantics.js.map +1 -0
  123. package/dist/engine/vector.d.ts +87 -0
  124. package/dist/engine/vector.d.ts.map +1 -0
  125. package/dist/engine/vector.js +4227 -0
  126. package/dist/engine/vector.js.map +1 -0
  127. package/dist/engine/worker-host.d.ts +48 -0
  128. package/dist/engine/worker-host.d.ts.map +1 -0
  129. package/dist/engine/worker-host.js +501 -0
  130. package/dist/engine/worker-host.js.map +1 -0
  131. package/dist/engine/worker.d.ts +2 -0
  132. package/dist/engine/worker.d.ts.map +1 -0
  133. package/dist/engine/worker.js +14 -0
  134. package/dist/engine/worker.js.map +1 -0
  135. package/dist/index.d.ts +2 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +2 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/plan/index.d.ts +17 -0
  140. package/dist/plan/index.d.ts.map +1 -0
  141. package/dist/plan/index.js +17 -0
  142. package/dist/plan/index.js.map +1 -0
  143. package/dist/storage/fixture-shape.d.ts +42 -0
  144. package/dist/storage/fixture-shape.d.ts.map +1 -0
  145. package/dist/storage/fixture-shape.js +146 -0
  146. package/dist/storage/fixture-shape.js.map +1 -0
  147. package/dist/storage/index.d.ts +5 -0
  148. package/dist/storage/index.d.ts.map +1 -0
  149. package/dist/storage/index.js +5 -0
  150. package/dist/storage/index.js.map +1 -0
  151. package/dist/storage/indexeddb.d.ts +139 -0
  152. package/dist/storage/indexeddb.d.ts.map +1 -0
  153. package/dist/storage/indexeddb.js +3161 -0
  154. package/dist/storage/indexeddb.js.map +1 -0
  155. package/dist/storage/memory.d.ts +121 -0
  156. package/dist/storage/memory.d.ts.map +1 -0
  157. package/dist/storage/memory.js +1455 -0
  158. package/dist/storage/memory.js.map +1 -0
  159. package/dist/storage/snapshot.d.ts +108 -0
  160. package/dist/storage/snapshot.d.ts.map +1 -0
  161. package/dist/storage/snapshot.js +276 -0
  162. package/dist/storage/snapshot.js.map +1 -0
  163. package/dist/storage/types.d.ts +895 -0
  164. package/dist/storage/types.d.ts.map +1 -0
  165. package/dist/storage/types.js +1549 -0
  166. package/dist/storage/types.js.map +1 -0
  167. package/dist/testing/index.d.ts +76 -0
  168. package/dist/testing/index.d.ts.map +1 -0
  169. package/dist/testing/index.js +233 -0
  170. package/dist/testing/index.js.map +1 -0
  171. package/dist/testing/seeds.d.ts +11 -0
  172. package/dist/testing/seeds.d.ts.map +1 -0
  173. package/dist/testing/seeds.js +50 -0
  174. package/dist/testing/seeds.js.map +1 -0
  175. package/dist/transactions/index.d.ts +148 -0
  176. package/dist/transactions/index.d.ts.map +1 -0
  177. package/dist/transactions/index.js +662 -0
  178. package/dist/transactions/index.js.map +1 -0
  179. package/dist/worker-protocol/index.d.ts +84 -0
  180. package/dist/worker-protocol/index.d.ts.map +1 -0
  181. package/dist/worker-protocol/index.js +117 -0
  182. package/dist/worker-protocol/index.js.map +1 -0
  183. package/package.json +66 -16
  184. package/sql-feature-matrix.json +1275 -0
  185. package/index.d.ts +0 -1
  186. package/index.js +0 -1
@@ -0,0 +1,661 @@
1
+ import { type BatchRow, type BatchValue, type InsertBatchInput } from "./batch.js";
2
+ import { BufferedTableWriter, type BufferedWriterOptions } from "./buffered-writer.js";
3
+ export { attachLifecycleFlush, BufferedTableWriter, type BufferedFlushResult, type BufferedWriterOptions, type LifecycleDocumentTarget, type LifecycleFlushOptions, type LifecycleFlushRequester, type LifecyclePageTarget, } from "./buffered-writer.js";
4
+ import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MissingKeyError, SqlCompileError, UniqueConstraintError } from "./errors.js";
5
+ import { type Compression } from "../block-format/index.js";
6
+ import { type BlockStore, type ColumnDefault, type CompactionJobRecord, type CompactionJobState, type GarbageCollectionJobRecord, type GarbageCollectionJobState, type SimpleDataType, type SnapshotExportProgress, type SnapshotLoadProgress } from "../storage/index.js";
7
+ import { type CompiledQuery, type CompiledStatement, type ForeignKeyDefinition, type QueryResult, type QueryRow, type QueryValue } from "./query.js";
8
+ import { LiveQuerySet, type LiveQuerySetOptions } from "./live.js";
9
+ import { type Catalog } from "./catalog.js";
10
+ import { type AnyTable, type MigrationStep, type SchemaDefinition } from "./schema.js";
11
+ export interface ColumnDefinition {
12
+ name: string;
13
+ type: SimpleDataType;
14
+ nullable?: boolean;
15
+ /** Fills null-or-absent slots at insert time; never applied at read time. */
16
+ defaultValue?: ColumnDefault;
17
+ /** String columns only: the closed set of values writes must draw from. */
18
+ enumValues?: readonly string[];
19
+ /** What rows written before this column existed read as, instead of NULL. */
20
+ backfill?: boolean | number | string | Date;
21
+ }
22
+ export interface MigrateOptions {
23
+ /**
24
+ * Allows steps that destroy data — dropping a column or a table. Off by default: a migration
25
+ * runs when an application opens, with nobody to review it.
26
+ */
27
+ readonly allowDestructive?: boolean;
28
+ /**
29
+ * Treats the schema as the whole database, so a table it created and no longer declares is
30
+ * dropped. Off by default: an application may migrate feature by feature, and each call
31
+ * declaring only its own tables must not mean "drop the others". Needs `allowDestructive`
32
+ * as well, since dropping a table destroys its rows.
33
+ */
34
+ readonly schemaOwnsDatabase?: boolean;
35
+ }
36
+ export interface CreateTableInput {
37
+ name: string;
38
+ columns: readonly ColumnDefinition[];
39
+ /** Row conditions every written row must satisfy (E141-06); each is a boolean SQL expression. */
40
+ checks?: ReadonlyArray<{
41
+ name: string;
42
+ sql: string;
43
+ }>;
44
+ /** Marks the table as created from a schema, which lets a later migration drop it. */
45
+ managed?: boolean;
46
+ /** Single-column references to another table's unique key (E141-04). */
47
+ foreignKeys?: readonly ForeignKeyDefinition[];
48
+ uniqueKey?: string;
49
+ }
50
+ export type { BatchRow, BatchValue, ColumnarBatch, InsertBatchInput } from "./batch.js";
51
+ export interface InsertBatchResult {
52
+ tableName: string;
53
+ segmentId: string;
54
+ rowCount: number;
55
+ blockCount: number;
56
+ storedBytes: number;
57
+ version: number;
58
+ metrics: WriteMetrics;
59
+ /**
60
+ * Full written vectors, input row order, for every column where the engine filled at least
61
+ * one default or generated slot. Absent when the batch was written exactly as provided.
62
+ */
63
+ generatedColumns?: Record<string, BatchValue[]>;
64
+ }
65
+ export interface UpsertBatchResult extends InsertBatchResult {
66
+ insertedRowCount: number;
67
+ updatedRowCount: number;
68
+ }
69
+ export interface UpdateBatchInput {
70
+ keys: readonly BatchValue[];
71
+ changes: Readonly<Record<string, readonly BatchValue[]>>;
72
+ }
73
+ export interface UpdateBatchResult {
74
+ tableName: string;
75
+ segmentId: string;
76
+ requestedRowCount: number;
77
+ updatedRowCount: number;
78
+ changedColumns: string[];
79
+ blockCount: number;
80
+ storedBytes: number;
81
+ version: number;
82
+ metrics: WriteMetrics;
83
+ }
84
+ export interface WriteMetrics {
85
+ logicalBytes: number;
86
+ storedBytes: number;
87
+ writeAmplification: number;
88
+ encodeMs: number;
89
+ stageMs: number;
90
+ commitMs: number;
91
+ totalMs: number;
92
+ retries: number;
93
+ rowsPerSecond: number;
94
+ }
95
+ export interface ReadTableOptions {
96
+ version?: number;
97
+ columns?: readonly string[];
98
+ }
99
+ /**
100
+ * The scope handed to `snapshot()`: queries pinned to one manifest version, consistent with
101
+ * each other for the lifetime of the callback.
102
+ */
103
+ export interface SnapshotSession {
104
+ /** The pinned manifest version; null only on a database with no commits yet. */
105
+ readonly version: number | null;
106
+ query(sql: string, options?: QueryOptions): Promise<QueryResult>;
107
+ }
108
+ /** Lifetime buffer pool counters; see MinnowDatabase.bufferPoolStats(). */
109
+ export interface BufferPoolStats {
110
+ limitBytes: number;
111
+ usedBytes: number;
112
+ entries: number;
113
+ hits: number;
114
+ misses: number;
115
+ evictions: number;
116
+ }
117
+ /** One staged mutation inside a write scope; the commit version arrives on the scope. */
118
+ export interface StagedWriteResult {
119
+ tableName: string;
120
+ segmentId: string | null;
121
+ rowCount: number;
122
+ }
123
+ /**
124
+ * The scope handed to `write()`: every mutation stages into one transaction and publishes
125
+ * as one commit — all of it or none of it, in every tab. Reads observe the pre-scope snapshot
126
+ * plus everything the scope has staged, so later statements (and trigger bodies) see earlier
127
+ * ones; AFTER triggers fire per staged operation exactly as they do for standalone writes.
128
+ *
129
+ * A mutation that fails after registering part of its work ends the scope: the registration
130
+ * cannot be undone in place, so later statements and the commit both reject even if the caller
131
+ * caught the original error. A mutation that fails validation before registering anything
132
+ * leaves the scope usable.
133
+ */
134
+ export interface WriteSession {
135
+ /**
136
+ * Read-your-writes: the query observes the pre-scope snapshot PLUS everything this scope
137
+ * has staged so far, ordered after all committed data — without publishing anything.
138
+ */
139
+ query(sql: string, options?: {
140
+ params?: QueryOptions["params"];
141
+ }): Promise<QueryResult>;
142
+ insertBatch(tableName: string, input: InsertBatchInput): Promise<StagedWriteResult>;
143
+ upsertBatch(tableName: string, input: InsertBatchInput): Promise<StagedWriteResult>;
144
+ updateBatch(tableName: string, input: UpdateBatchInput): Promise<StagedWriteResult>;
145
+ deleteBatch(tableName: string, input: DeleteBatchInput): Promise<StagedWriteResult>;
146
+ }
147
+ /** What one statement's execution cost, reported by the engine that ran it. */
148
+ export interface QueryExecutionStats {
149
+ /**
150
+ * Peak modeled execution memory for this statement, in bytes: the documented vector,
151
+ * row-index, group/result payload, and ordering buffers, which is the same model
152
+ * `executionMemoryBudgetBytes` bounds. Boxed snapshot preparation, JavaScript container
153
+ * overhead, and allocator overhead are outside it. Not reported for a memo hit — nothing ran.
154
+ */
155
+ readonly peakMemoryBytes: number;
156
+ }
157
+ export interface QueryOptions {
158
+ /**
159
+ * Called once with what this execution cost, before the result is returned. Additive and
160
+ * optional: the engine can report its own memory because it reserves before it allocates,
161
+ * which is not something the storage layer or a caller could measure from outside.
162
+ */
163
+ readonly onStats?: (stats: QueryExecutionStats) => void;
164
+ /**
165
+ * false makes this statement compute its results instead of reusing any it has cached: the
166
+ * probe-validated result memo, cached block results, and the columnar forms of derived and
167
+ * windowed sources are all bypassed (the default true serves provably-fresh cached results
168
+ * from each). Block and vector caches stay warm — those cache storage reads, not results.
169
+ *
170
+ * Useful for benchmarking execution itself, and for callers that re-run one statement in a
171
+ * tight loop over changing external state. Note that replaying one statement over unchanging
172
+ * data with the default on measures cache lookups, not query execution.
173
+ */
174
+ memoize?: boolean;
175
+ readonly version?: number;
176
+ /**
177
+ * Values for the statement's `?`/`$n` placeholders, in order. Required exactly when the
178
+ * statement has placeholders; the compiled plan is cached on the SQL text and re-bound per
179
+ * execution, so parameterized queries skip re-parsing.
180
+ */
181
+ readonly params?: readonly QueryValue[];
182
+ /**
183
+ * Budget for the documented modeled vector, row-index, group/result payload, and ordering buffers.
184
+ * Boxed snapshot preparation, JavaScript container overhead, returned-result lifetime, and browser
185
+ * allocator overhead are not included in this Phase 7B-B model.
186
+ */
187
+ readonly executionMemoryBudgetBytes?: number;
188
+ /** Forces durable temp pages; with an explicit budget, spill otherwise retries only after exhaustion. */
189
+ readonly spillToStorage?: boolean;
190
+ /** Maximum rows encoded in each merged spill page. */
191
+ readonly spillPageRows?: number;
192
+ }
193
+ export interface DeleteBatchInput {
194
+ keys: readonly BatchValue[];
195
+ }
196
+ export interface DeleteBatchResult {
197
+ tableName: string;
198
+ segmentId: string | null;
199
+ requestedKeyCount: number;
200
+ deletedRowCount: number;
201
+ blockCount: number;
202
+ storedBytes: number;
203
+ version: number | null;
204
+ metrics: WriteMetrics;
205
+ }
206
+ export interface CompactTableOptions {
207
+ /** @deprecated Use minimumLevel0Segments. */
208
+ minimumSegments?: number;
209
+ /** Minimum L0 segments promoted; one also permits a direct L0 -> L2 promotion. */
210
+ minimumLevel0Segments?: number;
211
+ /** Target maximum L0 segments promoted by one job. Equal-order groups remain indivisible. */
212
+ maxLevel0Segments?: number;
213
+ /** Target maximum stored L0 bytes promoted by one job. The L1 anchor is excluded. */
214
+ maxLevel0StoredBytes?: number;
215
+ /** Number of immutable output blocks processed before yielding and checkpointing. */
216
+ maxBlocksPerStep?: number;
217
+ /** Output level. L2 is the append-only row-range partition policy. */
218
+ targetLevel?: number;
219
+ /** Hard L2 output-byte limit as a multiple of newly promoted L0 stored bytes. */
220
+ maxWriteAmplification?: number;
221
+ /** Estimated uncompressed physical bytes per output column block. */
222
+ targetBlockBytes?: number;
223
+ /** Compression used for rewritten output blocks. */
224
+ outputCompression?: Compression;
225
+ /** Upper bound for accounted JavaScript-owned executor buffers. */
226
+ memoryBudgetBytes?: number;
227
+ }
228
+ export interface CompactTableStepOptions extends CompactTableOptions {
229
+ maxBlocks?: number;
230
+ }
231
+ export type CompactionSkipReason = "below-segment-threshold" | "contains-mutation-segments" | "keys-outside-selected-sources" | "non-contiguous-row-ids" | "unsupported-level-layout" | "write-amplification-budget";
232
+ export interface CompactTableResult {
233
+ jobId?: string;
234
+ tableName: string;
235
+ compacted: boolean;
236
+ skipReason?: CompactionSkipReason;
237
+ sourceSegmentCount: number;
238
+ sourceBlockCount: number;
239
+ outputSegmentId: string | null;
240
+ outputBlockCount: number;
241
+ rowCount: number;
242
+ sourceStoredBytes: number;
243
+ outputStoredBytes: number;
244
+ level0SourceStoredBytes?: number;
245
+ anchorSourceStoredBytes?: number;
246
+ compactionWriteAmplification?: number;
247
+ outputPartitionOrdinal?: number;
248
+ maxWriteAmplification?: number;
249
+ maximumOutputStoredBytes?: number;
250
+ plannedOutputStoredBytesUpperBound?: number;
251
+ /** Stored bytes cancelled or aborted attempts at these sources already wrote. */
252
+ priorAttemptOutputStoredBytes?: number;
253
+ /** This attempt's output plus every prior failed attempt's, sharing one lifetime ceiling. */
254
+ lifetimeOutputStoredBytes?: number;
255
+ outputLogicalBytes?: number;
256
+ targetBlockBytes?: number;
257
+ outputCompression?: Compression;
258
+ memoryBudgetBytes?: number;
259
+ minimumMemoryBytes?: number;
260
+ peakWorkingBytes?: number;
261
+ supersededBlockCount: number;
262
+ physicallyReclaimedBytes: 0;
263
+ version: number | null;
264
+ metrics: WriteMetrics | null;
265
+ }
266
+ export interface CompactionJobProgress {
267
+ jobId: string | null;
268
+ tableName: string;
269
+ state: CompactionJobState | "skipped";
270
+ processedRows: number;
271
+ sourceSegmentCount: number;
272
+ sourceBlockCount: number;
273
+ outputBlockCount: number;
274
+ level0SourceStoredBytes?: number;
275
+ anchorSourceStoredBytes?: number;
276
+ outputPartitionOrdinal?: number;
277
+ maxWriteAmplification?: number;
278
+ maximumOutputStoredBytes?: number;
279
+ plannedOutputStoredBytesUpperBound?: number;
280
+ memoryBudgetBytes?: number;
281
+ minimumMemoryBytes?: number;
282
+ peakWorkingBytes?: number;
283
+ result: CompactTableResult | null;
284
+ }
285
+ export interface CancelCompactionJobResult {
286
+ jobId: string;
287
+ state: "cancelled" | "published" | "aborted";
288
+ publishedVersion: number | null;
289
+ }
290
+ export interface CollectGarbageOptions {
291
+ /** Maximum candidates examined and checkpointed by each durable reclamation step. */
292
+ maxItemsPerStep?: number;
293
+ /** Maximum block/segment candidates copied into one durable planning record. */
294
+ maxPlanningItems?: number;
295
+ }
296
+ export interface CollectGarbageStepOptions {
297
+ /** Maximum candidates examined and checkpointed by this durable reclamation step. */
298
+ maxItems?: number;
299
+ /** Maximum block/segment candidates copied into a newly planned job. */
300
+ maxPlanningItems?: number;
301
+ }
302
+ export interface GarbageCollectionResult {
303
+ jobId: string;
304
+ prunedManifestCount: number;
305
+ alreadyPrunedManifestCount: number;
306
+ retainedManifestCount: number;
307
+ missingManifestCount: number;
308
+ reclaimedSegmentCount: number;
309
+ retainedSegmentCount: number;
310
+ missingSegmentCount: number;
311
+ reclaimedBlockCount: number;
312
+ retainedBlockCount: number;
313
+ missingBlockCount: number;
314
+ physicallyReclaimedBytes: number;
315
+ }
316
+ export interface GarbageCollectionProgress {
317
+ jobId: string;
318
+ state: GarbageCollectionJobState;
319
+ examinedManifestCount: number;
320
+ examinedSegmentCount: number;
321
+ examinedBlockCount: number;
322
+ result: GarbageCollectionResult | null;
323
+ }
324
+ export interface TableDefinition {
325
+ name: string;
326
+ columns: ColumnDefinition[];
327
+ uniqueKey?: string;
328
+ }
329
+ export type DatabaseRow = Record<string, Exclude<BatchValue, null> | null>;
330
+ export { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MissingKeyError, SqlCompileError, UniqueConstraintError, };
331
+ export interface MinnowDatabaseOptions {
332
+ /**
333
+ * Block codec for newly written blocks; defaults to "gzip", which is also what compaction
334
+ * rewrites to, so a table's blocks are encoded the same way however they got there.
335
+ *
336
+ * Measured over 200k rows on IndexedDB, gzip against raw: about half the stored bytes
337
+ * (4.9 MiB vs 10.0 MiB) and a *faster* cold scan (13.3 ms vs 17.9 ms) — reading half the
338
+ * bytes out of IndexedDB more than pays for decompressing them — at the cost of roughly
339
+ * 2.2x on bulk ingest (413 ms vs 184 ms). Warm scans are identical either way, because the
340
+ * buffer pool caches decoded blocks. Choose "raw" when ingest throughput matters more than
341
+ * storage quota; the browser usually makes the opposite trade worth it.
342
+ */
343
+ compression?: Compression;
344
+ rowsPerBlock?: number;
345
+ maxCommitRetries?: number;
346
+ now?: () => Date;
347
+ createId?: () => string;
348
+ /** Durable spill-owner lease lifetime; renewed while a spilling query runs. */
349
+ spillOwnerLeaseMs?: number;
350
+ /**
351
+ * How long a statement-level transaction (`BEGIN` … `COMMIT`) may sit untouched before it
352
+ * rolls itself back; 30 seconds by default. A scope nobody ever closes would otherwise hold
353
+ * its staged blocks and transaction record against the collector forever.
354
+ */
355
+ transactionIdleTimeoutMs?: number;
356
+ /**
357
+ * Retained bytes for the block buffer pool: decoded physical blocks, their vectorized
358
+ * per-block column forms, zone-map block descriptions, and derived/subquery block
359
+ * results. Every entry is keyed by an immutable identity (a block id, or an exact
360
+ * visible-segment-id fingerprint), so a cached entry can never serve stale data;
361
+ * superseded entries simply stop being referenced and age out of the byte-bounded
362
+ * LRU. 0 disables the pool. Defaults to 64 MiB.
363
+ */
364
+ bufferPoolBytes?: number;
365
+ /**
366
+ * Visible-row threshold at which a full-text MATCH on an unindexed append-only column
367
+ * schedules a background index build (fire-and-forget; correctness never waits on it).
368
+ * Defaults to 4096.
369
+ */
370
+ ftsAutoIndexRows?: number;
371
+ /**
372
+ * Read-triggered compaction: when a streamed scan observes a table fragmented past
373
+ * 48 visible segments, one incremental compaction step is scheduled fire-and-forget —
374
+ * the same self-maintenance pattern as the full-text auto index. Correctness never waits
375
+ * on it; repeated scans advance further steps. false disables.
376
+ */
377
+ autoCompact?: boolean;
378
+ }
379
+ export interface QuerySpillCleanupOptions {
380
+ /** Maximum owners examined in this pass. */
381
+ maxOwners?: number;
382
+ }
383
+ export interface QuerySpillCleanupResult {
384
+ ownersExamined: number;
385
+ ownersReclaimed: number;
386
+ ownersRetained: number;
387
+ }
388
+ export type ExecuteResult = {
389
+ kind: "rows";
390
+ result: QueryResult;
391
+ } | {
392
+ kind: "create-table";
393
+ table: string;
394
+ } | {
395
+ kind: "add-column";
396
+ table: string;
397
+ column: string;
398
+ } | {
399
+ kind: "drop-table";
400
+ table: string;
401
+ dropped: boolean;
402
+ } | {
403
+ kind: "merge";
404
+ table: string;
405
+ rowCount: number;
406
+ version?: number;
407
+ } | {
408
+ kind: "transaction";
409
+ action: "begin" | "commit" | "rollback";
410
+ version?: number;
411
+ } | {
412
+ kind: "create-view";
413
+ view: string;
414
+ } | {
415
+ kind: "drop-view";
416
+ view: string;
417
+ dropped: boolean;
418
+ } | {
419
+ kind: "create-trigger";
420
+ table: string;
421
+ name: string;
422
+ } | {
423
+ kind: "drop-trigger";
424
+ name: string;
425
+ } | {
426
+ kind: "insert";
427
+ table: string;
428
+ rowCount: number;
429
+ /** Absent when the statement affected no rows (an INSERT ... SELECT of an empty set). */
430
+ version?: number;
431
+ returnedRows?: QueryRow[];
432
+ } | {
433
+ kind: "update";
434
+ table: string;
435
+ rowCount: number;
436
+ version?: number;
437
+ returnedRows?: QueryRow[];
438
+ } | {
439
+ kind: "delete";
440
+ table: string;
441
+ rowCount: number;
442
+ version?: number | null;
443
+ returnedRows?: QueryRow[];
444
+ };
445
+ export interface RunStatementOptions {
446
+ /**
447
+ * Projects the affected rows back: column names, or "*" for every table column. Inserts echo
448
+ * the written values; updates return post-update values; deletes return the rows as read.
449
+ */
450
+ readonly returning?: readonly string[] | "*";
451
+ /**
452
+ * Where the statement's writes go. Absent means the database itself — one commit per
453
+ * statement. A write scope routes them into that scope instead, which is how a statement-level
454
+ * transaction makes several statements publish together.
455
+ */
456
+ readonly writer?: StatementWriter;
457
+ }
458
+ /**
459
+ * A write scope seen as somewhere statements can run: the batch operations, plus the reads the
460
+ * keyed mutation paths need — by SQL for subqueries, by plan for the rows an UPDATE or DELETE
461
+ * is about to touch. Both reads observe the scope's own staged writes.
462
+ */
463
+ export interface StatementWriter extends WriteSession {
464
+ queryPlan(plan: CompiledQuery): Promise<QueryResult>;
465
+ }
466
+ export interface VisibleSegment {
467
+ id: string;
468
+ rowCount: number;
469
+ columnBlockIds: Readonly<Record<string, readonly string[]>>;
470
+ }
471
+ export interface SnapshotExportOptions {
472
+ /** Called as the export moves through its phases; see SnapshotExportProgress. */
473
+ onProgress?: (progress: SnapshotExportProgress) => void;
474
+ }
475
+ export interface SnapshotImportOptions {
476
+ /** Called as blocks land, for a progress bar over a multi-megabyte file. */
477
+ onProgress?: (progress: SnapshotLoadProgress) => void;
478
+ }
479
+ export declare class MinnowDatabase {
480
+ #private;
481
+ private readonly store;
482
+ constructor(store: BlockStore, options?: MinnowDatabaseOptions);
483
+ createTable(input: CreateTableInput): Promise<void>;
484
+ /**
485
+ * The published catalog: stable column IDs, key identity, constraints, triggers, and view
486
+ * bodies. This is the introspection surface schema tooling builds on — `listTables()` answers
487
+ * what a reader can select, this answers what a planner needs to diff.
488
+ */
489
+ introspect(): Promise<Catalog>;
490
+ listTables(): Promise<TableDefinition[]>;
491
+ /**
492
+ * Defines a view: a query the catalog answers to by name (F031-02). The stored record carries
493
+ * the query's inferred output schema, so a view answers the same questions a table does —
494
+ * what a reader can select, and of what type — and the devtools rail lists it beside them.
495
+ * Reads expand it into the query it stands for; writes to it are refused.
496
+ */
497
+ createView(name: string, sql: string, options?: {
498
+ orReplace?: boolean;
499
+ managed?: boolean;
500
+ }): Promise<void>;
501
+ /** Removes a view. Returns whether one was dropped; `ifExists` makes a missing one no error. */
502
+ dropView(name: string, options?: {
503
+ ifExists?: boolean;
504
+ }): Promise<boolean>;
505
+ /**
506
+ * Drops a table: its rows, its catalog record, its full-text index, and its triggers. The
507
+ * blocks are retired through an ordinary commit rather than deleted, so a reader pinned to an
508
+ * older version keeps resolving the bytes it already holds and the lease-aware collector
509
+ * reclaims them when nobody can reach them. What a pinned reader does lose is the table
510
+ * itself — the catalog has one present tense, so a snapshot open across a drop sees the table
511
+ * disappear rather than a frozen copy of it.
512
+ *
513
+ * Returns whether a table was dropped; with `ifExists`, a missing table is not an error.
514
+ */
515
+ dropTable(tableName: string, options?: {
516
+ ifExists?: boolean;
517
+ }): Promise<boolean>;
518
+ insertBatch(tableName: string, input: InsertBatchInput): Promise<InsertBatchResult>;
519
+ insert(tableName: string, row: BatchRow): Promise<InsertBatchResult>;
520
+ upsertBatch(tableName: string, input: InsertBatchInput): Promise<UpsertBatchResult>;
521
+ upsert(tableName: string, row: BatchRow): Promise<UpsertBatchResult>;
522
+ updateBatch(tableName: string, input: UpdateBatchInput): Promise<UpdateBatchResult>;
523
+ update(tableName: string, key: Exclude<BatchValue, null>, changes: Readonly<Record<string, BatchValue>>): Promise<UpdateBatchResult>;
524
+ deleteBatch(tableName: string, input: DeleteBatchInput): Promise<DeleteBatchResult>;
525
+ bufferedWriter(tableName: string, options?: BufferedWriterOptions): BufferedTableWriter;
526
+ readTable(tableName: string, versionOrOptions?: number | ReadTableOptions): Promise<DatabaseRow[]>;
527
+ /**
528
+ * Runs the callback against one pinned manifest version: every query inside the scope
529
+ * observes the same committed state, however many commits land meanwhile. This is the
530
+ * only pinning primitive — it cannot leak, because the pin is the scope. The version's
531
+ * blocks stay protected by an internal reader lease for the scope's duration, renewed
532
+ * while queries run; keep scopes short so garbage collection is not held back.
533
+ *
534
+ * On a database with no commits yet the session has no version to pin; its queries run
535
+ * fresh, which is indistinguishable until the first commit.
536
+ */
537
+ snapshot<T>(action: (session: SnapshotSession) => Promise<T>): Promise<T>;
538
+ /** Executes a read-only SELECT statement through the public query API. */
539
+ query(sql: string, options?: QueryOptions): Promise<QueryResult>;
540
+ /**
541
+ * Reclaims temp spill pages whose owner lease is expired or missing at a cutoff fixed when the
542
+ * pass starts. Owners with an unexpired lease are retained; each owner is removed atomically
543
+ * against a concurrent renewal.
544
+ */
545
+ cleanupQuerySpill(options?: QuerySpillCleanupOptions): Promise<QuerySpillCleanupResult>;
546
+ /**
547
+ * Creates a live-query set over this database. Local commits hint it directly, an optional
548
+ * channel carries cross-tab hints, and an optional poll interval bounds staleness without any
549
+ * hint; every hint path converges on the durable manifest version, so missed messages delay a
550
+ * refresh but never produce a stale result. Subscriptions retain a result digest, not rows.
551
+ */
552
+ liveQueries(options?: LiveQuerySetOptions): LiveQuerySet;
553
+ /**
554
+ * Runs the callback against one shared write transaction: every staged mutation — across
555
+ * any number of keyed or keyless tables, with their AFTER triggers — publishes as one
556
+ * atomic commit. A concurrent *write* surfaces as a WriteConflictError from the scope
557
+ * (nothing published); retry the whole scope. Background self-maintenance is not a
558
+ * concurrent write: the scope rebases over data-neutral manifests and commits anyway, so
559
+ * compaction landing mid-scope never fails it. An error thrown by the callback aborts the
560
+ * scope with nothing published. A scope that stages nothing publishes nothing.
561
+ */
562
+ write<T>(action: (session: WriteSession) => Promise<T>): Promise<{
563
+ result: T;
564
+ version: number | null;
565
+ }>;
566
+ /** Executes a built ORM query through the same streaming-first pipeline as compiled SQL. */
567
+ run<TRow>(query: {
568
+ kind: "typed-query";
569
+ plan: CompiledQuery;
570
+ __row?: TRow;
571
+ }): Promise<TRow[]>;
572
+ /**
573
+ * Applies a schema definition to the catalog through metadata-only steps: creating missing
574
+ * tables, adding nullable columns, renaming columns via their stable IDs, and widening
575
+ * nullability. The pass is idempotent — re-running after a crash completes the remaining
576
+ * steps — and every catalog alteration is one atomic compare-and-swap, so a concurrent
577
+ * migrator fails explicitly with a conflict instead of interleaving.
578
+ */
579
+ migrate(definition: SchemaDefinition<readonly AnyTable[]>, options?: MigrateOptions): Promise<{
580
+ createdTables: string[];
581
+ alteredTables: string[];
582
+ droppedTables: string[];
583
+ replacedViews: string[];
584
+ droppedViews: string[];
585
+ steps: MigrationStep[];
586
+ }>;
587
+ /**
588
+ * Renders the optimized logical plan for a SELECT statement plus the physical strategy notes
589
+ * the prepared execution would choose, without executing it.
590
+ */
591
+ explain(sql: string): Promise<string>;
592
+ /**
593
+ * Executes one SQL statement. SELECT statements run through the read-only query pipeline;
594
+ * INSERT ... VALUES maps onto a column batch insert, and UPDATE/DELETE on a unique-key table
595
+ * read the matching keys at one snapshot and then apply the keyed mutation. The read and the
596
+ * mutation are two steps, not one serializable transaction: a key changed by a competing writer
597
+ * in between fails the statement explicitly rather than silently mutating other rows.
598
+ */
599
+ execute(sql: string, params?: readonly QueryValue[]): Promise<ExecuteResult>;
600
+ /**
601
+ * Executes an already-compiled statement — the typed mutation builders call this directly with
602
+ * the same statement structures SQL parses into, sharing every validation and conflict rule.
603
+ * With `returning`, the affected rows project back: inserts echo the written values, deletes
604
+ * return the rows as read at the statement's snapshot, and updates return post-update values
605
+ * (the snapshot row with assignments applied — the exact values the mutation wrote).
606
+ */
607
+ runStatement(statement: CompiledStatement, options?: RunStatementOptions): Promise<ExecuteResult>;
608
+ listVisibleSegments(tableName: string, version?: number): Promise<VisibleSegment[]>;
609
+ /**
610
+ * Copies the current committed version out as a portable snapshot file — the byte array
611
+ * `../storage/snapshot.ts` describes, which `importSnapshot()` loads back into any store.
612
+ *
613
+ * The bytes are the unit here rather than the structured `DatabaseSnapshot` the store returns,
614
+ * because that is what a caller does with a snapshot: write it to disk, hand it to a colleague,
615
+ * ship it as an asset. Reach for `store.exportSnapshot()` directly when you want the records
616
+ * instead. Either way the whole snapshot is materialized in memory, so a database of hundreds
617
+ * of megabytes needs the headroom for a copy of itself.
618
+ *
619
+ * Stores differ in how they hold still while this runs: see the note on exporting safely in the
620
+ * snapshots guide.
621
+ */
622
+ exportSnapshot(options?: SnapshotExportOptions): Promise<Uint8Array>;
623
+ /**
624
+ * Loads a snapshot file into this database's store, which must be empty. Every block is
625
+ * authenticated while decoding, so a corrupt file fails here rather than mid-query, and a store
626
+ * that already holds a database throws rather than merging two histories.
627
+ */
628
+ importSnapshot(bytes: Uint8Array, options?: SnapshotImportOptions): Promise<void>;
629
+ compactTable(tableName: string, options?: CompactTableOptions): Promise<CompactTableResult>;
630
+ /** Plans or advances one restart-safe physical compaction job. */
631
+ compactTableStep(tableName: string, options?: CompactTableStepOptions): Promise<CompactionJobProgress>;
632
+ /** Continues a persisted compaction job after a cooperative yield or restart. */
633
+ resumeCompactionJob(jobId: string, options?: {
634
+ maxBlocks?: number;
635
+ }): Promise<CompactionJobProgress>;
636
+ listCompactionJobs(tableName?: string): Promise<CompactionJobRecord[]>;
637
+ /** Atomically prevents an unpublished compaction job from committing its transaction. */
638
+ cancelCompactionJob(jobId: string): Promise<CancelCompactionJobResult>;
639
+ /** Runs restart-safe lease-aware reclamation to completion in bounded durable steps. */
640
+ collectGarbage(options?: CollectGarbageOptions): Promise<GarbageCollectionResult>;
641
+ /** Plans or advances one durable garbage-collection pass. */
642
+ collectGarbageStep(options?: CollectGarbageStepOptions): Promise<GarbageCollectionProgress>;
643
+ /** Continues a persisted reclamation pass after a cooperative yield or restart. */
644
+ resumeGarbageCollectionJob(jobId: string, options?: CollectGarbageStepOptions): Promise<GarbageCollectionProgress>;
645
+ listGarbageCollectionJobs(): Promise<GarbageCollectionJobRecord[]>;
646
+ /**
647
+ * Buffer pool observability: byte budget and residency plus lifetime hit/miss/eviction
648
+ * counters across every entry family (decoded blocks, block vectors, zone descriptions,
649
+ * derived results, memoized results). Use it to size bufferPoolBytes from real workloads.
650
+ */
651
+ bufferPoolStats(): BufferPoolStats;
652
+ /**
653
+ * Builds (or rebuilds) the persisted full-text pruning index for one column from the current
654
+ * snapshot. Append-only tables only. The planner consults the index when the column is
655
+ * "ready" with a matching tokenizer version and re-verifies every candidate row, so a stale,
656
+ * missing, or lost index costs speed, never correctness. Searches schedule this lazily once
657
+ * a table crosses the auto-index threshold; calling it directly is just a warm-up.
658
+ */
659
+ buildFtsIndex(tableName: string, columnName: string): Promise<void>;
660
+ }
661
+ //# sourceMappingURL=database.d.ts.map