@quereus/store 4.5.0 → 4.7.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 (107) hide show
  1. package/README.md +34 -6
  2. package/dist/src/common/encoding.d.ts +4 -3
  3. package/dist/src/common/encoding.d.ts.map +1 -1
  4. package/dist/src/common/encoding.js +17 -13
  5. package/dist/src/common/encoding.js.map +1 -1
  6. package/dist/src/common/events.d.ts +31 -25
  7. package/dist/src/common/events.d.ts.map +1 -1
  8. package/dist/src/common/events.js +38 -39
  9. package/dist/src/common/events.js.map +1 -1
  10. package/dist/src/common/implicit-unique-index.d.ts +80 -0
  11. package/dist/src/common/implicit-unique-index.d.ts.map +1 -0
  12. package/dist/src/common/implicit-unique-index.js +148 -0
  13. package/dist/src/common/implicit-unique-index.js.map +1 -0
  14. package/dist/src/common/index.d.ts +7 -3
  15. package/dist/src/common/index.d.ts.map +1 -1
  16. package/dist/src/common/index.js +5 -2
  17. package/dist/src/common/index.js.map +1 -1
  18. package/dist/src/common/json-key.d.ts +30 -2
  19. package/dist/src/common/json-key.d.ts.map +1 -1
  20. package/dist/src/common/json-key.js +49 -2
  21. package/dist/src/common/json-key.js.map +1 -1
  22. package/dist/src/common/key-builder.d.ts +40 -20
  23. package/dist/src/common/key-builder.d.ts.map +1 -1
  24. package/dist/src/common/key-builder.js +31 -23
  25. package/dist/src/common/key-builder.js.map +1 -1
  26. package/dist/src/common/kv-store.d.ts +10 -0
  27. package/dist/src/common/kv-store.d.ts.map +1 -1
  28. package/dist/src/common/pk-key-resolution.d.ts +348 -0
  29. package/dist/src/common/pk-key-resolution.d.ts.map +1 -0
  30. package/dist/src/common/pk-key-resolution.js +481 -0
  31. package/dist/src/common/pk-key-resolution.js.map +1 -0
  32. package/dist/src/common/store-module-access-plan.d.ts +32 -0
  33. package/dist/src/common/store-module-access-plan.d.ts.map +1 -0
  34. package/dist/src/common/store-module-access-plan.js +428 -0
  35. package/dist/src/common/store-module-access-plan.js.map +1 -0
  36. package/dist/src/common/store-module-alter-column.d.ts +23 -0
  37. package/dist/src/common/store-module-alter-column.d.ts.map +1 -0
  38. package/dist/src/common/store-module-alter-column.js +389 -0
  39. package/dist/src/common/store-module-alter-column.js.map +1 -0
  40. package/dist/src/common/store-module-alter.d.ts +55 -0
  41. package/dist/src/common/store-module-alter.d.ts.map +1 -0
  42. package/dist/src/common/store-module-alter.js +504 -0
  43. package/dist/src/common/store-module-alter.js.map +1 -0
  44. package/dist/src/common/store-module-base.d.ts +268 -0
  45. package/dist/src/common/store-module-base.d.ts.map +1 -0
  46. package/dist/src/common/store-module-base.js +362 -0
  47. package/dist/src/common/store-module-base.js.map +1 -0
  48. package/dist/src/common/store-module-catalog.d.ts +269 -0
  49. package/dist/src/common/store-module-catalog.d.ts.map +1 -0
  50. package/dist/src/common/store-module-catalog.js +462 -0
  51. package/dist/src/common/store-module-catalog.js.map +1 -0
  52. package/dist/src/common/store-module-index-build.d.ts +88 -0
  53. package/dist/src/common/store-module-index-build.d.ts.map +1 -0
  54. package/dist/src/common/store-module-index-build.js +280 -0
  55. package/dist/src/common/store-module-index-build.js.map +1 -0
  56. package/dist/src/common/store-module-index.d.ts +116 -0
  57. package/dist/src/common/store-module-index.d.ts.map +1 -0
  58. package/dist/src/common/store-module-index.js +373 -0
  59. package/dist/src/common/store-module-index.js.map +1 -0
  60. package/dist/src/common/store-module-rename.d.ts +49 -0
  61. package/dist/src/common/store-module-rename.d.ts.map +1 -0
  62. package/dist/src/common/store-module-rename.js +268 -0
  63. package/dist/src/common/store-module-rename.js.map +1 -0
  64. package/dist/src/common/store-module-schema-rewrite.d.ts +57 -0
  65. package/dist/src/common/store-module-schema-rewrite.d.ts.map +1 -0
  66. package/dist/src/common/store-module-schema-rewrite.js +140 -0
  67. package/dist/src/common/store-module-schema-rewrite.js.map +1 -0
  68. package/dist/src/common/store-module-schema-sync.d.ts +232 -0
  69. package/dist/src/common/store-module-schema-sync.d.ts.map +1 -0
  70. package/dist/src/common/store-module-schema-sync.js +529 -0
  71. package/dist/src/common/store-module-schema-sync.js.map +1 -0
  72. package/dist/src/common/store-module.d.ts +43 -909
  73. package/dist/src/common/store-module.d.ts.map +1 -1
  74. package/dist/src/common/store-module.js +184 -3276
  75. package/dist/src/common/store-module.js.map +1 -1
  76. package/dist/src/common/store-table-base.d.ts +539 -0
  77. package/dist/src/common/store-table-base.d.ts.map +1 -0
  78. package/dist/src/common/store-table-base.js +900 -0
  79. package/dist/src/common/store-table-base.js.map +1 -0
  80. package/dist/src/common/store-table-constraints.d.ts +237 -0
  81. package/dist/src/common/store-table-constraints.d.ts.map +1 -0
  82. package/dist/src/common/store-table-constraints.js +624 -0
  83. package/dist/src/common/store-table-constraints.js.map +1 -0
  84. package/dist/src/common/store-table-scan.d.ts +452 -0
  85. package/dist/src/common/store-table-scan.d.ts.map +1 -0
  86. package/dist/src/common/store-table-scan.js +901 -0
  87. package/dist/src/common/store-table-scan.js.map +1 -0
  88. package/dist/src/common/store-table.d.ts +71 -1144
  89. package/dist/src/common/store-table.d.ts.map +1 -1
  90. package/dist/src/common/store-table.js +168 -2385
  91. package/dist/src/common/store-table.js.map +1 -1
  92. package/dist/src/testing/index.d.ts +12 -0
  93. package/dist/src/testing/index.d.ts.map +1 -0
  94. package/dist/src/testing/index.js +12 -0
  95. package/dist/src/testing/index.js.map +1 -0
  96. package/dist/src/testing/kv-assert.d.ts +19 -0
  97. package/dist/src/testing/kv-assert.d.ts.map +1 -0
  98. package/dist/src/testing/kv-assert.js +25 -0
  99. package/dist/src/testing/kv-assert.js.map +1 -0
  100. package/dist/src/testing/kv-conformance.d.ts.map +1 -1
  101. package/dist/src/testing/kv-conformance.js +1 -15
  102. package/dist/src/testing/kv-conformance.js.map +1 -1
  103. package/dist/src/testing/kv-provider-conformance.d.ts +54 -0
  104. package/dist/src/testing/kv-provider-conformance.d.ts.map +1 -0
  105. package/dist/src/testing/kv-provider-conformance.js +183 -0
  106. package/dist/src/testing/kv-provider-conformance.js.map +1 -0
  107. package/package.json +8 -8
