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.
- package/CHANGELOG.md +27 -0
- package/COMPATIBILITY.md +398 -0
- package/LICENSE +21 -0
- package/MIGRATING.md +238 -0
- package/README.md +897 -0
- package/RELEASE_NOTES.md +68 -0
- package/dist/arrow.d.ts +93 -0
- package/dist/arrow.js +5366 -0
- package/dist/arrow.js.map +1 -0
- package/dist/broadcast.d.ts +173 -0
- package/dist/broadcast.js +319 -0
- package/dist/broadcast.js.map +1 -0
- package/dist/collection-DGlKgOGi.d.ts +1932 -0
- package/dist/idb.d.ts +146 -0
- package/dist/idb.js +6193 -0
- package/dist/idb.js.map +1 -0
- package/dist/index.d.ts +1802 -0
- package/dist/index.js +13924 -0
- package/dist/index.js.map +1 -0
- package/dist/query-CzV9E57Y.d.ts +279 -0
- package/dist/react.d.ts +51 -0
- package/dist/react.js +1633 -0
- package/dist/react.js.map +1 -0
- package/dist/tanstack.d.ts +51 -0
- package/dist/tanstack.js +191 -0
- package/dist/tanstack.js.map +1 -0
- package/dist/types-CSoU6uED.d.ts +50 -0
- package/package.json +139 -0
|
@@ -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 };
|