arrowbase 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.
@@ -0,0 +1,1932 @@
1
+ /**
2
+ * Column type codes.
3
+ *
4
+ * Fixed-width (Phase 1):
5
+ * Bool, Int/UInt 8..64, Float 32/64
6
+ *
7
+ * Variable-width (Phase 3):
8
+ * Utf8 — raw UTF-8 strings, offsets + values heap
9
+ * DictUtf8 — dictionary-encoded UTF-8; per-row stores a u32 dictionary
10
+ * code, with a sidecar string table (JS-side in v1).
11
+ *
12
+ * Values are stable integers — they are written to the column table in SAB
13
+ * and must not change without a schema-fingerprint bump.
14
+ */
15
+ declare const ColumnTypeCode: {
16
+ readonly Bool: 1;
17
+ readonly Int8: 2;
18
+ readonly Int16: 3;
19
+ readonly Int32: 4;
20
+ readonly Int64: 5;
21
+ readonly UInt8: 6;
22
+ readonly UInt16: 7;
23
+ readonly UInt32: 8;
24
+ readonly UInt64: 9;
25
+ readonly Float32: 10;
26
+ readonly Float64: 11;
27
+ readonly Utf8: 12;
28
+ readonly DictUtf8: 13;
29
+ readonly Binary: 14;
30
+ readonly List: 15;
31
+ readonly Struct: 16;
32
+ readonly Point: 17;
33
+ readonly LineString: 18;
34
+ readonly Polygon: 19;
35
+ };
36
+ type ColumnTypeCode = (typeof ColumnTypeCode)[keyof typeof ColumnTypeCode];
37
+ type ColumnTypeName = 'bool' | 'int8' | 'int16' | 'int32' | 'int64' | 'uint8' | 'uint16' | 'uint32' | 'uint64' | 'float32' | 'float64' | 'utf8' | 'dict_utf8' | 'binary' | 'list' | 'struct' | 'point' | 'linestring' | 'polygon';
38
+ /** True for variable-width columns that need a values heap. */
39
+ declare function isVariableWidth(code: ColumnTypeCode): boolean;
40
+ /** True for dictionary-encoded columns that need a JS-side dict table. */
41
+ declare function isDictionary(code: ColumnTypeCode): boolean;
42
+ /**
43
+ * Byte width of a single element for fixed-width columns. For variable-width
44
+ * columns (Utf8), returns the offsets array element width (i32 = 4).
45
+ * Dict columns store a u32 code per row (= 4).
46
+ */
47
+ declare function byteWidthOf(code: ColumnTypeCode): number;
48
+ /** JS value type for each column type. */
49
+ type PointValue = readonly [lng: number, lat: number];
50
+ type LineStringValue = readonly PointValue[];
51
+ type PolygonValue = readonly LineStringValue[];
52
+ type ValueOf<T extends ColumnTypeName> = T extends 'bool' ? boolean : T extends 'int64' | 'uint64' ? bigint : T extends 'utf8' | 'dict_utf8' ? string : T extends 'binary' ? Uint8Array : T extends 'list' ? readonly unknown[] : T extends 'struct' ? Record<string, unknown> : T extends 'point' ? PointValue : T extends 'linestring' ? LineStringValue : T extends 'polygon' ? PolygonValue : number;
53
+
54
+ /** User-facing column definition. */
55
+ interface ColumnDef {
56
+ type: ColumnTypeName;
57
+ /** If false (default), nulls are not allowed and no validity bitmap is kept. */
58
+ nullable?: boolean;
59
+ /**
60
+ * For `utf8`/`binary` columns: total bytes reserved for the values
61
+ * heap. For `list<utf8>`/`list<binary>` columns: bytes reserved for
62
+ * the **child** heap. Defaults to `32 * capacity` otherwise.
63
+ */
64
+ valuesHeapBytes?: number;
65
+ /** Required when `type === 'list'`. The child element type. */
66
+ items?: ColumnDef;
67
+ /** Required when `type === 'struct'`. Map of field name → def. */
68
+ fields?: Record<string, ColumnDef>;
69
+ /** For polygon columns: append first point when a ring is open. */
70
+ autoCloseRings?: boolean;
71
+ }
72
+ /** User-facing schema definition input. */
73
+ interface SchemaInput {
74
+ name: string;
75
+ /**
76
+ * Primary key must be a `uint32` column in Phase 1. Defaults to `__id`
77
+ * if present.
78
+ */
79
+ primaryKey?: string;
80
+ columns: Record<string, ColumnDef>;
81
+ }
82
+ /** Compiled, immutable schema describing a collection's columns. */
83
+ interface CompiledColumn {
84
+ readonly name: string;
85
+ readonly index: number;
86
+ readonly type: ColumnTypeName;
87
+ readonly typeCode: ColumnTypeCode;
88
+ /**
89
+ * For fixed-width columns: byte width of a single element.
90
+ * For Utf8/Binary: byte width of the offsets-array element (i32 = 4).
91
+ * For DictUtf8: byte width of a code (u32 = 4).
92
+ * For List: byte width of the offsets-array element (i32 = 4).
93
+ * For Struct: 0 (no primary buffer — fields carry the storage).
94
+ */
95
+ readonly byteWidth: number;
96
+ readonly nullable: boolean;
97
+ /**
98
+ * For utf8/binary columns: total bytes reserved in the values heap.
99
+ * For list<utf8>/list<binary> columns: bytes reserved for the child heap.
100
+ * Undefined uses the default (32 bytes per row).
101
+ */
102
+ readonly valuesHeapBytes: number | undefined;
103
+ /**
104
+ * For List columns: the compiled child element column. `index === -1`
105
+ * on the child to signal "this is not a top-level column". Its
106
+ * `byteWidth` drives child-array allocation. Child is always a leaf
107
+ * type (primitive, utf8, dict_utf8, binary, or bool) in v1.
108
+ */
109
+ readonly childColumn?: CompiledColumn;
110
+ /**
111
+ * For Struct columns: child field columns in declaration order. Each
112
+ * field column has `index` ≥ 0 but is *not* present in the top-level
113
+ * `columns` array of the parent schema — fields live only on their
114
+ * struct parent. Nested structs and list-fields are rejected in v1.
115
+ */
116
+ readonly fields?: readonly CompiledColumn[];
117
+ readonly fieldsByName?: ReadonlyMap<string, CompiledColumn>;
118
+ /** Polygon-only storage option. */
119
+ readonly autoCloseRings?: boolean;
120
+ }
121
+ interface CompiledSchema {
122
+ readonly name: string;
123
+ readonly primaryKey: string;
124
+ readonly primaryKeyIndex: number;
125
+ readonly columns: readonly CompiledColumn[];
126
+ readonly columnsByName: ReadonlyMap<string, CompiledColumn>;
127
+ readonly fingerprint: bigint;
128
+ }
129
+ /**
130
+ * Compile a user schema into the immutable layout used by allocators and
131
+ * collections. Validates:
132
+ * - non-empty column set
133
+ * - no duplicate names
134
+ * - PK exists and has type uint32 (Phase 1 constraint)
135
+ * - all column types are supported
136
+ */
137
+ declare function defineSchema(input: SchemaInput): CompiledSchema;
138
+
139
+ /**
140
+ * Ref proxies — `@tanstack/db` parity (Layer C.2).
141
+ *
142
+ * A ref proxy is a JS Proxy that records every property access as a
143
+ * path segment, materialized into a `PropRef` by `toExpression`.
144
+ * Every builder callback (`where`, `select`, `orderBy`, etc.) is
145
+ * passed either:
146
+ * - a root proxy (multiple aliases): `({ users, posts }) => eq(users.id, posts.userId)`
147
+ * - a single-row proxy: `(row) => row.name`
148
+ * - a with-selected proxy: `({ posts, $selected }) => $selected.count`
149
+ *
150
+ * Runtime matches `@tanstack/db/query/builder/ref-proxy.js` gesture-
151
+ * for-gesture; type layer is looser (we use `any` in a few places
152
+ * where upstream's inference is too deep for our scope). The
153
+ * conformance test in C.11 catches meaningful regressions.
154
+ */
155
+
156
+ /**
157
+ * Brand carried by every ref-proxy leaf. Matches upstream's
158
+ * `RefProxy<T>` shape; `__path` is the access trail.
159
+ */
160
+ interface RefProxy<T = unknown> {
161
+ /** @internal */
162
+ readonly __refProxy: true;
163
+ /** @internal */
164
+ readonly __path: Array<string>;
165
+ /** @internal — phantom type for TS inference. */
166
+ readonly __type: T;
167
+ }
168
+ /**
169
+ * A leaf in a ref proxy tree — wraps a scalar `T` and carries
170
+ * `__path` + `__refProxy`. Used by the deep-mapped
171
+ * `SingleRowRefProxy` to type column access.
172
+ */
173
+ type RefLeaf<T = unknown> = RefProxy<T> & {
174
+ readonly __refLeaf: true;
175
+ };
176
+ /**
177
+ * Virtual row properties exposed on every single-row proxy for
178
+ * parity with `@tanstack/db`. Runtime compilation of these is
179
+ * Layer H; Layer C accepts them structurally so callers can write
180
+ * code referencing `row.$key` etc. without tripping the IR.
181
+ */
182
+ type VirtualPropsRefProxy<TKey extends string | number = string | number> = {
183
+ readonly $synced: RefLeaf<boolean>;
184
+ readonly $origin: RefLeaf<'sync' | 'optimistic'>;
185
+ readonly $key: RefLeaf<TKey>;
186
+ readonly $collectionId: RefLeaf<string>;
187
+ };
188
+ /**
189
+ * Deep-mapped: each scalar column becomes a `RefLeaf<T>`; each
190
+ * object column recurses. Matches `@tanstack/db`'s
191
+ * `SingleRowRefProxy` shape. Used for single-row callbacks
192
+ * (`fn.select`, `fn.where`, `fn.having`) and inside index
193
+ * expression evaluators.
194
+ */
195
+ type SingleRowRefProxy<T, TKey extends string | number = string | number> = T extends Record<string, unknown> ? {
196
+ readonly [K in keyof T]: T[K] extends Record<string, unknown> ? SingleRowRefProxy<T[K], TKey> & RefProxy<T[K]> : RefLeaf<T[K]>;
197
+ } & RefProxy<T> & VirtualPropsRefProxy<TKey> : RefProxy<T> & VirtualPropsRefProxy<TKey>;
198
+ /** TanStack-style public ref alias. */
199
+ type Ref<T = unknown> = T extends Record<string, unknown> ? SingleRowRefProxy<T> : RefLeaf<T>;
200
+ /**
201
+ * Create a single-row ref proxy. Every property access records a
202
+ * path segment and returns a nested proxy (memoized per-path).
203
+ *
204
+ * Matches `@tanstack/db`'s `createSingleRowRefProxy<T>()` runtime
205
+ * byte-for-byte (modulo style).
206
+ */
207
+ declare function createSingleRowRefProxy<T extends Record<string, unknown> = Record<string, unknown>>(): SingleRowRefProxy<T>;
208
+ /**
209
+ * Root-level ref proxy shape: each declared alias is exposed as a
210
+ * `SingleRowRefProxy<T[alias]>`. The root itself is branded as a
211
+ * `RefProxy`.
212
+ */
213
+ type RootRefProxy<T extends Record<string, Record<string, unknown>>> = RefProxy<T> & {
214
+ readonly [K in keyof T]: SingleRowRefProxy<T[K]>;
215
+ };
216
+ /**
217
+ * Create a root ref proxy scoped to a set of table aliases. The
218
+ * root proxy exposes each alias as a nested single-row proxy;
219
+ * path segments accumulate alias + column + (nested...) and are
220
+ * materialized by `toExpression`.
221
+ *
222
+ * Matches `@tanstack/db`'s `createRefProxy<T>(aliases)` runtime.
223
+ */
224
+ declare function createRefProxy<T extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>>(aliases: Array<string>): RootRefProxy<T>;
225
+ /**
226
+ * Create a root ref proxy augmented with a `$selected` namespace.
227
+ * Used inside `having` callbacks where the preceding `select` has
228
+ * introduced named columns that HAVING can reference by alias.
229
+ *
230
+ * Paths rooted at `$selected` are emitted as
231
+ * `['$selected', ...rest]`; the compiler then resolves them
232
+ * against the resolved SELECT shape.
233
+ */
234
+ declare function createRefProxyWithSelected<T extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>>(aliases: Array<string>): RootRefProxy<T> & {
235
+ $selected: SingleRowRefProxy<Record<string, unknown>>;
236
+ };
237
+ /**
238
+ * Type guard: is `value` a ref proxy?
239
+ */
240
+ declare function isRefProxy(value: unknown): value is RefProxy;
241
+ /**
242
+ * Convert a value to a `BasicExpression`:
243
+ *
244
+ * - A ref proxy becomes a `PropRef` of its recorded path.
245
+ * - An existing IR expression (ref/val/func/agg) is returned as-is.
246
+ * - `ToArrayWrapper` / `ConcatToArrayWrapper` (Layer F) throws —
247
+ * matches upstream's guard; we don't have those wrappers yet so
248
+ * the guard is a no-op-in-practice today.
249
+ * - Any other value is wrapped as a `Value` literal.
250
+ */
251
+ declare function toExpression<T = unknown>(value: T): BasicExpression;
252
+ /**
253
+ * Wrap a literal as a `Value` expression. Matches
254
+ * `@tanstack/db`'s `val(v)`. Useful for distinguishing a literal
255
+ * from a ref-proxy in contexts where both appear — e.g.
256
+ * `eq(users.id, val(1))` vs `eq(users.id, 1)` (the second is
257
+ * identical in practice because `toExpression` wraps literals,
258
+ * but `val()` makes intent explicit in generated code).
259
+ */
260
+ declare function val<T>(value: T): BasicExpression<T>;
261
+
262
+ /**
263
+ * TanStack DB-compatible type surface.
264
+ *
265
+ * We mirror `@tanstack/db`'s public type vocabulary here so that every
266
+ * layer of ArrowBase can import from a single internal module instead
267
+ * of redeclaring types. Types live here; runtime lives in
268
+ * `src/collection/*` and elsewhere. Nothing in this file imports
269
+ * `@tanstack/db` at runtime.
270
+ *
271
+ * Kept intentionally minimal for Layer B. Layer C (query) and Layer E
272
+ * (transactions) will expand this file.
273
+ */
274
+ /** Operation type in a ChangeMessage. Matches @tanstack/db. */
275
+ type OperationType = 'insert' | 'update' | 'delete';
276
+ /**
277
+ * Arbitrary function type. Matches @tanstack/db's `Fn`.
278
+ */
279
+ type Fn = (...args: Array<unknown>) => unknown;
280
+ /**
281
+ * Record of utility functions attached to a collection via
282
+ * `CollectionConfig.utils`. Matches @tanstack/db's `UtilsRecord`.
283
+ * Intentionally `any` on the value side so each util can carry its
284
+ * own narrow signature at the call site.
285
+ */
286
+ type UtilsRecord = Record<string, any>;
287
+ /**
288
+ * String collation config for sort operations. Matches
289
+ * `@tanstack/db`'s `StringCollationConfig` discriminated union.
290
+ */
291
+ type StringCollationConfig = {
292
+ stringSort?: 'lexical';
293
+ } | {
294
+ stringSort?: 'locale';
295
+ locale?: string;
296
+ localeOptions?: object;
297
+ };
298
+ interface SpatialIndexOptions$1 {
299
+ readonly column: string;
300
+ readonly type: 'rtree';
301
+ readonly eager?: boolean;
302
+ }
303
+ type SpatialIndexConfig$1 = SpatialIndexOptions$1 | readonly SpatialIndexOptions$1[];
304
+ /**
305
+ * A single change emitted by `subscribeChanges`. Matches @tanstack/db's
306
+ * `ChangeMessage<T, TKey>` field-for-field.
307
+ *
308
+ * - `key` — primary key of the row affected.
309
+ * - `value` — current row value after the mutation (for delete, the
310
+ * final state, i.e. tombstone for soft-deletes or the pre-removal
311
+ * snapshot for hard-deletes).
312
+ * - `previousValue` — row state immediately before an update. Absent
313
+ * for inserts and deletes (TanStack DB also omits it for inserts;
314
+ * for deletes `value` IS the pre-delete row, matching their shape).
315
+ * - `type` — 'insert' | 'update' | 'delete'.
316
+ * - `metadata` — optional free-form bag; used by sync adapters to
317
+ * attach origin info.
318
+ */
319
+ interface ChangeMessage<T extends object = Record<string, unknown>, TKey extends string | number = string | number> {
320
+ key: TKey;
321
+ value: T;
322
+ previousValue?: T;
323
+ type: OperationType;
324
+ metadata?: Record<string, unknown>;
325
+ }
326
+ type DeleteKeyMessage<TKey extends string | number = string | number> = Omit<ChangeMessage<any, TKey>, 'value' | 'previousValue' | 'type'> & {
327
+ type: 'delete';
328
+ };
329
+ type ChangeMessageOrDeleteKeyMessage<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = Omit<ChangeMessage<T, TKey>, 'key'> | DeleteKeyMessage<TKey>;
330
+ type OptimisticChangeMessage<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = (ChangeMessage<T, TKey> & {
331
+ isActive?: boolean;
332
+ }) | (DeleteKeyMessage<TKey> & {
333
+ isActive?: boolean;
334
+ });
335
+ /**
336
+ * Options for `subscribeChanges`. Matches @tanstack/db's
337
+ * `SubscribeChangesOptions` for the public surface.
338
+ *
339
+ * `includeInitialState`: when `true`, the callback is invoked once
340
+ * synchronously with a snapshot of the current rows as `insert`
341
+ * messages before any subsequent mutation-driven calls.
342
+ */
343
+ interface SubscribeChangesOptions {
344
+ includeInitialState?: boolean;
345
+ /** Callback form lowered to `whereExpression` for filtering/subset/index planning. */
346
+ where?: (row: SingleRowRefProxy<Record<string, unknown>>) => unknown;
347
+ /** Precompiled where expression used by query/live internals. */
348
+ whereExpression?: BasicExpression<boolean>;
349
+ }
350
+ /**
351
+ * Options for `currentStateAsChanges`.
352
+ *
353
+ * Reduced from @tanstack/db in Layer B — `where` / `orderBy` / `limit`
354
+ * / `optimizedOnly` are query-builder concepts and land in Layer C.
355
+ * The B signature still accepts the full shape structurally so Layer
356
+ * C can add behavior without changing the method signature.
357
+ */
358
+ interface CurrentStateAsChangesOptions {
359
+ where?: BasicExpression<boolean>;
360
+ whereExpression?: BasicExpression<boolean>;
361
+ orderBy?: OrderBy;
362
+ limit?: number;
363
+ optimizedOnly?: boolean;
364
+ }
365
+ /**
366
+ * Handle returned from `subscribeChanges`. Calling `unsubscribe()`
367
+ * detaches the listener. Additional event-emitter methods (`status`,
368
+ * event handlers) are added in a later layer.
369
+ */
370
+ interface CollectionSubscription {
371
+ readonly status: 'ready' | 'loadingSubset';
372
+ unsubscribe(): void;
373
+ }
374
+ /**
375
+ * Metadata passed alongside a single mutation. Matches
376
+ * `@tanstack/db`'s `OperationConfig`.
377
+ */
378
+ interface OperationConfig {
379
+ metadata?: Record<string, unknown>;
380
+ /** Apply optimistic updates immediately. Defaults to true. */
381
+ optimistic?: boolean;
382
+ }
383
+ /** Insert-specific config. Superset of `OperationConfig`. */
384
+ interface InsertConfig extends OperationConfig {
385
+ }
386
+ interface Deferred<T> {
387
+ readonly promise: Promise<T>;
388
+ resolve(value: T | PromiseLike<T>): void;
389
+ reject(reason?: unknown): void;
390
+ readonly settled: boolean;
391
+ }
392
+ /**
393
+ * Transaction-state tag. Matches @tanstack/db.
394
+ */
395
+ type TransactionState = 'pending' | 'persisting' | 'completed' | 'failed';
396
+ interface TransactionCollectionLike {
397
+ readonly id: string;
398
+ readonly _state?: {
399
+ onTransactionStateChange?: () => void;
400
+ pendingSyncedTransactions?: ReadonlyArray<unknown>;
401
+ commitPendingTransactions?: () => void;
402
+ };
403
+ }
404
+ type ResolveTransactionChanges<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType> = TOperation extends 'delete' ? T : Partial<T>;
405
+ /**
406
+ * One entry in a pending transaction. Matches @tanstack/db's public
407
+ * mutation record shape closely enough for Layer E transaction APIs.
408
+ */
409
+ interface PendingMutation<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType, TCollection extends TransactionCollectionLike = TransactionCollectionLike> {
410
+ mutationId: string;
411
+ original: TOperation extends 'insert' ? {} : T;
412
+ modified: T;
413
+ changes: ResolveTransactionChanges<T, TOperation>;
414
+ globalKey: string;
415
+ key: unknown;
416
+ type: TOperation;
417
+ metadata: unknown;
418
+ syncMetadata: Record<string, unknown>;
419
+ optimistic: boolean;
420
+ createdAt: Date;
421
+ updatedAt: Date;
422
+ collection: TCollection;
423
+ }
424
+ type NonEmptyArray<T> = [T, ...Array<T>];
425
+ interface Transaction$1<T extends object = Record<string, unknown>> {
426
+ readonly id: string;
427
+ state: TransactionState;
428
+ readonly mutationFn: MutationFn<T>;
429
+ readonly mutations: Array<PendingMutation<T>>;
430
+ readonly isPersisted: Deferred<Transaction$1<T>>;
431
+ readonly autoCommit: boolean;
432
+ readonly createdAt: Date;
433
+ readonly sequenceNumber: number;
434
+ readonly metadata: Record<string, unknown>;
435
+ readonly error?: {
436
+ message: string;
437
+ error: Error;
438
+ };
439
+ setState(newState: TransactionState): void;
440
+ mutate(callback: () => void | PromiseLike<void>): Transaction$1<T>;
441
+ applyMutations(mutations: Array<PendingMutation<any>>): void;
442
+ rollback(config?: {
443
+ isSecondaryRollback?: boolean;
444
+ }): Transaction$1<T>;
445
+ touchCollection(): void;
446
+ commit(): Promise<Transaction$1<T>>;
447
+ compareCreatedAt(other: Transaction$1<any>): number;
448
+ }
449
+ type TransactionWithMutations<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType> = Omit<Transaction$1<T>, 'mutations'> & {
450
+ mutations: NonEmptyArray<PendingMutation<T, TOperation>>;
451
+ };
452
+ type MutationFnParams<T extends object = Record<string, unknown>> = {
453
+ transaction: TransactionWithMutations<T>;
454
+ };
455
+ type MutationFn<T extends object = Record<string, unknown>> = (params: MutationFnParams<T>) => Promise<unknown>;
456
+ interface TransactionConfig<T extends object = Record<string, unknown>> {
457
+ id?: string;
458
+ autoCommit?: boolean;
459
+ mutationFn: MutationFn<T>;
460
+ metadata?: Record<string, unknown>;
461
+ }
462
+ /** Options for createOptimisticAction. Mirrors @tanstack/db's helper. */
463
+ interface CreateOptimisticActionsOptions<TVars = unknown, T extends object = Record<string, unknown>> extends Omit<TransactionConfig<T>, 'mutationFn'> {
464
+ /** Function to apply optimistic updates locally before the mutation completes. */
465
+ onMutate: (vars: TVars) => void;
466
+ /** Function to execute the mutation on the server. */
467
+ mutationFn: (vars: TVars, params: MutationFnParams<T>) => Promise<unknown>;
468
+ }
469
+ interface BaseStrategy<TName extends string = string> {
470
+ _type: TName;
471
+ execute: <T extends object = Record<string, unknown>>(fn: () => Transaction$1<T>) => void | Promise<void>;
472
+ cleanup: () => void;
473
+ }
474
+ interface DebounceStrategyOptions {
475
+ wait: number;
476
+ leading?: boolean;
477
+ trailing?: boolean;
478
+ }
479
+ interface DebounceStrategy extends BaseStrategy<'debounce'> {
480
+ options: DebounceStrategyOptions;
481
+ }
482
+ interface QueueStrategyOptions {
483
+ wait?: number;
484
+ maxSize?: number;
485
+ addItemsTo?: 'front' | 'back';
486
+ getItemsFrom?: 'front' | 'back';
487
+ }
488
+ interface QueueStrategy extends BaseStrategy<'queue'> {
489
+ options?: QueueStrategyOptions;
490
+ }
491
+ interface ThrottleStrategyOptions {
492
+ wait: number;
493
+ leading?: boolean;
494
+ trailing?: boolean;
495
+ }
496
+ interface ThrottleStrategy extends BaseStrategy<'throttle'> {
497
+ options: ThrottleStrategyOptions;
498
+ }
499
+ interface BatchStrategyOptions {
500
+ maxSize?: number;
501
+ wait?: number;
502
+ getShouldExecute?: (items: Array<unknown>) => boolean;
503
+ }
504
+ interface BatchStrategy extends BaseStrategy<'batch'> {
505
+ options?: BatchStrategyOptions;
506
+ }
507
+ type Strategy = DebounceStrategy | QueueStrategy | ThrottleStrategy | BatchStrategy;
508
+ type StrategyOptions<T extends Strategy> = T extends DebounceStrategy ? DebounceStrategyOptions : T extends QueueStrategy ? QueueStrategyOptions : T extends ThrottleStrategy ? ThrottleStrategyOptions : T extends BatchStrategy ? BatchStrategyOptions : never;
509
+ interface PacedMutationsConfig<TVariables = unknown, T extends object = Record<string, unknown>> {
510
+ onMutate: (variables: TVariables) => void;
511
+ mutationFn: MutationFn<T>;
512
+ strategy: Strategy;
513
+ metadata?: Record<string, unknown>;
514
+ }
515
+ interface LoadSubsetOptions {
516
+ /** The where expression to filter the data. */
517
+ where?: unknown;
518
+ /** The order-by clause to sort the data. */
519
+ orderBy?: unknown;
520
+ /** Maximum rows to load. */
521
+ limit?: number;
522
+ /** Cursor expressions for cursor-based pagination. */
523
+ cursor?: unknown;
524
+ /** Row offset for offset-based pagination. */
525
+ offset?: number;
526
+ /** Subscription that triggered the load, when available. */
527
+ subscription?: unknown;
528
+ }
529
+ type LoadSubsetFn = (options: LoadSubsetOptions) => true | Promise<void>;
530
+ type UnloadSubsetFn = (options: LoadSubsetOptions) => void;
531
+ interface SyncParams<T extends object = Record<string, unknown>, TKey extends string | number = string | number> {
532
+ /** The collection the sync is attached to. Typed loosely to avoid a circular import. */
533
+ collection: unknown;
534
+ begin: (options?: {
535
+ immediate?: boolean;
536
+ }) => void;
537
+ write: (message: ChangeMessageOrDeleteKeyMessage<T, TKey>) => void;
538
+ commit: () => void;
539
+ markReady: () => void;
540
+ truncate: () => void;
541
+ }
542
+ /**
543
+ * Sync adapter protocol. Matches the subset of `@tanstack/db`'s
544
+ * `SyncConfig` that Layer B consumers can plug into. The actual
545
+ * `sync` function will be invoked by Layer E's transaction flow;
546
+ * for now we only accept + store the reference.
547
+ */
548
+ interface SyncConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number> {
549
+ sync: (params: SyncParams<T, TKey>) => void | (() => void);
550
+ }
551
+ /**
552
+ * Parameters passed to collection mutation-handler callbacks.
553
+ * `onInsert`/`onUpdate`/`onDelete` receive this.
554
+ */
555
+ interface CollectionMutationFnParams<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TOperation extends OperationType = OperationType> {
556
+ transaction: TransactionWithMutations<T, TOperation>;
557
+ collection: unknown;
558
+ }
559
+ type InsertMutationFnParams<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = CollectionMutationFnParams<T, TKey, 'insert'>;
560
+ type UpdateMutationFnParams<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = CollectionMutationFnParams<T, TKey, 'update'>;
561
+ type DeleteMutationFnParams<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = CollectionMutationFnParams<T, TKey, 'delete'>;
562
+ type InsertMutationFn<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TReturn = unknown> = (params: InsertMutationFnParams<T, TKey>) => Promise<TReturn>;
563
+ type UpdateMutationFn<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TReturn = unknown> = (params: UpdateMutationFnParams<T, TKey>) => Promise<TReturn>;
564
+ type DeleteMutationFn<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TReturn = unknown> = (params: DeleteMutationFnParams<T, TKey>) => Promise<TReturn>;
565
+ interface LocalOnlyCollectionUtils extends UtilsRecord {
566
+ acceptMutations: (transaction: {
567
+ mutations: Array<PendingMutation<Record<string, unknown>>>;
568
+ }) => void;
569
+ }
570
+ interface LocalOnlyCollectionConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number> extends Omit<CreateCollectionConfig<T, TKey>, 'gcTime' | 'startSync' | 'sync' | 'utils'> {
571
+ initialData?: Array<T>;
572
+ }
573
+ type LocalOnlyCollectionOptionsResult<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = CreateCollectionConfig<T, TKey> & {
574
+ gcTime: 0;
575
+ startSync: true;
576
+ initialData?: Array<T>;
577
+ utils: LocalOnlyCollectionUtils;
578
+ };
579
+ type StorageApi = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
580
+ type StorageEventApi = {
581
+ addEventListener: (type: 'storage', listener: (event: StorageEvent) => void) => void;
582
+ removeEventListener: (type: 'storage', listener: (event: StorageEvent) => void) => void;
583
+ };
584
+ interface Parser {
585
+ parse: (data: string) => unknown;
586
+ stringify: (data: unknown) => string;
587
+ }
588
+ type ClearStorageFn = () => void;
589
+ type GetStorageSizeFn = () => number;
590
+ interface LocalStorageCollectionUtils extends UtilsRecord {
591
+ clearStorage: ClearStorageFn;
592
+ getStorageSize: GetStorageSizeFn;
593
+ acceptMutations: (transaction: {
594
+ mutations: Array<PendingMutation<Record<string, unknown>>>;
595
+ }) => void;
596
+ }
597
+ interface LocalStorageCollectionConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number> extends Omit<CreateCollectionConfig<T, TKey>, 'sync' | 'utils'> {
598
+ storageKey: string;
599
+ storage?: StorageApi;
600
+ storageEventApi?: StorageEventApi;
601
+ parser?: Parser;
602
+ }
603
+ type LocalStorageCollectionOptionsResult<T extends object = Record<string, unknown>, TKey extends string | number = string | number> = CreateCollectionConfig<T, TKey> & {
604
+ id: string;
605
+ sync: SyncConfig<T, TKey>;
606
+ utils: LocalStorageCollectionUtils;
607
+ };
608
+ /**
609
+ * `createCollection` config shape. A hybrid of @tanstack/db's
610
+ * `CollectionConfig` and ArrowBase's native `CollectionOptions`
611
+ * (we need `schema` + `capacity` because our store is columnar).
612
+ *
613
+ * Non-essential TanStack fields (`gcTime`/`startSync`/`syncMode`/
614
+ * `compare`/`singleResult`) are accepted structurally but currently
615
+ * unused by Layer B. Layer E wires `sync`/`onInsert`/`onUpdate`/
616
+ * `onDelete`; Layer D wires `autoIndex`/`defaultIndexType`.
617
+ */
618
+ interface CreateCollectionConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number> {
619
+ /**
620
+ * ArrowBase compiled schema (required). TanStack DB's
621
+ * `StandardSchemaV1`-based schema support will land in Layer C;
622
+ * Layer B requires the compiled columnar layout.
623
+ *
624
+ * Typed as `unknown` here to avoid circular imports — the factory
625
+ * narrows it to `CompiledSchema` at runtime.
626
+ */
627
+ schema: unknown;
628
+ /** Row capacity. Required — ArrowBase is fixed-capacity. */
629
+ capacity: number;
630
+ id?: string;
631
+ /**
632
+ * Function to extract the primary key. If omitted, reads the
633
+ * schema's declared PK column. Passing a function overrides.
634
+ */
635
+ getKey?: (item: T) => TKey;
636
+ gcTime?: number;
637
+ startSync?: boolean;
638
+ syncMode?: 'eager' | 'on-demand';
639
+ autoIndex?: 'off' | 'eager';
640
+ defaultIndexType?: IndexConstructor<TKey>;
641
+ sync?: SyncConfig<T, TKey>;
642
+ utils?: UtilsRecord;
643
+ compareOptions?: StringCollationConfig;
644
+ onInsert?: InsertMutationFn<T, TKey>;
645
+ onUpdate?: UpdateMutationFn<T, TKey>;
646
+ onDelete?: DeleteMutationFn<T, TKey>;
647
+ undoCapacity?: number;
648
+ softDelete?: boolean;
649
+ spatialIndex?: SpatialIndexConfig$1;
650
+ }
651
+
652
+ /**
653
+ * Query IR — `@tanstack/db` parity.
654
+ *
655
+ * This module mirrors `@tanstack/db/dist/esm/query/ir.d.ts` field-for-
656
+ * field. Expression classes carry `type` brands matching upstream
657
+ * ('collectionRef', 'queryRef', 'ref', 'val', 'func', 'agg',
658
+ * 'includesSubquery') so that code that walks the IR by `type` tag
659
+ * works identically on either runtime.
660
+ *
661
+ * We deliberately do NOT import from `@tanstack/db` here — Layer C
662
+ * has zero runtime dep on upstream (types only). Field names are
663
+ * kept identical for structural interop; semantic behavior for
664
+ * Layer-C-unsupported features (IncludesSubquery, residual WHERE) is
665
+ * defined but not yet compiled.
666
+ */
667
+
668
+ /** A row keyed by source alias. Mirrors `@tanstack/db`'s `NamespacedRow`. */
669
+ type NamespacedRow = Record<string, Record<string, unknown>>;
670
+ /**
671
+ * Root IR shape for a query. Every builder emits a `QueryIR` via
672
+ * `_getQuery()`; every compiler consumes one. Matches
673
+ * `@tanstack/db`'s `QueryIR` field-for-field.
674
+ */
675
+ interface QueryIR {
676
+ from: From;
677
+ select?: Select;
678
+ join?: Join;
679
+ where?: Array<Where>;
680
+ groupBy?: GroupBy;
681
+ having?: Array<Having>;
682
+ orderBy?: OrderBy;
683
+ limit?: Limit;
684
+ offset?: Offset;
685
+ distinct?: true;
686
+ singleResult?: true;
687
+ /**
688
+ * Functional SELECT — JS closure invoked per row. Bypasses the
689
+ * vectorized compile path; used by `builder.fn.select(cb)`.
690
+ */
691
+ fnSelect?: (row: NamespacedRow) => unknown;
692
+ /**
693
+ * Functional WHERE — JS closure invoked per row. ANDed with any
694
+ * structural `where` entries. Populated by `builder.fn.where(cb)`.
695
+ */
696
+ fnWhere?: Array<(row: NamespacedRow) => unknown>;
697
+ /**
698
+ * Functional HAVING — evaluated against grouped rows. Populated by
699
+ * `builder.fn.having(cb)`.
700
+ */
701
+ fnHaving?: Array<(row: NamespacedRow) => unknown>;
702
+ }
703
+ /**
704
+ * Materialization strategy for `IncludesSubquery`. Layer F owns
705
+ * the runtime; Layer C accepts the tag structurally.
706
+ */
707
+ type IncludesMaterialization = 'collection' | 'array' | 'concat' | 'single';
708
+ /**
709
+ * Synthetic field name used by `IncludesSubquery` scalar paths.
710
+ * Matches upstream literal ('__includes_scalar__').
711
+ */
712
+ declare const INCLUDES_SCALAR_FIELD = "__includes_scalar__";
713
+ type From = CollectionRef | QueryRef;
714
+ type Select = {
715
+ [alias: string]: BasicExpression | Aggregate | Select | IncludesSubquery;
716
+ };
717
+ type Join = Array<JoinClause>;
718
+ interface JoinClause {
719
+ from: CollectionRef | QueryRef;
720
+ type: 'left' | 'right' | 'inner' | 'outer' | 'full' | 'cross';
721
+ left: BasicExpression;
722
+ right: BasicExpression;
723
+ }
724
+ /**
725
+ * A WHERE clause entry. Either a bare expression or a
726
+ * `{ expression, residual? }` object. The `residual` flag marks
727
+ * a predicate that the optimizer couldn't push into an index scan
728
+ * — present for interop; Layer C treats residual and non-residual
729
+ * identically (Layer D's index optimizer will start emitting them).
730
+ */
731
+ type Where = BasicExpression<boolean> | {
732
+ expression: BasicExpression<boolean>;
733
+ residual?: boolean;
734
+ };
735
+ type GroupBy = Array<BasicExpression>;
736
+ type Having = Where;
737
+ type OrderBy = Array<OrderByClause>;
738
+ interface OrderByClause {
739
+ expression: BasicExpression;
740
+ compareOptions: CompareOptions;
741
+ }
742
+ type OrderByDirection = 'asc' | 'desc';
743
+ /**
744
+ * Full compare options for an orderBy expression. Extends the
745
+ * shared string-collation config with direction + null-sort mode.
746
+ * Matches `@tanstack/db`'s `CompareOptions`.
747
+ */
748
+ type CompareOptions = StringCollationConfig & {
749
+ direction: OrderByDirection;
750
+ nulls: 'first' | 'last';
751
+ };
752
+ type Limit = number;
753
+ type Offset = number;
754
+ /**
755
+ * Common base for every IR expression node. Carries a `type` brand
756
+ * checked by `isExpressionLike` and the compiler's walk.
757
+ */
758
+ declare abstract class BaseExpression<T = unknown> {
759
+ abstract type: string;
760
+ /** @internal — phantom type carrier for TS inference. */
761
+ readonly __returnType: T;
762
+ }
763
+ /** Reference to a base Collection at a given alias. */
764
+ declare class CollectionRef extends BaseExpression {
765
+ collection: Collection;
766
+ alias: string;
767
+ readonly type: "collectionRef";
768
+ constructor(collection: Collection, alias: string);
769
+ }
770
+ /** Reference to a subquery (nested `QueryIR`) at a given alias. */
771
+ declare class QueryRef extends BaseExpression {
772
+ query: QueryIR;
773
+ alias: string;
774
+ readonly type: "queryRef";
775
+ constructor(query: QueryIR, alias: string);
776
+ }
777
+ /** Column / property reference. `path = ['alias', 'col', 'nested']`. */
778
+ declare class PropRef<T = unknown> extends BaseExpression<T> {
779
+ path: Array<string>;
780
+ readonly type: "ref";
781
+ constructor(path: Array<string>);
782
+ }
783
+ /** Literal value wrapped as an expression. */
784
+ declare class Value<T = unknown> extends BaseExpression<T> {
785
+ value: T;
786
+ readonly type: "val";
787
+ constructor(value: T);
788
+ }
789
+ /**
790
+ * Scalar function call. `name` is one of the upstream operator
791
+ * literals ('eq' / 'gt' / 'upper' / etc.); `args` are expressions.
792
+ */
793
+ declare class Func<T = unknown> extends BaseExpression<T> {
794
+ name: string;
795
+ args: Array<BasicExpression>;
796
+ readonly type: "func";
797
+ constructor(name: string, args: Array<BasicExpression>);
798
+ }
799
+ type BasicExpression<T = unknown> = PropRef<T> | Value<T> | Func<T>;
800
+ /**
801
+ * Aggregate function call. Separated from `Func` because aggregates
802
+ * can appear in `select` / `having` but not in `where`. Name is
803
+ * 'count' / 'sum' / 'avg' / 'min' / 'max'.
804
+ */
805
+ declare class Aggregate<T = unknown> extends BaseExpression<T> {
806
+ name: string;
807
+ args: Array<BasicExpression>;
808
+ readonly type: "agg";
809
+ constructor(name: string, args: Array<BasicExpression>);
810
+ }
811
+ /**
812
+ * Correlated subquery projected into a parent select clause.
813
+ * Full runtime lands in Layer F (IVM); the class shape is shipped
814
+ * now so IR walkers can skip it cleanly.
815
+ */
816
+ declare class IncludesSubquery extends BaseExpression {
817
+ /** Child query, with the correlation predicate stripped. */
818
+ query: QueryIR;
819
+ /** Parent-side correlation ref (e.g. `project.id`). */
820
+ correlationField: PropRef;
821
+ /** Child-side correlation ref (e.g. `issue.projectId`). */
822
+ childCorrelationField: PropRef;
823
+ /** Result field name on the parent row (e.g. `"issues"`). */
824
+ fieldName: string;
825
+ /** Parent-scope WHERE clauses to apply post-join. */
826
+ parentFilters?: Array<Where> | undefined;
827
+ /** Parent-scope refs consumed by `parentFilters`. */
828
+ parentProjection?: Array<PropRef> | undefined;
829
+ /** Shape of the projected result. Default 'collection'. */
830
+ materialization: IncludesMaterialization;
831
+ /** Field name when materialization is 'concat' scalar. */
832
+ scalarField?: string | undefined;
833
+ readonly type: "includesSubquery";
834
+ constructor(
835
+ /** Child query, with the correlation predicate stripped. */
836
+ query: QueryIR,
837
+ /** Parent-side correlation ref (e.g. `project.id`). */
838
+ correlationField: PropRef,
839
+ /** Child-side correlation ref (e.g. `issue.projectId`). */
840
+ childCorrelationField: PropRef,
841
+ /** Result field name on the parent row (e.g. `"issues"`). */
842
+ fieldName: string,
843
+ /** Parent-scope WHERE clauses to apply post-join. */
844
+ parentFilters?: Array<Where> | undefined,
845
+ /** Parent-scope refs consumed by `parentFilters`. */
846
+ parentProjection?: Array<PropRef> | undefined,
847
+ /** Shape of the projected result. Default 'collection'. */
848
+ materialization?: IncludesMaterialization,
849
+ /** Field name when materialization is 'concat' scalar. */
850
+ scalarField?: string | undefined);
851
+ }
852
+ /**
853
+ * Detects whether `value` is an IR expression object. Used by ref-
854
+ * proxy conversion and compiler walks. Matches upstream semantics.
855
+ */
856
+ declare function isExpressionLike(value: unknown): boolean;
857
+ /** Extract the boolean expression from a `Where` entry. */
858
+ declare function getWhereExpression(where: Where): BasicExpression<boolean>;
859
+ /**
860
+ * Extract the expression from a `Having` entry. HAVING clauses may
861
+ * contain aggregates, unlike plain WHERE.
862
+ */
863
+ declare function getHavingExpression(having: Having): BasicExpression | Aggregate;
864
+ /** Is this `Where` entry marked residual (post-index-scan)? */
865
+ declare function isResidualWhere(where: Where): boolean;
866
+ /** Wrap a bare boolean expression as a residual `Where`. */
867
+ declare function createResidualWhere(expression: BasicExpression<boolean>): Where;
868
+ /**
869
+ * Walk a `PropRef`'s first alias segment back through any
870
+ * enclosing `QueryRef`s to reach the underlying `Collection` and
871
+ * the remaining column-path. Returns `undefined` if the ref can't
872
+ * be resolved to a collection (e.g. it points at a computed
873
+ * SELECT field; Layer F's optimizer is the only caller today).
874
+ */
875
+ declare function followRef(query: QueryIR, ref: PropRef<unknown>, collection: Collection): {
876
+ collection: Collection;
877
+ path: Array<string>;
878
+ } | undefined;
879
+
880
+ type ir_Aggregate<T = unknown> = Aggregate<T>;
881
+ declare const ir_Aggregate: typeof Aggregate;
882
+ type ir_BasicExpression<T = unknown> = BasicExpression<T>;
883
+ type ir_CollectionRef = CollectionRef;
884
+ declare const ir_CollectionRef: typeof CollectionRef;
885
+ type ir_CompareOptions = CompareOptions;
886
+ type ir_From = From;
887
+ type ir_Func<T = unknown> = Func<T>;
888
+ declare const ir_Func: typeof Func;
889
+ type ir_GroupBy = GroupBy;
890
+ type ir_Having = Having;
891
+ declare const ir_INCLUDES_SCALAR_FIELD: typeof INCLUDES_SCALAR_FIELD;
892
+ type ir_IncludesMaterialization = IncludesMaterialization;
893
+ type ir_IncludesSubquery = IncludesSubquery;
894
+ declare const ir_IncludesSubquery: typeof IncludesSubquery;
895
+ type ir_Join = Join;
896
+ type ir_JoinClause = JoinClause;
897
+ type ir_Limit = Limit;
898
+ type ir_NamespacedRow = NamespacedRow;
899
+ type ir_Offset = Offset;
900
+ type ir_OrderBy = OrderBy;
901
+ type ir_OrderByClause = OrderByClause;
902
+ type ir_OrderByDirection = OrderByDirection;
903
+ type ir_PropRef<T = unknown> = PropRef<T>;
904
+ declare const ir_PropRef: typeof PropRef;
905
+ type ir_QueryIR = QueryIR;
906
+ type ir_QueryRef = QueryRef;
907
+ declare const ir_QueryRef: typeof QueryRef;
908
+ type ir_Select = Select;
909
+ type ir_Value<T = unknown> = Value<T>;
910
+ declare const ir_Value: typeof Value;
911
+ type ir_Where = Where;
912
+ declare const ir_createResidualWhere: typeof createResidualWhere;
913
+ declare const ir_followRef: typeof followRef;
914
+ declare const ir_getHavingExpression: typeof getHavingExpression;
915
+ declare const ir_getWhereExpression: typeof getWhereExpression;
916
+ declare const ir_isExpressionLike: typeof isExpressionLike;
917
+ declare const ir_isResidualWhere: typeof isResidualWhere;
918
+ declare namespace ir {
919
+ export { ir_Aggregate as Aggregate, type ir_BasicExpression as BasicExpression, ir_CollectionRef as CollectionRef, type ir_CompareOptions as CompareOptions, type ir_From as From, ir_Func as Func, type ir_GroupBy as GroupBy, type ir_Having as Having, ir_INCLUDES_SCALAR_FIELD as INCLUDES_SCALAR_FIELD, type ir_IncludesMaterialization as IncludesMaterialization, ir_IncludesSubquery as IncludesSubquery, type ir_Join as Join, type ir_JoinClause as JoinClause, type ir_Limit as Limit, type ir_NamespacedRow as NamespacedRow, type ir_Offset as Offset, type ir_OrderBy as OrderBy, type ir_OrderByClause as OrderByClause, type ir_OrderByDirection as OrderByDirection, ir_PropRef as PropRef, type ir_QueryIR as QueryIR, ir_QueryRef as QueryRef, type ir_Select as Select, ir_Value as Value, type ir_Where as Where, ir_createResidualWhere as createResidualWhere, ir_followRef as followRef, ir_getHavingExpression as getHavingExpression, ir_getWhereExpression as getWhereExpression, ir_isExpressionLike as isExpressionLike, ir_isResidualWhere as isResidualWhere };
920
+ }
921
+
922
+ /**
923
+ * Expression helpers — `@tanstack/db` parity (Layer C.3).
924
+ *
925
+ * Each helper returns a `BasicExpression` (PropRef / Value / Func)
926
+ * or `Aggregate` node. Comparison / logical / string / numeric /
927
+ * null / aggregate helpers all route literals and ref-proxies
928
+ * through `toExpression`.
929
+ *
930
+ * Runtime behavior matches `@tanstack/db/query/builder/functions.js`.
931
+ * Type layer is loosened (we type operands as `unknown`) because
932
+ * upstream's deep inference machinery (`ComparisonOperand`,
933
+ * `AggregateReturnType`, `CoalesceReturnType`, etc.) is Layer-G work;
934
+ * users still get good IDE support because the return types (`Func`,
935
+ * `Aggregate`) are narrow IR nodes, and the builder callbacks
936
+ * receive typed ref proxies.
937
+ *
938
+ * Also exports:
939
+ * - `operators` — runtime array of all operator names.
940
+ * - `comparisonFunctions` — subset that indexes can accept.
941
+ * - `OperatorName` — union of operator literals.
942
+ * - `ToArrayWrapper` / `ConcatToArrayWrapper` / `toArray` — IR
943
+ * wrappers for sub-query projection. Compiled in Layer C.5.
944
+ */
945
+
946
+ declare function eq(left: unknown, right: unknown): BasicExpression<boolean>;
947
+ declare function gt(left: unknown, right: unknown): BasicExpression<boolean>;
948
+ declare function gte(left: unknown, right: unknown): BasicExpression<boolean>;
949
+ declare function lt(left: unknown, right: unknown): BasicExpression<boolean>;
950
+ declare function lte(left: unknown, right: unknown): BasicExpression<boolean>;
951
+ declare function and(left: unknown, right: unknown, ...rest: Array<unknown>): BasicExpression<boolean>;
952
+ declare function or(left: unknown, right: unknown, ...rest: Array<unknown>): BasicExpression<boolean>;
953
+ declare function not(value: unknown): BasicExpression<boolean>;
954
+ declare function isUndefined(value: unknown): BasicExpression<boolean>;
955
+ declare function isNull(value: unknown): BasicExpression<boolean>;
956
+ /**
957
+ * `inArray(value, array)` — operator name is `'in'` in IR (matches
958
+ * upstream) even though the helper is named `inArray`.
959
+ */
960
+ declare function inArray(value: unknown, array: unknown): BasicExpression<boolean>;
961
+ declare function like(left: unknown, right: unknown): BasicExpression<boolean>;
962
+ declare function ilike(left: unknown, right: unknown): BasicExpression<boolean>;
963
+ declare function upper(arg: unknown): BasicExpression<string | null | undefined>;
964
+ declare function lower(arg: unknown): BasicExpression<string | null | undefined>;
965
+ declare function length(arg: unknown): BasicExpression<number | null | undefined>;
966
+ /**
967
+ * `concat(...args)` — string concatenation. When a single
968
+ * `ToArrayWrapper` argument is passed (subquery projection), wraps
969
+ * it in `ConcatToArrayWrapper` so the compiler projects into a
970
+ * joined string. Multiple `ToArrayWrapper` args are not supported
971
+ * (matches upstream error).
972
+ */
973
+ declare function concat(...args: Array<unknown>): BasicExpression<string> | ConcatToArrayWrapper;
974
+ declare function add(left: unknown, right: unknown): BasicExpression<number | null | undefined>;
975
+ declare function subtract(left: unknown, right: unknown): BasicExpression<number>;
976
+ declare function multiply(left: unknown, right: unknown): BasicExpression<number>;
977
+ declare function divide(left: unknown, right: unknown): BasicExpression<number | null>;
978
+ declare function coalesce(first: unknown, ...rest: Array<unknown>): BasicExpression;
979
+ /** Scalar CASE WHEN expression. Conditions and values alternate; an odd final
980
+ * argument is the default value. Without a default, unmatched rows yield null. */
981
+ declare function caseWhen(...args: Array<unknown>): BasicExpression;
982
+ declare function count(arg: unknown): Aggregate<number>;
983
+ declare function avg(arg: unknown): Aggregate<number | null | undefined>;
984
+ declare function sum(arg: unknown): Aggregate<number | null | undefined>;
985
+ declare function min(arg: unknown): Aggregate;
986
+ declare function max(arg: unknown): Aggregate;
987
+ /** Comparison operators accepted by index implementations. */
988
+ declare const comparisonFunctions: readonly ["eq", "gt", "gte", "lt", "lte", "in", "like", "ilike"];
989
+ /** All supported operator names. Matches upstream. */
990
+ declare const operators: readonly ["eq", "gt", "gte", "lt", "lte", "in", "like", "ilike", "and", "or", "not", "isNull", "isUndefined", "upper", "lower", "length", "concat", "add", "subtract", "multiply", "divide", "coalesce", "caseWhen", "count", "avg", "sum", "min", "max"];
991
+ type OperatorName = (typeof operators)[number];
992
+ /**
993
+ * Marker for `toArray(q)` — materializes a sub-query as an array
994
+ * projected into the parent SELECT. Compile path lands in C.5;
995
+ * the class is shipped now so type-resolution in builder / helpers
996
+ * works.
997
+ */
998
+ declare class ToArrayWrapper<_T = unknown> {
999
+ readonly query: unknown;
1000
+ readonly __brand: "ToArrayWrapper";
1001
+ readonly _type: 'toArray';
1002
+ readonly _result: _T;
1003
+ constructor(query: unknown);
1004
+ }
1005
+ /**
1006
+ * Marker for `concat(toArray(q))` — string-joins the projected
1007
+ * sub-query rows. Compile path lands in C.5.
1008
+ */
1009
+ declare class ConcatToArrayWrapper<_T = unknown> {
1010
+ readonly query: unknown;
1011
+ readonly __brand: "ConcatToArrayWrapper";
1012
+ readonly _type: 'concatToArray';
1013
+ readonly _result: _T;
1014
+ constructor(query: unknown);
1015
+ }
1016
+ declare class MaterializeWrapper<_T = unknown, _IsSingle extends boolean = boolean> {
1017
+ readonly query: unknown;
1018
+ readonly __brand: "MaterializeWrapper";
1019
+ readonly _type: 'materialize';
1020
+ readonly _result: _T;
1021
+ readonly _isSingle: _IsSingle;
1022
+ constructor(query: unknown);
1023
+ }
1024
+ /**
1025
+ * Wrap a QueryBuilder as an array-result sub-query. Used as a
1026
+ * SELECT field value: `select(({p, children}) => ({ p, children:
1027
+ * toArray(children) }))`. Compile path in C.5.
1028
+ */
1029
+ declare function toArray(query: unknown): ToArrayWrapper;
1030
+ declare function materialize(query: unknown): MaterializeWrapper;
1031
+
1032
+ interface RangeQueryOptions {
1033
+ from?: unknown;
1034
+ to?: unknown;
1035
+ fromInclusive?: boolean;
1036
+ toInclusive?: boolean;
1037
+ }
1038
+
1039
+ /** Operations that index implementations can support. */
1040
+ declare const IndexOperation: readonly ["eq", "gt", "gte", "lt", "lte", "in", "like", "ilike"];
1041
+ type IndexOperation = (typeof comparisonFunctions)[number];
1042
+ /** Statistics about index usage and performance. */
1043
+ interface IndexStats {
1044
+ readonly entryCount: number;
1045
+ readonly lookupCount: number;
1046
+ readonly averageLookupTime: number;
1047
+ readonly lastUpdated: Date;
1048
+ }
1049
+ interface IndexInterface<TKey extends string | number = string | number> {
1050
+ add(key: TKey, item: unknown): void;
1051
+ remove(key: TKey, item: unknown): void;
1052
+ update(key: TKey, oldItem: unknown, newItem: unknown): void;
1053
+ build(entries: Iterable<[TKey, unknown]>): void;
1054
+ clear(): void;
1055
+ lookup(operation: IndexOperation, value: unknown): Set<TKey>;
1056
+ equalityLookup(value: unknown): Set<TKey>;
1057
+ inArrayLookup(values: Array<unknown>): Set<TKey>;
1058
+ rangeQuery(options?: RangeQueryOptions): Set<TKey>;
1059
+ rangeQueryReversed(options?: RangeQueryOptions): Set<TKey>;
1060
+ take(n: number, from?: unknown, filterFn?: (key: TKey) => boolean): Array<TKey>;
1061
+ takeFromStart(n: number, filterFn?: (key: TKey) => boolean): Array<TKey>;
1062
+ takeReversed(n: number, from?: unknown, filterFn?: (key: TKey) => boolean): Array<TKey>;
1063
+ takeReversedFromEnd(n: number, filterFn?: (key: TKey) => boolean): Array<TKey>;
1064
+ get keyCount(): number;
1065
+ get orderedEntriesArray(): Array<[unknown, Set<TKey>]>;
1066
+ get orderedEntriesArrayReversed(): Array<[unknown, Set<TKey>]>;
1067
+ get indexedKeysSet(): Set<TKey>;
1068
+ get valueMapData(): Map<unknown, Set<TKey>>;
1069
+ supports(operation: IndexOperation): boolean;
1070
+ matchesField(fieldPath: Array<string>): boolean;
1071
+ matchesCompareOptions(compareOptions: CompareOptions): boolean;
1072
+ matchesDirection(direction: OrderByDirection): boolean;
1073
+ getStats(): IndexStats;
1074
+ }
1075
+ /** Base abstract class that all index types extend. */
1076
+ declare abstract class BaseIndex<TKey extends string | number = string | number> implements IndexInterface<TKey> {
1077
+ readonly id: number;
1078
+ readonly name?: string;
1079
+ readonly expression: BasicExpression;
1080
+ abstract readonly supportedOperations: Set<IndexOperation>;
1081
+ protected lookupCount: number;
1082
+ protected totalLookupTime: number;
1083
+ protected lastUpdated: Date;
1084
+ protected compareOptions: CompareOptions;
1085
+ constructor(id: number, expression: BasicExpression, name?: string, options?: unknown);
1086
+ abstract add(key: TKey, item: unknown): void;
1087
+ abstract remove(key: TKey, item: unknown): void;
1088
+ abstract update(key: TKey, oldItem: unknown, newItem: unknown): void;
1089
+ abstract build(entries: Iterable<[TKey, unknown]>): void;
1090
+ abstract clear(): void;
1091
+ abstract lookup(operation: IndexOperation, value: unknown): Set<TKey>;
1092
+ abstract equalityLookup(value: unknown): Set<TKey>;
1093
+ abstract inArrayLookup(values: Array<unknown>): Set<TKey>;
1094
+ abstract rangeQuery(options?: RangeQueryOptions): Set<TKey>;
1095
+ abstract rangeQueryReversed(options?: RangeQueryOptions): Set<TKey>;
1096
+ abstract take(n: number, from?: unknown, filterFn?: (key: TKey) => boolean): Array<TKey>;
1097
+ abstract takeFromStart(n: number, filterFn?: (key: TKey) => boolean): Array<TKey>;
1098
+ abstract takeReversed(n: number, from?: unknown, filterFn?: (key: TKey) => boolean): Array<TKey>;
1099
+ abstract takeReversedFromEnd(n: number, filterFn?: (key: TKey) => boolean): Array<TKey>;
1100
+ abstract get keyCount(): number;
1101
+ abstract get orderedEntriesArray(): Array<[unknown, Set<TKey>]>;
1102
+ abstract get orderedEntriesArrayReversed(): Array<[unknown, Set<TKey>]>;
1103
+ abstract get indexedKeysSet(): Set<TKey>;
1104
+ abstract get valueMapData(): Map<unknown, Set<TKey>>;
1105
+ protected abstract initialize(options?: unknown): void;
1106
+ supports(operation: IndexOperation): boolean;
1107
+ matchesField(fieldPath: Array<string>): boolean;
1108
+ /** Checks compare options; direction ignored because ReverseIndex can flip traversal. */
1109
+ matchesCompareOptions(compareOptions: CompareOptions): boolean;
1110
+ matchesDirection(direction: OrderByDirection): boolean;
1111
+ getStats(): IndexStats;
1112
+ protected evaluateIndexExpression(item: unknown): unknown;
1113
+ protected trackLookup(startTime: number): void;
1114
+ protected updateTimestamp(): void;
1115
+ }
1116
+ /** Type for index constructors. */
1117
+ type IndexConstructor<TKey extends string | number = string | number> = new (id: number, expression: BasicExpression, name?: string, options?: any) => BaseIndex<TKey>;
1118
+
1119
+ interface IndexOptions<TIndexType extends IndexConstructor = IndexConstructor> {
1120
+ /** Optional name for the index. */
1121
+ name?: string;
1122
+ /** Index implementation to instantiate, e.g. BasicIndex or BTreeIndex. */
1123
+ indexType?: TIndexType;
1124
+ /** Options passed to the index constructor. */
1125
+ options?: TIndexType extends new (id: number, expr: any, name?: string, options?: infer O) => unknown ? O : never;
1126
+ }
1127
+
1128
+ /**
1129
+ * Change event emitted by Collection after each mutation, consumed by the
1130
+ * reactive query engine.
1131
+ *
1132
+ * `columns` is an explicit set of column names that were written. Deletions
1133
+ * (soft) touch `__deleted` only; rollbacks may emit `columns: 'all'` when a
1134
+ * rollback re-inserts a snapshot.
1135
+ */
1136
+ type ChangeOp = 'insert' | 'update' | 'delete' | 'rollback' | 'compact';
1137
+ interface ChangeEvent {
1138
+ readonly op: ChangeOp;
1139
+ readonly rowId: number;
1140
+ /** Columns written by this mutation, or 'all' when unknown / broad. */
1141
+ readonly columns: ReadonlySet<string> | 'all';
1142
+ /** Monotonic collection global version after the mutation. */
1143
+ readonly globalVersion: number;
1144
+ /**
1145
+ * Current row snapshot after the mutation.
1146
+ *
1147
+ * For `insert` and `update` ops: the full row as it exists post-mutation.
1148
+ * For `delete` op (soft or hard): the final row state — for soft-deletes
1149
+ * this is the row with `__deleted: true`; for hard-deletes it's the
1150
+ * last snapshot before removal (taken from the undo log).
1151
+ * For `rollback` and `compact`: may be undefined if the snapshot would
1152
+ * be expensive to reconstruct and no consumer needs it.
1153
+ *
1154
+ * Exists so `subscribeChanges` adapters (TanStack DB `ChangeMessage`
1155
+ * shape) can emit the `value` field without re-reading the collection,
1156
+ * which is critical for delete events where the row is gone.
1157
+ */
1158
+ readonly value?: Readonly<Record<string, unknown>>;
1159
+ /**
1160
+ * For `update` ops only: the subset of columns as they were before the
1161
+ * mutation. Keys match the entries in `columns`. Absent for other ops.
1162
+ */
1163
+ readonly previousValue?: Readonly<Record<string, unknown>>;
1164
+ /**
1165
+ * Optional decomposed high-level changes for broad events like rollback.
1166
+ * Kept structurally typed here to avoid coupling the low-level emitter to
1167
+ * TanStack-facing public types.
1168
+ */
1169
+ readonly changes?: ReadonlyArray<{
1170
+ key: number;
1171
+ value: Readonly<Record<string, unknown>>;
1172
+ previousValue?: Readonly<Record<string, unknown>>;
1173
+ type: 'insert' | 'update' | 'delete';
1174
+ }>;
1175
+ }
1176
+ type ChangeListener = (event: ChangeEvent) => void;
1177
+ /**
1178
+ * Simple synchronous emitter. Listeners are invoked in insertion order. An
1179
+ * error thrown by a listener is caught and logged so subsequent listeners
1180
+ * still run — this keeps mutation correctness independent of query bugs.
1181
+ */
1182
+ declare class ChangeEmitter {
1183
+ private listeners;
1184
+ subscribe(listener: ChangeListener): () => void;
1185
+ emit(event: ChangeEvent): void;
1186
+ get size(): number;
1187
+ }
1188
+
1189
+ type MutateCallbackResult = void | PromiseLike<void>;
1190
+ declare function createTransaction<T extends object = Record<string, unknown>>(config: TransactionConfig<T>): Transaction<T>;
1191
+ declare function getActiveTransaction(): Transaction | undefined;
1192
+ declare class Transaction<T extends object = Record<string, unknown>> {
1193
+ readonly id: string;
1194
+ readonly mutationFn: MutationFn<T>;
1195
+ readonly mutations: Array<PendingMutation<T>>;
1196
+ readonly isPersisted: Deferred<Transaction<T>>;
1197
+ readonly autoCommit: boolean;
1198
+ readonly createdAt: Date;
1199
+ readonly sequenceNumber: number;
1200
+ readonly metadata: Record<string, unknown>;
1201
+ private readonly rollbackHandlers;
1202
+ state: TransactionState;
1203
+ error?: {
1204
+ message: string;
1205
+ error: Error;
1206
+ };
1207
+ constructor(config: TransactionConfig<T>);
1208
+ setState(newState: TransactionState): void;
1209
+ mutate(callback: () => MutateCallbackResult): Transaction<T>;
1210
+ addRollbackHandler(handler: () => void): void;
1211
+ applyMutations(mutations: Array<PendingMutation<any>>): void;
1212
+ rollback(config?: {
1213
+ isSecondaryRollback?: boolean;
1214
+ }): Transaction<T>;
1215
+ touchCollection(): void;
1216
+ commit(): Promise<Transaction<T>>;
1217
+ compareCreatedAt(other: Transaction<any>): number;
1218
+ }
1219
+
1220
+ /**
1221
+ * Per-column append-only byte heap used by Utf8 columns. Strings are written
1222
+ * contiguously; each row owns a `[start, end)` byte range stored externally
1223
+ * in the column's offsets buffer. Updates always append fresh bytes at the
1224
+ * tail — old bytes are leaked until a future compaction pass.
1225
+ *
1226
+ * The heap is a Uint8Array view onto the segment; we own only the bump
1227
+ * cursor and encoder/decoder.
1228
+ */
1229
+ declare class ValuesHeap {
1230
+ private cursor;
1231
+ private readonly bytes;
1232
+ private readonly encoder;
1233
+ private readonly decoder;
1234
+ constructor(bytes: Uint8Array);
1235
+ /** Current bump position (= first free byte). */
1236
+ get used(): number;
1237
+ /** Total capacity in bytes. */
1238
+ get capacity(): number;
1239
+ /** Read-only view of the underlying byte buffer. Used by snapshot export. */
1240
+ get rawBytes(): Uint8Array;
1241
+ /** Append raw bytes; returns their `[start, end)` range. */
1242
+ appendBytes(src: Uint8Array): {
1243
+ start: number;
1244
+ end: number;
1245
+ };
1246
+ /**
1247
+ * Encode `value` as UTF-8 and append to the heap. Returns the byte range
1248
+ * `[start, end)` where the encoded bytes live.
1249
+ */
1250
+ append(value: string): {
1251
+ start: number;
1252
+ end: number;
1253
+ };
1254
+ /** Decode a `[start, end)` byte range back to a string. */
1255
+ read(start: number, end: number): string;
1256
+ /** Read a `[start, end)` range as a copy of raw bytes. */
1257
+ readBytes(start: number, end: number): Uint8Array;
1258
+ /**
1259
+ * Copy bytes `[start, end)` from this heap directly into `dest` starting
1260
+ * at `destOffset`. No allocation. Used by compaction to shuffle live
1261
+ * ranges without a per-row Uint8Array allocation.
1262
+ */
1263
+ copyInto(start: number, end: number, dest: Uint8Array, destOffset: number): void;
1264
+ /**
1265
+ * Reset the cursor to zero. The caller must have already copied any live
1266
+ * ranges elsewhere. Used by `Collection.compact()`.
1267
+ */
1268
+ resetEmpty(): void;
1269
+ /**
1270
+ * Overwrite the heap with `src[0..length)` starting at byte 0 and set
1271
+ * the cursor to `length`. Caller guarantees `length <= capacity`. Used
1272
+ * by `Collection.compact()` to swap a rebuilt heap back in place.
1273
+ */
1274
+ rewrite(src: Uint8Array, length: number): void;
1275
+ }
1276
+ /**
1277
+ * Side table for a dictionary-encoded Utf8 column. Code 0 is the first
1278
+ * interned string — nulls are signalled via the column's validity bitmap,
1279
+ * not via a reserved code.
1280
+ *
1281
+ * Dictionary is append-only in Phase 3. A later phase may add reference
1282
+ * counts and compaction.
1283
+ */
1284
+ declare class Dictionary {
1285
+ private codeByString;
1286
+ private stringByCode;
1287
+ /** Number of distinct strings currently interned. */
1288
+ get size(): number;
1289
+ /** Return the code for `s`, interning it if absent. */
1290
+ intern(s: string): number;
1291
+ /** Return the code for `s`, or undefined if not interned. */
1292
+ lookup(s: string): number | undefined;
1293
+ /** Decode a code back to its string. Throws on unknown codes. */
1294
+ decode(code: number): string;
1295
+ /** Iterate all (code, string) pairs in insertion order. */
1296
+ entries(): IterableIterator<[number, string]>;
1297
+ }
1298
+
1299
+ type Point = readonly [lng: number, lat: number];
1300
+
1301
+ type BBox = readonly [minX: number, minY: number, maxX: number, maxY: number];
1302
+
1303
+ type LineString = readonly Point[];
1304
+
1305
+ type LinearRing = readonly Point[];
1306
+ type Polygon = readonly LinearRing[];
1307
+
1308
+ /** Row value for a schema with primitive + utf8 + binary + list + struct + geo columns. */
1309
+ type RowValue = Record<string, number | bigint | boolean | string | Uint8Array | readonly unknown[] | Record<string, unknown> | Point | LineString | Polygon | null>;
1310
+ /**
1311
+ * Collection lifecycle status. Mirrors `@tanstack/db`'s
1312
+ * `CollectionStatus` union bit-for-bit:
1313
+ *
1314
+ * - `idle` — created but sync not started (used only with
1315
+ * `startSync: false` sync configs).
1316
+ * - `loading` — sync has started and is loading.
1317
+ * - `ready` — collection is usable; data available.
1318
+ * - `error` — sync initialization failed.
1319
+ * - `cleaned-up` — resources released; no further use.
1320
+ *
1321
+ * In-memory collections (our current default) start in `'ready'` and
1322
+ * only transition to `'cleaned-up'` via `cleanup()`.
1323
+ */
1324
+ type CollectionStatus = 'idle' | 'loading' | 'ready' | 'error' | 'cleaned-up';
1325
+ /**
1326
+ * Payload for the `status:change` event. Matches @tanstack/db's
1327
+ * `CollectionStatusChangeEvent`.
1328
+ */
1329
+ interface CollectionStatusChangeEvent {
1330
+ type: 'status:change';
1331
+ collection: Collection;
1332
+ previousStatus: CollectionStatus;
1333
+ status: CollectionStatus;
1334
+ }
1335
+ /**
1336
+ * Payload for `subscribers:change`. Fires whenever the number of
1337
+ * `subscribeChanges` subscribers grows or shrinks.
1338
+ */
1339
+ interface CollectionSubscribersChangeEvent {
1340
+ type: 'subscribers:change';
1341
+ collection: Collection;
1342
+ previousSubscriberCount: number;
1343
+ subscriberCount: number;
1344
+ }
1345
+ /**
1346
+ * Payload for `truncate`. Fires when the backing sync source has
1347
+ * instructed us to drop all rows (e.g. after a must-refetch
1348
+ * signal). Currently unused at the collection layer but exposed
1349
+ * for parity; Layer E wires it up.
1350
+ */
1351
+ interface CollectionTruncateEvent {
1352
+ type: 'truncate';
1353
+ collection: Collection;
1354
+ }
1355
+ /**
1356
+ * All events a Collection can emit. Matches @tanstack/db's
1357
+ * `AllCollectionEvents` in shape (minus index-add/remove, which
1358
+ * land in Layer D, and loadingSubset, which is subset-load-only).
1359
+ */
1360
+ type CollectionEvents = {
1361
+ 'status:change': CollectionStatusChangeEvent;
1362
+ 'subscribers:change': CollectionSubscribersChangeEvent;
1363
+ truncate: CollectionTruncateEvent;
1364
+ 'status:idle': CollectionStatusChangeEvent;
1365
+ 'status:loading': CollectionStatusChangeEvent;
1366
+ 'status:ready': CollectionStatusChangeEvent;
1367
+ 'status:error': CollectionStatusChangeEvent;
1368
+ 'status:cleaned-up': CollectionStatusChangeEvent;
1369
+ };
1370
+ type IndexExpressionCallback = (row: SingleRowRefProxy<Record<string, unknown>>) => unknown;
1371
+ type CollectionIndexOptions = IndexOptions<IndexConstructor<number>>;
1372
+ type AutoIndexMode = 'off' | 'eager';
1373
+ interface SpatialIndexOptions {
1374
+ readonly column: string;
1375
+ readonly type: 'rtree';
1376
+ readonly eager?: boolean;
1377
+ }
1378
+ type SpatialIndexConfig = SpatialIndexOptions | readonly SpatialIndexOptions[];
1379
+ interface CollectionRuntimeConfig {
1380
+ autoIndex: AutoIndexMode;
1381
+ defaultIndexType?: IndexConstructor<number>;
1382
+ spatialIndex?: SpatialIndexConfig;
1383
+ }
1384
+ interface CollectionOptions {
1385
+ /** Maximum number of rows the collection can hold. Required in Phase 1. */
1386
+ capacity: number;
1387
+ /** Undo ring capacity in entries. Default 4096. */
1388
+ undoCapacity?: number;
1389
+ /**
1390
+ * When true, `delete(id)` sets a `__deleted` flag and keeps the row slot.
1391
+ * The column must be declared in the schema as `{ type: 'bool' }`.
1392
+ * Defaults to true if `__deleted` column exists, else false.
1393
+ */
1394
+ softDelete?: boolean;
1395
+ /**
1396
+ * Optional stable identifier for the collection. Mirrors
1397
+ * `@tanstack/db`'s `CollectionConfig.id`. Defaults to
1398
+ * `${schema.name}:${monotonicCounter}`. Used for debugging,
1399
+ * devtools, and as a key in broadcast/sync adapters.
1400
+ */
1401
+ id?: string;
1402
+ /**
1403
+ * Utility functions attached to this collection. Exposed via the
1404
+ * `utils` getter. Callers can use these to plumb collection-specific
1405
+ * helpers (e.g. `refetch`, `setState`) without subclassing. Matches
1406
+ * `@tanstack/db`'s `CollectionConfig.utils`.
1407
+ */
1408
+ utils?: UtilsRecord;
1409
+ /**
1410
+ * String collation config — influences `orderBy` over string
1411
+ * columns. Currently stored and echoed through `compareOptions`; the
1412
+ * query layer picks it up in Layer C. Matches `@tanstack/db`'s
1413
+ * `CollectionConfig.compareOptions`.
1414
+ */
1415
+ compareOptions?: StringCollationConfig;
1416
+ /** Auto-index strategy. `eager` creates indexes for simple subscribed where expressions. */
1417
+ autoIndex?: AutoIndexMode;
1418
+ /** Default index implementation used by auto-index and option-less createIndex. */
1419
+ defaultIndexType?: IndexConstructor<number>;
1420
+ /** Optional R-tree index config for point/linestring/polygon envelopes. */
1421
+ spatialIndex?: SpatialIndexConfig;
1422
+ }
1423
+ type TypedValueArray = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
1424
+ /**
1425
+ * Internal scan-view entry exposed via `_internalScanColumns()` for the
1426
+ * vectorized kernel. Not part of the public API surface — may change.
1427
+ */
1428
+ interface ScanColumn {
1429
+ readonly name: string;
1430
+ readonly typeCode: ColumnTypeCode;
1431
+ readonly nullable: boolean;
1432
+ readonly validity: Uint8Array | null;
1433
+ readonly values: TypedValueArray;
1434
+ readonly heap: ValuesHeap | null;
1435
+ readonly dictionary: Dictionary | null;
1436
+ }
1437
+ /**
1438
+ * Tree-shaped view emitted by `bulkColumnViewsTree()` for the snapshot
1439
+ * exporter. Internal surface — subject to change.
1440
+ */
1441
+ interface TreeView {
1442
+ readonly name: string;
1443
+ readonly type: ColumnTypeName;
1444
+ readonly typeCode: ColumnTypeCode;
1445
+ readonly nullable: boolean;
1446
+ readonly validity: Uint8Array | null;
1447
+ readonly primaryBuffer: Uint8Array;
1448
+ readonly heap: Uint8Array | null;
1449
+ readonly dictionaryEntries: readonly string[] | null;
1450
+ readonly listChildElements?: number;
1451
+ readonly listChild?: TreeView;
1452
+ readonly fields?: readonly TreeView[];
1453
+ }
1454
+ /**
1455
+ * Phase 1 Collection: fixed-capacity, fixed-width primitive columns, dense
1456
+ * `uint32` PK, single-writer. No cross-worker attach yet (Segment is created
1457
+ * locally); the SAB buffer is exposed via `getSegmentBuffer()` for future
1458
+ * worker handoff.
1459
+ */
1460
+ declare class Collection {
1461
+ readonly schema: CompiledSchema;
1462
+ readonly capacity: number;
1463
+ private readonly segment;
1464
+ private readonly columns;
1465
+ private readonly columnList;
1466
+ private readonly rowIndex;
1467
+ private readonly undo;
1468
+ private readonly pkColumn;
1469
+ private readonly deletedColumn;
1470
+ private readonly softDelete;
1471
+ private readonly emitter;
1472
+ /**
1473
+ * TanStack-DB-compatible high-level event emitter. Handles
1474
+ * `status:change`, `subscribers:change`, `truncate`, `index:added`,
1475
+ * `index:removed`, and per-status events. Separate from the
1476
+ * low-level per-mutation `ChangeEmitter` above because the event
1477
+ * cadences differ: mutation events fire on every row touch; these
1478
+ * fire on lifecycle transitions.
1479
+ */
1480
+ private readonly events;
1481
+ /** Active secondary indexes keyed by monotonically assigned index id. */
1482
+ private readonly _indexes;
1483
+ /** Active geometry-envelope spatial indexes keyed by column name. */
1484
+ private readonly _spatialIndexes;
1485
+ private _nextIndexId;
1486
+ /**
1487
+ * Tracks external subscribers created via `subscribeChanges`. Used
1488
+ * by `subscriberCount` getter and emitted via `subscribers:change`.
1489
+ */
1490
+ private _subscriberCount;
1491
+ /** Dense row cursor: next row slot to use. */
1492
+ private rowCursor;
1493
+ /** Monotonic collection-wide version counter. */
1494
+ private _globalVersion;
1495
+ /** Stable identifier (see `id` getter). */
1496
+ private readonly _id;
1497
+ /** Utils record (see `utils` getter). */
1498
+ private readonly _utils;
1499
+ /** Compare options for string orderBy (see `compareOptions` getter). */
1500
+ private readonly _compareOptions;
1501
+ /** TanStack-shaped runtime collection config needed by index planning. */
1502
+ private readonly _config;
1503
+ /** Undo marks registered for optimistic transaction rollbacks. */
1504
+ private readonly transactionRollbackMarks;
1505
+ /** Attached sync source lifecycle state. */
1506
+ private syncStarted;
1507
+ private syncCleanup;
1508
+ private constructor();
1509
+ static create(schema: CompiledSchema, options: CollectionOptions): Collection;
1510
+ /** Monotonic counter for default `id` assignment. */
1511
+ private static _idCounter;
1512
+ /** Number of live (non-deleted) rows. */
1513
+ get size(): number;
1514
+ /** Raw row slot count (including tombstoned rows for soft-delete). */
1515
+ get rowCount(): number;
1516
+ get globalVersion(): number;
1517
+ /** Runtime collection config (TanStack-shaped subset). */
1518
+ get config(): Readonly<CollectionRuntimeConfig>;
1519
+ /** Read the version counter for a single column. */
1520
+ columnVersion(name: string): number;
1521
+ /** Expose the underlying segment buffer (for future worker handoff). */
1522
+ getSegmentBuffer(): SharedArrayBuffer | ArrayBuffer;
1523
+ /** Subscribe to mutation events. Returns an unsubscribe function. */
1524
+ subscribe(listener: ChangeListener): () => void;
1525
+ /** Count of active `subscribeChanges` subscribers. */
1526
+ get subscriberCount(): number;
1527
+ /**
1528
+ * Subscribe to collection changes as TanStack DB `ChangeMessage[]`
1529
+ * batches. The callback receives an array of change messages;
1530
+ * batches contain a single message in Layer B (one message per
1531
+ * mutation). Layer E's transaction machinery will coalesce
1532
+ * multiple mutations into a single array when a tx commits.
1533
+ *
1534
+ * When `options.includeInitialState` is true, the callback is
1535
+ * invoked synchronously with one `insert` message per current
1536
+ * live row before any mutation-driven calls.
1537
+ *
1538
+ * Returns a `CollectionSubscription` handle; call `unsubscribe()`
1539
+ * to detach. Reading `subscriberCount` also reflects the count.
1540
+ */
1541
+ subscribeChanges(callback: (changes: ChangeMessage<RowValue, number>[]) => void, options?: SubscribeChangesOptions): CollectionSubscription;
1542
+ /**
1543
+ * Return the current live state as an array of `insert`
1544
+ * `ChangeMessage`s. Analogous to @tanstack/db's
1545
+ * `currentStateAsChanges()`. Options are accepted for future
1546
+ * compat (where / orderBy / limit) but are no-ops in Layer B;
1547
+ * Layer C wires them up to the query path.
1548
+ */
1549
+ currentStateAsChanges(_options?: CurrentStateAsChangesOptions): ChangeMessage<RowValue, number>[];
1550
+ /**
1551
+ * Map a low-level `ChangeEvent` to a TanStack `ChangeMessage`.
1552
+ * Returns null for `rollback`/`compact` — those don't have a 1:1
1553
+ * representation in TanStack DB's model (they'd decompose into a
1554
+ * series of inverse inserts/updates/deletes). Layer E will handle
1555
+ * that decomposition; for now consumers that care must observe
1556
+ * the low-level `subscribe()` channel.
1557
+ */
1558
+ private _changeEventToMessage;
1559
+ private filterAndFlipSubscriptionChanges;
1560
+ private _subscribeWhereExpression;
1561
+ /** Type-safe event subscription. Returns an unsubscribe fn. */
1562
+ on<K extends keyof CollectionEvents>(event: K, callback: (payload: CollectionEvents[K]) => void): () => void;
1563
+ /** Subscribe for one emission of `event`. Returns unsubscribe fn. */
1564
+ once<K extends keyof CollectionEvents>(event: K, callback: (payload: CollectionEvents[K]) => void): () => void;
1565
+ /** Remove a specific `on`/`once` listener. */
1566
+ off<K extends keyof CollectionEvents>(event: K, callback: (payload: CollectionEvents[K]) => void): void;
1567
+ /**
1568
+ * Await the next emission of `event`. Rejects with a timeout error
1569
+ * if `timeout` ms elapse first. Matches @tanstack/db semantics.
1570
+ */
1571
+ waitFor<K extends keyof CollectionEvents>(event: K, timeout?: number): Promise<CollectionEvents[K]>;
1572
+ /** List all column names in declaration order. */
1573
+ columnNames(): readonly string[];
1574
+ /** True when the collection has a soft-delete column active. */
1575
+ get hasSoftDelete(): boolean;
1576
+ /**
1577
+ * Expose underlying buffer views to the snapshot exporter. Rows are
1578
+ * emitted up to `rowCursor`, so consumers copy the *used* subregion
1579
+ * of each typed-array buffer (not the whole allocated capacity). This
1580
+ * keeps snapshots proportional to live data.
1581
+ */
1582
+ bulkColumnViews(): ReadonlyArray<{
1583
+ name: string;
1584
+ type: ColumnTypeName;
1585
+ typeCode: ColumnTypeCode;
1586
+ nullable: boolean;
1587
+ validity: Uint8Array | null;
1588
+ primaryBuffer: Uint8Array;
1589
+ heap: Uint8Array | null;
1590
+ dictionaryEntries: readonly string[] | null;
1591
+ }>;
1592
+ /**
1593
+ * Tree-shaped column view for the snapshot exporter. Mirrors the
1594
+ * compiled schema: list columns carry a `listChild` view; struct
1595
+ * columns carry a `fields` array. Each leaf view is slice-copied
1596
+ * up to the collection's current row cursor (for leaves) or list
1597
+ * child cursor (for list children) so the snapshot size is
1598
+ * proportional to live data.
1599
+ */
1600
+ bulkColumnViewsTree(): ReadonlyArray<TreeView>;
1601
+ private buildTreeView;
1602
+ /** Internal: restore the monotonic `globalVersion` after a snapshot import. */
1603
+ _restoreGlobalVersionForSnapshot(version: number): void;
1604
+ /**
1605
+ * Internal low-level scan view for the query kernel. Exposes raw
1606
+ * typed-array references + heap + dictionary so the kernel can read
1607
+ * values by (column, row ordinal) without allocating a row object.
1608
+ *
1609
+ * The returned arrays are live views into the collection's storage.
1610
+ * Do not mutate them. Their validity is bounded by the next mutation
1611
+ * that may resize the segment (today the segment capacity is fixed,
1612
+ * so views remain stable for the lifetime of the collection — but
1613
+ * this is an implementation detail that can change).
1614
+ */
1615
+ _internalScanColumns(): readonly ScanColumn[];
1616
+ /**
1617
+ * Internal: yield live row ordinals (respecting soft-delete) in PK
1618
+ * insertion order. The kernel iterates these to drive vectorized scans.
1619
+ */
1620
+ _internalLiveOrdinals(options?: {
1621
+ includeSoftDeleted?: boolean;
1622
+ }): IterableIterator<number>;
1623
+ /**
1624
+ * Internal: yield live row ordinals whose primary keys are in `keys`, preserving scan order.
1625
+ */
1626
+ _internalLiveOrdinalsForKeys(keys: ReadonlySet<number>): IterableIterator<number>;
1627
+ /** Search an attached geometry-envelope index. Returns row ordinals. */
1628
+ _internalSearchSpatialIndex(column: string, query: BBox): Uint32Array | undefined;
1629
+ /** Resolve a primary key to its current row ordinal without materializing a row. */
1630
+ _internalRowOrdinalForKey(key: number): number | undefined;
1631
+ /** Evaluate a bbox predicate directly against the cached geometry envelope. */
1632
+ _internalGeometryBboxMatches(column: string, row: number, query: BBox, mode: 'intersects' | 'within'): boolean;
1633
+ /** Evaluate point distance directly against coordinate buffers. */
1634
+ _internalPointDWithin(column: string, row: number, point: Point, meters: number): boolean;
1635
+ /**
1636
+ * Internal: read a single cell at (column, row) for the kernel. Used
1637
+ * to materialize projected rows only after filter + sort + limit
1638
+ * have produced a final ordinal list.
1639
+ */
1640
+ _internalReadCell(colName: string, row: number): RowValue[string];
1641
+ /**
1642
+ * Introspection view for devtools. Returns per-column metadata
1643
+ * (version, null count, heap usage, dictionary sample) without
1644
+ * exposing live buffers. `nullCount` walks the validity bitmap once
1645
+ * per nullable column — O(rowCursor) total. Safe to call on a hot
1646
+ * path but not a no-op.
1647
+ */
1648
+ describeColumnViews(): ReadonlyArray<{
1649
+ name: string;
1650
+ type: ColumnTypeName;
1651
+ nullable: boolean;
1652
+ version: number;
1653
+ nullCount: number;
1654
+ heap: {
1655
+ used: number;
1656
+ capacity: number;
1657
+ } | null;
1658
+ dictionaryEntries: readonly string[] | null;
1659
+ }>;
1660
+ insert(row: RowValue, config?: InsertConfig): Transaction<RowValue>;
1661
+ update(id: number, patch: Partial<RowValue>): Transaction<RowValue>;
1662
+ update(id: number, callback: (draft: RowValue) => void): Transaction<RowValue>;
1663
+ update(id: number, config: OperationConfig, callback: Partial<RowValue> | ((draft: RowValue) => void)): Transaction<RowValue>;
1664
+ delete(id: number, config?: OperationConfig): Transaction<RowValue>;
1665
+ private applyCollectionMutation;
1666
+ private registerTransactionRollback;
1667
+ private shouldConfirmSyncedUpdates;
1668
+ private callCollectionMutationHandler;
1669
+ private createPendingMutation;
1670
+ private resolveUpdatePatch;
1671
+ private patchFromCallback;
1672
+ private insertRaw;
1673
+ private updateRaw;
1674
+ private deleteRaw;
1675
+ get(id: number): RowValue | undefined;
1676
+ /**
1677
+ * Iterate rows as plain JS objects.
1678
+ *
1679
+ * By default, soft-deleted rows are excluded. Pass
1680
+ * `{ includeSoftDeleted: true }` to include them — useful for sync
1681
+ * adapters that want to mirror tombstones to downstream stores.
1682
+ */
1683
+ rows(options?: {
1684
+ includeSoftDeleted?: boolean;
1685
+ }): IterableIterator<RowValue>;
1686
+ /** Cached `Map<pk, row>` view. Built lazily on first read. */
1687
+ private _stateCache;
1688
+ /** `globalVersion` at the moment `_stateCache` was built. */
1689
+ private _stateCacheVersion;
1690
+ /** Cached dense `row[]` view. Built lazily on first read. */
1691
+ private _toArrayCache;
1692
+ /** `globalVersion` at the moment `_toArrayCache` was built. */
1693
+ private _toArrayCacheVersion;
1694
+ private _status;
1695
+ private _firstReadyListeners;
1696
+ private _firstReadyFired;
1697
+ /** Promises awaiting `preload()` / `stateWhenReady()` / etc. */
1698
+ private _readyPromise;
1699
+ private _readyResolve;
1700
+ /**
1701
+ * Current lifecycle status of the collection. For in-memory
1702
+ * collections this starts as `'ready'` and stays there until
1703
+ * `cleanup()` transitions to `'cleaned-up'`.
1704
+ */
1705
+ get status(): CollectionStatus;
1706
+ /** `true` iff status is `'ready'`. */
1707
+ isReady(): boolean;
1708
+ /**
1709
+ * Register a callback that fires exactly once, the first time the
1710
+ * collection becomes ready. If the collection is already ready, the
1711
+ * callback is invoked on the next microtask (never synchronously, so
1712
+ * ordering is predictable and matches @tanstack/db).
1713
+ *
1714
+ * Duplicate registrations are allowed; each registered callback
1715
+ * fires at most once.
1716
+ */
1717
+ onFirstReady(callback: () => void): void;
1718
+ /**
1719
+ * Internal helper for lifecycle machinery to mark the collection as
1720
+ * ready. Not exposed publicly — callers use the sync-config
1721
+ * `markReady` callback instead. For in-memory collections this is
1722
+ * invoked once during construction.
1723
+ */
1724
+ private _markReady;
1725
+ /**
1726
+ * Returns a promise that resolves when the collection is ready.
1727
+ * Resolves immediately if already ready. No-op for in-memory
1728
+ * collections after the first construction microtask.
1729
+ */
1730
+ preload(): Promise<void>;
1731
+ /**
1732
+ * Request eager synchronous start of any attached sync source. For
1733
+ * pure in-memory collections this is a no-op; the hook exists so
1734
+ * sync-backed subclasses / configs can override it without breaking
1735
+ * the TanStack surface.
1736
+ */
1737
+ startSyncImmediate(): void;
1738
+ private primaryKeyFromMessage;
1739
+ private patchFromSyncValue;
1740
+ private applySyncMessage;
1741
+ private truncateFromSync;
1742
+ /**
1743
+ * Resolves with a Map snapshot of the collection once ready. After
1744
+ * the collection is ready this is equivalent to reading `state`
1745
+ * (still reuses the lazy cache).
1746
+ */
1747
+ stateWhenReady(): Promise<Map<number, RowValue>>;
1748
+ /**
1749
+ * Resolves with a dense array snapshot once ready.
1750
+ */
1751
+ toArrayWhenReady(): Promise<RowValue[]>;
1752
+ /** Stable collection identifier. Matches @tanstack/db's `Collection.id`. */
1753
+ get id(): string;
1754
+ /**
1755
+ * Collection-scoped utility record. Callers can plumb helper
1756
+ * functions (e.g. `refetch`, `reset`, `prefetchPage`) via
1757
+ * `CollectionOptions.utils`. The getter returns the live record;
1758
+ * mutating it after construction is NOT recommended but not
1759
+ * forbidden (matches @tanstack/db).
1760
+ */
1761
+ get utils(): UtilsRecord;
1762
+ /**
1763
+ * String collation config for orderBy on string columns. Matches
1764
+ * `@tanstack/db`'s `Collection.compareOptions`. Defaults to
1765
+ * `{ stringSort: 'lexical' }` when not configured.
1766
+ */
1767
+ get compareOptions(): StringCollationConfig;
1768
+ /**
1769
+ * Whether a sync-layer subset load is in flight. Always `false`
1770
+ * for in-memory collections (no subset loading). Present for
1771
+ * @tanstack/db parity; sync-backed collections override.
1772
+ */
1773
+ get isLoadingSubset(): boolean;
1774
+ /** Secondary indexes attached to this collection. */
1775
+ get indexes(): ReadonlyMap<number, IndexInterface<number>>;
1776
+ createIndex(callback: IndexExpressionCallback, options?: CollectionIndexOptions): IndexInterface<number>;
1777
+ /**
1778
+ * Return the primary key value of a row-shaped item. Matches
1779
+ * `@tanstack/db`'s `Collection.getKeyFromItem(item)`. Reads the
1780
+ * schema's PK column from the given row.
1781
+ *
1782
+ * @throws ValidationError if the PK column is missing from `item`.
1783
+ */
1784
+ getKeyFromItem(item: Readonly<RowValue>): number;
1785
+ /**
1786
+ * Validate a data record against the collection schema. Matches
1787
+ * `@tanstack/db`'s `Collection.validateData(data, type, key?)`.
1788
+ *
1789
+ * For `'insert'`: every column declared in the schema must be
1790
+ * present (or nullable-null) and typed correctly.
1791
+ * For `'update'`: only provided columns are checked; the PK column
1792
+ * must NOT appear in the patch.
1793
+ *
1794
+ * Returns the validated data (same shape as input on success).
1795
+ * Throws `ValidationError` on failure — matches the reference's
1796
+ * `TOutput | never` return shape.
1797
+ */
1798
+ validateData(data: unknown, type: 'insert' | 'update', _key?: number): RowValue;
1799
+ /**
1800
+ * Release resources: detach every `subscribeChanges`/`on` listener,
1801
+ * drop cached state, clear the undo ring, transition status to
1802
+ * `'cleaned-up'`. Idempotent; subsequent mutations will still work
1803
+ * but no longer notify external subscribers.
1804
+ *
1805
+ * Matches `@tanstack/db`'s `Collection.cleanup()`. Async for
1806
+ * parity; the in-memory implementation completes after a single
1807
+ * microtask so `await cleanup()` returns on the next tick.
1808
+ */
1809
+ cleanup(): Promise<void>;
1810
+ /**
1811
+ * Return true if the collection contains a live (non-soft-deleted)
1812
+ * row with the given primary key.
1813
+ */
1814
+ has(id: number): boolean;
1815
+ /**
1816
+ * Iterate primary keys of live rows in insertion order.
1817
+ *
1818
+ * Matches `Map.prototype.keys()` shape.
1819
+ */
1820
+ keys(): IterableIterator<number>;
1821
+ /**
1822
+ * Iterate live row values. Identical to `rows()` with default
1823
+ * options — provided under the TanStack DB-compatible name.
1824
+ */
1825
+ values(): IterableIterator<RowValue>;
1826
+ /**
1827
+ * Iterate `[pk, row]` tuples for live rows.
1828
+ *
1829
+ * Matches `Map.prototype.entries()` shape.
1830
+ */
1831
+ entries(): IterableIterator<[number, RowValue]>;
1832
+ /**
1833
+ * Apply `callback(value, key, index)` to every live row. `index` is
1834
+ * the 0-based position in the live sequence (not the underlying row
1835
+ * slot).
1836
+ */
1837
+ forEach(callback: (value: RowValue, key: number, index: number) => void): void;
1838
+ /**
1839
+ * Like `Array.prototype.map`, but over live rows. Returns a dense
1840
+ * array. Matches `@tanstack/db` CollectionImpl.map.
1841
+ */
1842
+ map<U>(callback: (value: RowValue, key: number, index: number) => U): U[];
1843
+ /**
1844
+ * Map of live rows keyed by primary key. Materialized lazily on
1845
+ * first access and cached until the next mutation bumps
1846
+ * `globalVersion`.
1847
+ *
1848
+ * Reading `.state` N times between mutations builds the map once.
1849
+ * Never use it if you only need to iterate — `values()` / `rows()`
1850
+ * stream without materializing the Map.
1851
+ */
1852
+ /**
1853
+ * Lazily materialized snapshot of the live-row state as a
1854
+ * `Map<PK, row>`. Matches `@tanstack/db`'s `Collection.state` both
1855
+ * in shape and in semantics: the returned Map IS the internal
1856
+ * cache, not a clone — mutating it is undefined behavior (same
1857
+ * caveat as upstream). The cache is invalidated on every write,
1858
+ * so a fresh Map materializes lazily on the next read.
1859
+ *
1860
+ * The `Map` return type is widened (vs `ReadonlyMap`) for
1861
+ * TanStack parity; prefer `values()` / `entries()` / `has()` /
1862
+ * `get()` for mutation-proof access.
1863
+ */
1864
+ get state(): Map<number, RowValue>;
1865
+ /**
1866
+ * Dense array of live rows in insertion order. Materialized lazily
1867
+ * on first access and cached until the next mutation bumps
1868
+ * `globalVersion`.
1869
+ *
1870
+ * Matches `@tanstack/db`'s `Collection.toArray` shape and
1871
+ * semantics: the returned array IS the cache — mutating it is
1872
+ * undefined behavior. Prefer `values()` / `rows()` for iteration.
1873
+ *
1874
+ * Repeated reads between mutations are O(1).
1875
+ */
1876
+ get toArray(): RowValue[];
1877
+ /** Take a mark; use with `rollback(mark)` to undo everything after. */
1878
+ beginTransaction(): number;
1879
+ /**
1880
+ * Roll back all mutations that happened at or after `mark`, newest-first.
1881
+ * Throws `UndoError` if the ring has wrapped past `mark`.
1882
+ */
1883
+ rollback(mark: number): void;
1884
+ /**
1885
+ * Compact the collection:
1886
+ * 1. Drop any soft-deleted rows (they remain in the segment as zombies
1887
+ * until compact runs).
1888
+ * 2. Re-pack remaining live rows into a dense [0, liveCount) row slot
1889
+ * range, preserving their relative order by existing row index.
1890
+ * 3. Rebuild utf8/binary values heaps, discarding bytes that are not
1891
+ * referenced by a live row (reclaims space leaked by prior updates).
1892
+ * 4. Invalidate the undo ring (old row indices become meaningless).
1893
+ * 5. Bump all column versions + emit a single 'compact' ChangeEvent so
1894
+ * reactive queries recompute.
1895
+ *
1896
+ * Returns `{ reclaimedRows, reclaimedHeapBytes }` for observability.
1897
+ */
1898
+ compact(): {
1899
+ reclaimedRows: number;
1900
+ reclaimedHeapBytes: number;
1901
+ };
1902
+ _internalConfirmSyncedMutations(mutations: Array<PendingMutation<RowValue>>): void;
1903
+ private rollbackRecordToChange;
1904
+ private applyInverse;
1905
+ private initializeSpatialIndexes;
1906
+ private spatialBboxCache;
1907
+ private liveRowOrdinalsForSpatialIndex;
1908
+ private markSpatialRowDirty;
1909
+ private markSpatialRowDeleted;
1910
+ private rebuildSpatialIndexes;
1911
+ private rebuildSpatialIndexColumn;
1912
+ private addToIndexes;
1913
+ private removeFromIndexes;
1914
+ private updateIndexes;
1915
+ private rebuildIndexes;
1916
+ private isSoftDeletedValue;
1917
+ private writeCell;
1918
+ private readCell;
1919
+ private readBool;
1920
+ private writeListCell;
1921
+ private writeListElement;
1922
+ private readListCell;
1923
+ private listChildTypedBytes;
1924
+ private readListElement;
1925
+ private writeStructCell;
1926
+ private readStructCell;
1927
+ private snapshotRow;
1928
+ private coerceUint32;
1929
+ private coerceBoolNumber;
1930
+ }
1931
+
1932
+ export { type Point as $, Aggregate as A, type BasicExpression as B, Collection as C, type DeleteMutationFn as D, type SubscribeChangesOptions as E, type CollectionSubscription as F, type GroupBy as G, type Having as H, type InsertMutationFn as I, BaseIndex as J, IndexOperation as K, type LocalOnlyCollectionConfig as L, MaterializeWrapper as M, type RangeQueryOptions as N, type OrderBy as O, type PacedMutationsConfig as P, type QueueStrategyOptions as Q, type RowValue as R, type SyncConfig as S, type Transaction$1 as T, type UpdateMutationFn as U, type IndexInterface as V, type Where as W, type OrderByDirection as X, type IndexStats as Y, type CollectionStatus as Z, type BBox as _, type CompiledSchema as a, type StrategyOptions as a$, type OperatorName as a0, type ColumnTypeName as a1, type BaseStrategy as a2, type BatchStrategy as a3, type BatchStrategyOptions as a4, ChangeEmitter as a5, type ChangeEvent as a6, type ChangeListener as a7, type ChangeMessageOrDeleteKeyMessage as a8, type ChangeOp as a9, type JoinClause as aA, type Limit as aB, type LineString as aC, type LoadSubsetFn as aD, type LocalOnlyCollectionUtils as aE, type LocalStorageCollectionUtils as aF, type MutationFn as aG, type MutationFnParams as aH, type NamespacedRow as aI, type NonEmptyArray as aJ, type Offset as aK, type OperationConfig as aL, type OperationType as aM, type OptimisticChangeMessage as aN, type OrderByClause as aO, type Parser as aP, type PendingMutation as aQ, type Polygon as aR, QueryRef as aS, type Ref as aT, type RefLeaf as aU, type RefProxy as aV, type ResolveTransactionChanges as aW, type SchemaInput as aX, type StorageApi as aY, type StorageEventApi as aZ, type Strategy as a_, type ClearStorageFn as aa, type CollectionEvents as ab, type CollectionMutationFnParams as ac, type CollectionOptions as ad, CollectionRef as ae, type CollectionStatusChangeEvent as af, type CollectionSubscribersChangeEvent as ag, type CollectionTruncateEvent as ah, type ColumnDef as ai, ColumnTypeCode as aj, type CompiledColumn as ak, type CurrentStateAsChangesOptions as al, type Deferred as am, type DeleteKeyMessage as an, type DeleteMutationFnParams as ao, Dictionary as ap, type Fn as aq, type From as ar, Func as as, type GetStorageSizeFn as at, INCLUDES_SCALAR_FIELD as au, ir as av, type IndexOptions as aw, type InsertConfig as ax, type InsertMutationFnParams as ay, type Join as az, type IndexConstructor as b, Transaction as b0, type TransactionCollectionLike as b1, type TransactionConfig as b2, type TransactionState as b3, type TransactionWithMutations as b4, type UnloadSubsetFn as b5, type UpdateMutationFnParams as b6, Value as b7, type ValueOf as b8, ValuesHeap as b9, isDictionary as bA, isExpressionLike as bB, isNull as bC, isRefProxy as bD, isResidualWhere as bE, isUndefined as bF, isVariableWidth as bG, length as bH, like as bI, lower as bJ, lt as bK, lte as bL, materialize as bM, max as bN, min as bO, multiply as bP, not as bQ, operators as bR, or as bS, subtract as bT, sum as bU, toArray as bV, toExpression as bW, upper as bX, val as bY, type VirtualPropsRefProxy as ba, add as bb, and as bc, avg as bd, byteWidthOf as be, caseWhen as bf, coalesce as bg, comparisonFunctions as bh, concat as bi, count as bj, createRefProxy as bk, createRefProxyWithSelected as bl, createResidualWhere as bm, createSingleRowRefProxy as bn, createTransaction as bo, defineSchema as bp, divide as bq, eq as br, followRef as bs, getActiveTransaction as bt, getHavingExpression as bu, getWhereExpression as bv, gt as bw, gte as bx, ilike as by, inArray as bz, type CreateCollectionConfig as c, type CreateOptimisticActionsOptions as d, type DebounceStrategyOptions as e, type DebounceStrategy as f, type QueueStrategy as g, type ThrottleStrategyOptions as h, type ThrottleStrategy as i, type LocalOnlyCollectionOptionsResult as j, type LocalStorageCollectionConfig as k, type LocalStorageCollectionOptionsResult as l, type QueryIR as m, type Select as n, IncludesSubquery as o, type RootRefProxy as p, type SingleRowRefProxy as q, ToArrayWrapper as r, ConcatToArrayWrapper as s, type CompareOptions as t, PropRef as u, type IncludesMaterialization as v, type LoadSubsetOptions as w, type UtilsRecord as x, type StringCollationConfig as y, type ChangeMessage as z };