@@ -0,0 +1,539 @@
1
+ /**
2
+ * State and storage plumbing shared by every layer of the KVStore-backed virtual
3
+ * table: schema/key-encoding state, store + coordinator handles, statistics,
4
+ * transaction lifecycle, and the effective-read primitives (committed store
5
+ * merged with the coordinator's pending ops) the read and write paths build on.
6
+ *
7
+ * Base of the store-table layer chain:
8
+ * StoreTableBase -> StoreTableScan -> StoreTableConstraints -> StoreTable
9
+ */
10
+ import { VirtualTable, type Database, type CollationResolver, type TableSchema, type TableIndexSchema, type Row, type SqlValue, type TableStatistics, type VirtualTableConnection } from '@quereus/quereus';
11
+ import type { IterateOptions, KVEntry, KVStore } from './kv-store.js';
12
+ import type { DataChangeEvent, StoreEventEmitter } from './events.js';
13
+ import type { TransactionCoordinator } from './transaction.js';
14
+ import { StoreConnection } from './store-connection.js';
15
+ import { type TableStats } from './serialization.js';
16
+ import { type EncodeOptions, type KeyValueTransform } from './encoding.js';
17
+ /**
18
+ * Configuration for a store table.
19
+ */
20
+ export interface StoreTableConfig {
21
+ /** Collation for text keys. Default: 'NOCASE'. */
22
+ collation?: 'BINARY' | 'NOCASE';
23
+ /**
24
+ * Serialized-byte budget for a single index-build write batch (see
25
+ * `buildIndexEntries` (store-module-index-build.ts)). Parsed from the `max_batch_bytes` module
26
+ * arg; undefined falls back to the module default.
27
+ */
28
+ maxBatchBytes?: number;
29
+ /** Additional platform-specific options. */
30
+ [key: string]: unknown;
31
+ }
32
+ /**
33
+ * Interface for the store module that manages this table.
34
+ * Provides access to stores and coordinators.
35
+ */
36
+ export interface StoreTableModule {
37
+ /** Get the data store for a table. */
38
+ getStore(schemaName: string, tableName: string, config: StoreTableConfig): Promise<KVStore>;
39
+ /** Get an index store for a table. */
40
+ getIndexStore(schemaName: string, tableName: string, indexName: string): Promise<KVStore>;
41
+ /** Get the stats store for a table. */
42
+ getStatsStore(schemaName: string, tableName: string): Promise<KVStore>;
43
+ /**
44
+ * Get the module's single shared transaction coordinator (one per storage
45
+ * module, shared by every table — the unit of cross-table atomicity).
46
+ * Synchronous: ops are addressed by explicit store handle, so obtaining a
47
+ * coordinator never requires opening storage.
48
+ */
49
+ getCoordinator(): TransactionCoordinator;
50
+ /** Save table DDL to persistent storage (unconditional put). */
51
+ saveTableDDL(tableSchema: TableSchema): Promise<void>;
52
+ /** Write table DDL only when the persisted entry is absent or differs. */
53
+ persistTableCatalogEntryIfChanged(tableSchema: TableSchema): Promise<void>;
54
+ }
55
+ /**
56
+ * Storage-facing base of the generic KVStore-backed virtual table.
57
+ *
58
+ * Holds the table's schema-derived key encoding state, its data/index/stats
59
+ * store handles and transaction coordinator, its statistics accounting, and the
60
+ * effective-row reads every higher layer issues. Platform-specific behavior is
61
+ * delegated to the {@link StoreTableModule}.
62
+ *
63
+ * NOTE: `export` here is required, not intentional API surface — `StoreTable extends`
64
+ * this class transitively, so TypeScript cannot emit its declaration unless every base
65
+ * in the chain is nameable (TS4020). The package index deliberately does not re-export
66
+ * this class or the two layers above it; if an API-surface extractor is ever added, it
67
+ * should treat them as internal rather than prompt a re-export.
68
+ */
69
+ export declare abstract class StoreTableBase extends VirtualTable {
70
+ protected storeModule: StoreTableModule;
71
+ protected config: StoreTableConfig;
72
+ protected store: KVStore | null;
73
+ protected storeInitPromise: Promise<KVStore> | null;
74
+ protected indexStores: Map<string, KVStore>;
75
+ protected statsStore: KVStore | null;
76
+ protected coordinator: TransactionCoordinator | null;
77
+ /**
78
+ * Disposer returned by the coordinator's `registerCallbacks`, captured on the
79
+ * first {@link attachCoordinator}. Run by {@link dispose} at hard eviction to
80
+ * deregister this instance's {stats apply/discard} pair from the module-wide
81
+ * coordinator; null until attached, and nulled again after dispose.
82
+ */
83
+ private coordinatorDisposer;
84
+ protected connection: StoreConnection | null;
85
+ protected eventEmitter?: StoreEventEmitter;
86
+ protected encodeOptions: EncodeOptions;
87
+ protected pkDirections: boolean[];
88
+ /**
89
+ * Per-PK-column KEY collation (see {@link resolvePkKeyCollations}). Drives the
90
+ * physical encoding of every data key and the PK suffix of every secondary-index
91
+ * key, so a text PK column declared BINARY/NOCASE/RTRIM is keyed under its own
92
+ * collation rather than one fixed table-level collation. Recomputed on every
93
+ * {@link updateSchema} (an ALTER COLUMN SET COLLATE on a PK member changes it).
94
+ */
95
+ protected pkKeyCollations: (string | undefined)[];
96
+ /**
97
+ * Per-PK-column key-identity value transform (see {@link resolvePkKeyTransforms}).
98
+ * Threaded alongside {@link pkKeyCollations} into every data-key / PK-suffix /
99
+ * PK-prefix-bounds encode, so a semantic-ordering PK member (TIMESPAN) keys
100
+ * semantically-equal spellings to one physical key. Recomputed on every
101
+ * {@link updateSchema}.
102
+ */
103
+ protected pkKeyTransforms: (KeyValueTransform | undefined)[];
104
+ /**
105
+ * Per-PK-column typed EQUALITY comparator for the semantic-ordering members only —
106
+ * `undefined` for every other member, which `StoreTableConstraints.keysEqual` still compares with
107
+ * strict `!==` as before. Keeps self-PK exclusion and PK-identity questions in
108
+ * agreement with the physical key identity above ('PT1H' row IS the 'PT60M' row).
109
+ */
110
+ protected pkSemanticEquality: (((a: SqlValue, b: SqlValue) => number) | undefined)[];
111
+ /**
112
+ * `db.getCollationResolver()`, bound once at construction. Every collation-aware
113
+ * VALUE comparison this table makes — pushed-constraint re-check, UNIQUE conflict
114
+ * detection — resolves names through it, so a collation registered with
115
+ * `db.registerCollation` on *this* connection is honored rather than silently
116
+ * degraded to BINARY by the process-global built-in registry.
117
+ *
118
+ * Only the resolver closure is cached: it reads the live registry, so a collation
119
+ * registered after connect is still visible. Resolved *functions* are hoisted no
120
+ * further than the comparator or constraint check that resolved them.
121
+ *
122
+ * Its key-bytes counterpart, `db.getKeyNormalizerResolver()`, is bound into
123
+ * {@link encodeOptions} so the names in {@link pkKeyCollations} resolve to the same
124
+ * per-connection registry.
125
+ */
126
+ protected readonly collationResolver: CollationResolver;
127
+ protected ddlSaved: boolean;
128
+ protected cachedStats: TableStats | null;
129
+ protected pendingStatsDelta: number;
130
+ protected mutationCount: number;
131
+ protected statsFlushPending: boolean;
132
+ /**
133
+ * {@link tableSchema} with a hidden `_uc_*` secondary index materialized per
134
+ * non-derived UNIQUE constraint that no explicit index already covers (see
135
+ * {@link withImplicitUniqueIndexes}) — the schema that drives UNIQUE ENFORCEMENT
136
+ * (`StoreTableConstraints.findIndexForUniqueConstraint`) and physical index MAINTENANCE
137
+ * (`StoreTableConstraints.updateSecondaryIndexes`).
138
+ *
139
+ * Deliberately SEPARATE from the engine-facing {@link tableSchema}: the engine
140
+ * reads `tableInstance.tableSchema` at CREATE (`SchemaManager.finalizeCreatedTableSchema`)
141
+ * and the read-query planner reads the registered schema, and NEITHER may see
142
+ * `_uc_*` (mirrors the memory backend keeping its materialized schema
143
+ * manager-local; a plain UNIQUE gets no read-side plan from `_uc_*`, only
144
+ * enforcement). Recomputed alongside `tableSchema` in the constructor and
145
+ * {@link updateSchema}.
146
+ */
147
+ protected materializedSchema: TableSchema;
148
+ constructor(db: Database, storeModule: StoreTableModule, tableSchema: TableSchema, config: StoreTableConfig, eventEmitter?: StoreEventEmitter, isConnected?: boolean);
149
+ /**
150
+ * Reject, at DDL time, any collation this table's key encoding would need but cannot
151
+ * use — before a single row is written under bytes the connection cannot reproduce.
152
+ *
153
+ * A collation keys a persisted structure only if it carries a KEY NORMALIZER (the
154
+ * `(s) => string` whose output equality partitions strings exactly as its comparator
155
+ * does). `db.registerCollation(name, cmp)` with no `{ normalizer }` gives a collation
156
+ * that can order rows but not key them; an unregistered name gives nothing at all.
157
+ * Both raise here rather than at the first insert.
158
+ *
159
+ * Checked over exactly the collations the key encoding actually uses:
160
+ * - every defined `pkKeyCollations` entry (text-capable PK columns);
161
+ * - every defined index key collation of every index in the MATERIALIZED schema
162
+ * (`resolveIndexKeyCollations` — the index column's COLLATE, else the table
163
+ * column's declared collation, else BINARY; hidden `_uc_*` indexes included).
164
+ *
165
+ * Two deliberate consequences of validating the actual index key collations rather
166
+ * than blanket-requiring the table key collation K whenever any index column is
167
+ * text-capable (the pre-per-column-index-collation behavior):
168
+ * - an index column declaring a comparator-only collation is rejected here instead
169
+ * of silently keying under K;
170
+ * - a table whose K has no normalizer but whose key encoding never uses K (all
171
+ * index columns BINARY/type-native, PK needing no K) is no longer unopenable.
172
+ *
173
+ * Blast radius: this also fires on catalog rehydration. Reopening a persisted database
174
+ * from a connection that has not re-registered its custom collation now throws at
175
+ * CREATE-TABLE-from-catalog rather than silently reading rows under a key layout it
176
+ * cannot reproduce. See `docs/plugins.md`.
177
+ *
178
+ * Takes `pkKeyCollations` rather than reading the field so `updateSchema` can validate
179
+ * the incoming schema BEFORE it overwrites its own state with it.
180
+ */
181
+ private validateKeyCollations;
182
+ /**
183
+ * Throw-only half of {@link validateKeyCollations}: raise unless every name in
184
+ * `names` resolves to a registered key normalizer.
185
+ */
186
+ private assertCollationsCanKey;
187
+ /**
188
+ * Throw-only pre-check for `StoreModuleIndex.createIndex`: reject a NEW index whose
189
+ * key collations cannot key (comparator-only or unregistered), BEFORE the physical
190
+ * index store is created — so a rejection leaves no store directory behind even for
191
+ * an empty table (where the build itself would encode nothing and the later
192
+ * `updateSchema` validation would fire only after the store exists).
193
+ */
194
+ assertIndexKeyCollationsCanKey(indexSchema: TableIndexSchema): void;
195
+ /**
196
+ * Reject, at DDL time, a key member whose semantic-ordering logical type has no
197
+ * store key transform — before a single row is keyed under bytes whose order the
198
+ * type's `compare` (and so the isolation merge, the memory oracle, and Sort)
199
+ * disagrees with.
200
+ *
201
+ * A semantic-ordering type keys soundly only through an order- and
202
+ * identity-preserving transform ({@link storeSemanticKeyTransform}: the type's
203
+ * `groupKey`, or a store-local encoder like JSON's structural one). This gap used
204
+ * to be undetectable — JSON sat here transform-less for a release, keying in
205
+ * canonical-text order while every comparator ordered structurally, and the only
206
+ * symptom was a misaligned overlay merge deep inside a transaction. Unreachable
207
+ * today (TIMESPAN and JSON are both covered); it exists so the NEXT
208
+ * semantic-ordering type fails loudly at CREATE TABLE instead.
209
+ *
210
+ * Checked over the same materialized schema as {@link validateKeyCollations}:
211
+ * every PK member and every (explicit or hidden `_uc_*`) index column.
212
+ *
213
+ * CAVEAT: this can only check that a transform EXISTS — a `groupKey` that is
214
+ * identity-faithful but not order-preserving passes undetected, so a new type's
215
+ * transform still needs its byte order argued against its `compare` (see
216
+ * json-key.ts for the shape of that argument).
217
+ */
218
+ private validateSemanticKeyTransforms;
219
+ /** Get the table configuration. */
220
+ getConfig(): StoreTableConfig;
221
+ /** Get the table schema (engine-facing, WITHOUT the hidden `_uc_*` indexes). */
222
+ getSchema(): TableSchema;
223
+ /**
224
+ * Get the enforcement schema — {@link getSchema} plus the hidden `_uc_*`
225
+ * index materialized per non-derived UNIQUE. Used by the module to resolve the
226
+ * physical index store to build/tear down during ALTER; never registered with
227
+ * the engine.
228
+ */
229
+ getMaterializedSchema(): TableSchema;
230
+ /**
231
+ * Update the table schema after an ALTER TABLE / CREATE INDEX operation.
232
+ *
233
+ * Validates the incoming schema's key collations before adopting any of it, so a
234
+ * rejection leaves this table on its previous, consistent schema.
235
+ */
236
+ updateSchema(newSchema: TableSchema): void;
237
+ /**
238
+ * Mark the table's DDL as already persisted to the catalog, so the lazy
239
+ * first-store-access save in {@link initializeStore} is skipped. Called by
240
+ * `StoreModule.createIndex` / `dropIndex` after they eagerly write the catalog
241
+ * bundle, so a subsequent INSERT does not redundantly re-persist identical DDL.
242
+ */
243
+ markDdlSaved(): void;
244
+ /** Close and forget a cached index-store handle, if any. */
245
+ releaseIndexStore(indexName: string): Promise<void>;
246
+ /**
247
+ * Returns true if the table has at least one LIVE row — the open transaction's
248
+ * pending overlay over the committed store. Stops after the first hit.
249
+ *
250
+ * Effective (not committed-only) because its one caller, `ADD COLUMN`'s NOT
251
+ * NULL-without-DEFAULT rejection, must see rows the same transaction inserted:
252
+ * they are migrated too (the arm DDL-commits before `migrateRows`), and a
253
+ * committed-only probe would wave them through only to give them a NULL in a
254
+ * NOT NULL column. Conversely, a pending delete of the last row makes the table
255
+ * legitimately empty. Reading effectively keeps the check throw-only and
256
+ * BEFORE the DDL-commit, so a rejection leaves the transaction intact.
257
+ */
258
+ hasAnyRows(): Promise<boolean>;
259
+ /**
260
+ * Yield the LIVE value of `colIndex` for every row — the open transaction's
261
+ * pending overlay over the committed store. For throw-only ALTER COLUMN probes
262
+ * that must run BEFORE the arm's DDL-commit (see `StoreModule.ddlCommitPendingOps`):
263
+ * they have to see rows this transaction wrote, because those rows are rewritten
264
+ * too, and a rejection here must leave the transaction intact.
265
+ */
266
+ iterateEffectiveValuesAtIndex(colIndex: number): AsyncIterable<SqlValue>;
267
+ /**
268
+ * Count the LIVE rows whose column at `colIndex` holds NULL (see
269
+ * {@link iterateEffectiveValuesAtIndex} for why this reads effectively).
270
+ * Used by ALTER COLUMN SET NOT NULL to decide whether the tightening is safe.
271
+ */
272
+ rowsWithNullAtIndex(colIndex: number): Promise<number>;
273
+ /**
274
+ * Ensure the data store is open and DDL is persisted.
275
+ * Uses a promise-based singleton pattern to prevent race conditions
276
+ * when multiple concurrent queries access the same table.
277
+ */
278
+ protected ensureStore(): Promise<KVStore>;
279
+ /**
280
+ * Internal method to actually initialize the store.
281
+ * Only called once per table instance.
282
+ */
283
+ private initializeStore;
284
+ /**
285
+ * Get or create an index store for the given index name.
286
+ */
287
+ protected ensureIndexStore(indexName: string): Promise<KVStore>;
288
+ /**
289
+ * Read the persisted row count into {@link cachedStats} once per table instance,
290
+ * before any mutation can be tracked against it.
291
+ *
292
+ * `trackMutation` / `applyPendingStats` both seed a missing `cachedStats` with
293
+ * `rowCount: 0` and add their delta to it, so WITHOUT this priming the first write
294
+ * after a reopen silently restarted the count from zero: a table reopened with 500
295
+ * persisted rows reported 1 after a single insert, and the next
296
+ * {@link flushStats} made that durable. Nothing read the count for planning before,
297
+ * so the loss was invisible; it is not once {@link getKnownRowCount} prices access
298
+ * plans with it.
299
+ *
300
+ * Called from {@link initializeStore}, which every read and write path awaits
301
+ * before touching storage — so priming precedes the first `trackMutation` without
302
+ * any caller having to remember it. Costs one extra KV `get` per table per session.
303
+ *
304
+ * Statistics are advisory (same posture as `StoreModuleRename`'s stats re-key): a
305
+ * failure to open or read the stats store warns and leaves the count unknown rather
306
+ * than failing the storage open that carries the caller's actual query.
307
+ *
308
+ * NOTE: on that failure path the pre-fix behaviour returns for this table — the next
309
+ * `trackMutation` seeds `cachedStats` at 0 and a later {@link flushStats} makes the
310
+ * restarted count durable, silently discarding the persisted one. Tolerated because a
311
+ * stats-store read failure is already a storage-level fault and the count is advisory.
312
+ * If it ever needs to be safe, gate {@link flushStats} on a "primed or genuinely
313
+ * absent" flag rather than on `cachedStats` being non-null.
314
+ */
315
+ private primeStats;
316
+ /**
317
+ * Get or create the stats store.
318
+ */
319
+ protected ensureStatsStore(): Promise<KVStore>;
320
+ /**
321
+ * Resolve + cache the module's shared TransactionCoordinator and hook the
322
+ * stats lifecycle callbacks, WITHOUT creating or registering a connection.
323
+ * Synchronous (the coordinator is handle-addressed, never store-opening — see
324
+ * `StoreTableModule.getCoordinator`), so the backing host's resolution path can
325
+ * call it eagerly. Attaching matters for reads: `iterateEffective` /
326
+ * `readEffectiveRowByKey` consult `this.coordinator` for the pending merge, so a
327
+ * table whose only writer is the privileged backing host (which queues ops on the
328
+ * module coordinator, never through `update()`) must still hold the
329
+ * reference for its read paths to be reads-own-writes.
330
+ *
331
+ * The coordinator is module-wide, so its commit/rollback callback array holds
332
+ * one {stats apply/discard} pair per PARTICIPATING table; each table's
333
+ * `applyPendingStats` early-returns when its own `pendingStatsDelta` is 0, so a
334
+ * table that did no work contributes nothing. Registers only on first call per
335
+ * StoreTable instance (the `if (!this.coordinator)` guard); a fresh instance
336
+ * after drop+recreate re-registers against the shared coordinator. The OLD
337
+ * instance is not GC'd on its own — its callback closures capture `this` and
338
+ * stay pinned on the module-wide coordinator until {@link dispose} runs the
339
+ * captured disposer (called at the genuine eviction sites, see
340
+ * `StoreModule.tearDownTableStorage` / `renameTable`).
341
+ */
342
+ attachCoordinator(): TransactionCoordinator;
343
+ /**
344
+ * Ensure the coordinator is available and connection is registered.
345
+ */
346
+ protected ensureCoordinator(): Promise<TransactionCoordinator>;
347
+ /**
348
+ * Deliver one data-change event: buffered on the coordinator inside a transaction
349
+ * (fires on commit, discarded on rollback), emitted straight through otherwise.
350
+ * Every write path routes its event here so the two arms can never drift apart.
351
+ *
352
+ * Ordering within a transaction is the coordinator's queue order, which is the order
353
+ * these calls are made — the event contract's delete-before-insert promise for a
354
+ * relocating key change rides on that (docs/usage.md § Subscribing to Data Changes).
355
+ */
356
+ protected emitOrQueueDataChange(inTransaction: boolean, event: DataChangeEvent): void;
357
+ /** Apply pending stats on commit. */
358
+ protected applyPendingStats(): void;
359
+ /** Discard pending stats on rollback. */
360
+ protected discardPendingStats(): void;
361
+ /** Flush statistics to the stats store. */
362
+ protected flushStats(): Promise<void>;
363
+ /** Create a new connection for transaction support. */
364
+ createConnection(): Promise<VirtualTableConnection>;
365
+ /** Get the current connection. */
366
+ getConnection(): VirtualTableConnection | undefined;
367
+ /** Extract primary key values from a full row (positioned by column index). */
368
+ protected extractPK(row: Row): SqlValue[];
369
+ /**
370
+ * Resolve the PK cells an UPDATE/DELETE's `oldKeyValues` addresses.
371
+ *
372
+ * `UpdateArgs.oldKeyValues` is COMPACT — one cell per `primaryKeyDefinition`
373
+ * entry, in that order — NOT a full row positioned by column index. Every
374
+ * producer builds it that way (`pkIndices.map(i => row[i])` in the DML
375
+ * executor and in the isolation flush/overlay), and the memory module's
376
+ * `buildPrimaryKeyFromValues` asserts exactly this arity.
377
+ *
378
+ * Running it through {@link extractPK} instead only coincides when every PK
379
+ * column sits at the index matching its position in the PK definition. For a
380
+ * table whose PK is not its leading columns (e.g. a generated stored PK
381
+ * declared after the columns it derives from) that read lands past the end of
382
+ * the compact array and yields `undefined`.
383
+ */
384
+ protected pkFromKeyValues(keyValues: Row): SqlValue[];
385
+ /**
386
+ * Coerce each cell in `row` to its declared column logical type.
387
+ * Mirrors the memory-table path (MemoryTableManager.performInsert/performUpdate)
388
+ * so INTEGER/REAL affinity is applied and JSON columns are parsed into native
389
+ * objects before PK extraction, serialization, and index-key construction.
390
+ */
391
+ protected coerceRow(row: Row): Row;
392
+ /**
393
+ * Iterate the effective entry state of this table's data store within
394
+ * `bounds`: the committed `store.iterate` stream merged with the
395
+ * coordinator's pending ops for the data store (read-your-own-writes).
396
+ *
397
+ * Both inputs are sorted by encoded key bytes, so this is an
398
+ * order-preserving two-way merge: a pending put wins over a committed entry
399
+ * at the same key, a pending delete suppresses its committed entry, and
400
+ * pending puts outside `bounds` are excluded. With no active transaction
401
+ * (or an empty pending bucket) it degrades to the bare committed iterate.
402
+ *
403
+ * The pending side is the module coordinator's bucket for THIS table's data
404
+ * store handle (`store`) — every data op is queued under that exact handle, so
405
+ * a sibling table's pending ops (a different data-store handle) never bleed in.
406
+ */
407
+ protected iterateEffective(store: KVStore, bounds: IterateOptions, reverse?: boolean): AsyncIterable<KVEntry>;
408
+ /**
409
+ * Read the live row at `pk` — this transaction's pending overlay (a pending
410
+ * delete ⇒ gone; a pending put ⇒ its value) shadowing the committed store.
411
+ * Backs `query()`'s point-lookup arm and validates covering-MV conflict
412
+ * candidates against the source of truth.
413
+ */
414
+ protected readLiveRowByPk(pk: SqlValue[]): Promise<Row | null>;
415
+ /** Encode `pkValues` (in PK-definition order) exactly as the data store keys rows. */
416
+ encodeDataKey(pkValues: SqlValue[]): Uint8Array;
417
+ /**
418
+ * Byte bounds covering every data key whose leading PK columns equal
419
+ * `prefixValues` — encoded under the same per-column DESC directions and key
420
+ * collations as {@link encodeDataKey}, so seek + early-terminate addresses the
421
+ * exact slice. An empty prefix yields full-scan bounds.
422
+ */
423
+ encodePkPrefixBounds(prefixValues: SqlValue[]): {
424
+ gte: Uint8Array;
425
+ lt?: Uint8Array;
426
+ };
427
+ /**
428
+ * Effective (pending-over-committed) point read by encoded data key: a pending
429
+ * delete ⇒ null, a pending put ⇒ its value, else the committed store entry.
430
+ */
431
+ readEffectiveRowByKey(key: Uint8Array): Promise<Row | null>;
432
+ /**
433
+ * Effective ordered entry scan within `bounds` (see {@link iterateEffective}).
434
+ * Opens the data store first — which fires the lazy first-access `saveTableDDL`
435
+ * for a freshly created table, the catalog write a store-backed MV backing
436
+ * relies on to survive reopen.
437
+ */
438
+ iterateEffectiveEntries(bounds: IterateOptions, reverse?: boolean): AsyncIterable<KVEntry>;
439
+ /** Buffer a privileged row-count delta, applied at coordinator commit (host writes). */
440
+ trackPrivilegedMutation(delta: number): void;
441
+ /**
442
+ * Reset statistics to an absolute committed row count and flush immediately.
443
+ * Used by the host's `replaceContents` (create-fill / refresh), where the new
444
+ * count is exact, replacing any drifted delta-tracked estimate.
445
+ */
446
+ resetStats(rowCount: number): Promise<void>;
447
+ /**
448
+ * Open (and cache) the data store, firing the lazy first-access `saveTableDDL`.
449
+ * Public for the host's `replaceContents`, which writes the store directly.
450
+ */
451
+ openDataStore(): Promise<KVStore>;
452
+ /**
453
+ * Effective (pending-over-committed) point read by PK values — the public
454
+ * read an external writer issues before an upsert to learn the row's current
455
+ * image. Thin wrapper over the same private point-lookup that backs
456
+ * `StoreTableScan.query`'s point arm, so an external read merges pending-over-committed
457
+ * exactly like an engine read does.
458
+ */
459
+ readRowByPk(pk: SqlValue[]): Promise<Row | null>;
460
+ /**
461
+ * Begin a table-scoped transaction by ensuring the coordinator is active.
462
+ *
463
+ * Used by the isolation layer's flush path, which treats the underlying
464
+ * write as an independent mini-transaction. Idempotent: if the coordinator
465
+ * is already in a transaction (e.g. started by a registered connection),
466
+ * this is a no-op.
467
+ */
468
+ begin(): Promise<void>;
469
+ /**
470
+ * Commits a table-scoped transaction, flushing any buffered writes to the KV store.
471
+ * No-op if the coordinator is not currently in a transaction.
472
+ */
473
+ commit(): Promise<void>;
474
+ /**
475
+ * Rolls back a table-scoped transaction, discarding any buffered writes.
476
+ * No-op if the coordinator is not currently in a transaction.
477
+ */
478
+ rollback(): Promise<void>;
479
+ /** Disconnect from the store. */
480
+ disconnect(): Promise<void>;
481
+ /**
482
+ * Hard teardown: fully detach this instance from the module-wide coordinator.
483
+ *
484
+ * Distinct from the per-scan {@link disconnect} (which only flushes stats and
485
+ * deliberately keeps the table hooked mid-life). Called ONLY at the genuine
486
+ * eviction sites — `StoreModule.tearDownTableStorage` (drop / reclaim) and
487
+ * `renameTable` — where this instance is removed from the module's `tables` map
488
+ * and will never be used again. It best-effort flushes any buffered stats (the
489
+ * backing store is about to be deleted / relocated, so this is the last chance,
490
+ * same posture as the teardown-time `disconnect` it replaces), then runs the
491
+ * coordinator disposer so this instance's {stats apply/discard} callback pair —
492
+ * and the `this` its closures capture — is spliced off the shared coordinator's
493
+ * array rather than pinned for the module's lifetime.
494
+ *
495
+ * Idempotent: the disposer is run at most once and both it and the coordinator
496
+ * reference are nulled, so a double-dispose is a no-op and a re-`attachCoordinator`
497
+ * after dispose registers a fresh pair instead of double-registering.
498
+ */
499
+ dispose(): Promise<void>;
500
+ /** Get the current estimated row count. */
501
+ getEstimatedRowCount(): Promise<number>;
502
+ /**
503
+ * The row count this instance can answer WITHOUT any I/O — `undefined` when no
504
+ * count has been read or maintained yet (a table nothing has touched this session,
505
+ * or one that has never been counted at all).
506
+ *
507
+ * Synchronous by design: `StoreModule.getBestAccessPlan` is a synchronous engine
508
+ * callback, so the only count it can price a plan with is one already in memory.
509
+ * {@link primeStats} is what makes that the common case rather than the rare one —
510
+ * it loads the persisted count when storage is first opened, which every read and
511
+ * write path does before it can reach the planner a second time.
512
+ *
513
+ * Includes the open transaction's buffered delta, so a statement that reads what
514
+ * its own transaction just wrote is costed against the size it will actually see.
515
+ */
516
+ getKnownRowCount(): number | undefined;
517
+ /**
518
+ * The `VirtualTable.getStatistics` contract: this table's SIZE, reported from the
519
+ * running count the write paths already maintain and persist, in O(1) — no scan.
520
+ *
521
+ * Column statistics are deliberately absent. The store keeps no value distribution
522
+ * (a distinct count or histogram would cost a full scan of the table or of an index),
523
+ * and `ANALYZE` reads an empty `columnStats` as "this module reported its size
524
+ * cheaply, collect the rest by scanning" (see `runtime/emit/analyze.ts`) — so
525
+ * implementing this method makes the count reachable without giving up the
526
+ * per-column statistics ANALYZE collects today.
527
+ *
528
+ * `rowCount` is delta-tracked rather than counted, so it can drift from the true
529
+ * count if a write path ever mis-accounts; `ANALYZE`'s scan is the reconciliation.
530
+ *
531
+ * `lastAnalyzed` is deliberately left unset: the only timestamp this table holds is
532
+ * `TableStats.updatedAt`, the moment the count last MOVED, which is a different fact
533
+ * — reporting it here would tell a staleness check the table had been analyzed.
534
+ */
535
+ getStatistics(): Promise<TableStatistics>;
536
+ /** Track a mutation and schedule lazy stats persistence. */
537
+ protected trackMutation(delta: number, inTransaction?: boolean): void;
538
+ }
539
+ //# sourceMappingURL=store-table-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-table-base.d.ts","sourceRoot":"","sources":["../../../src/common/store-table-base.ts"],"names":[],"mappings":"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"}