@tanstack/db 0.2.3 → 0.2.5
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/dist/cjs/collection.cjs +23 -4
- package/dist/cjs/collection.cjs.map +1 -1
- package/dist/cjs/collection.d.cts +35 -41
- package/dist/cjs/local-only.cjs.map +1 -1
- package/dist/cjs/local-only.d.cts +17 -43
- package/dist/cjs/local-storage.cjs +3 -12
- package/dist/cjs/local-storage.cjs.map +1 -1
- package/dist/cjs/local-storage.d.cts +16 -39
- package/dist/cjs/query/builder/types.d.cts +12 -11
- package/dist/cjs/query/compiler/joins.cjs +4 -3
- package/dist/cjs/query/compiler/joins.cjs.map +1 -1
- package/dist/cjs/query/live/collection-subscriber.cjs +5 -1
- package/dist/cjs/query/live/collection-subscriber.cjs.map +1 -1
- package/dist/cjs/query/live-query-collection.cjs.map +1 -1
- package/dist/cjs/types.d.cts +10 -31
- package/dist/esm/collection.d.ts +35 -41
- package/dist/esm/collection.js +23 -4
- package/dist/esm/collection.js.map +1 -1
- package/dist/esm/local-only.d.ts +17 -43
- package/dist/esm/local-only.js.map +1 -1
- package/dist/esm/local-storage.d.ts +16 -39
- package/dist/esm/local-storage.js +3 -12
- package/dist/esm/local-storage.js.map +1 -1
- package/dist/esm/query/builder/types.d.ts +12 -11
- package/dist/esm/query/compiler/joins.js +4 -3
- package/dist/esm/query/compiler/joins.js.map +1 -1
- package/dist/esm/query/live/collection-subscriber.js +5 -1
- package/dist/esm/query/live/collection-subscriber.js.map +1 -1
- package/dist/esm/query/live-query-collection.js.map +1 -1
- package/dist/esm/types.d.ts +10 -31
- package/package.json +2 -2
- package/src/collection.ts +148 -196
- package/src/local-only.ts +57 -77
- package/src/local-storage.ts +53 -85
- package/src/query/builder/types.ts +52 -16
- package/src/query/compiler/joins.ts +4 -3
- package/src/query/live/collection-subscriber.ts +5 -1
- package/src/query/live-query-collection.ts +1 -1
- package/src/types.ts +25 -55
package/dist/esm/collection.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { IndexProxy } from './indexes/lazy-index.js';
|
|
|
4
4
|
import { Transaction } from './transactions.js';
|
|
5
5
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
6
|
import { SingleRowRefProxy } from './query/builder/ref-proxy.js';
|
|
7
|
-
import { ChangeListener, ChangeMessage, CollectionConfig, CollectionStatus, CurrentStateAsChangesOptions, Fn,
|
|
7
|
+
import { ChangeListener, ChangeMessage, CollectionConfig, CollectionStatus, CurrentStateAsChangesOptions, Fn, InferSchemaInput, InferSchemaOutput, InsertConfig, OperationConfig, OptimisticChangeMessage, SubscribeChangesOptions, Transaction as TransactionType, UtilsRecord, WritableDeep } from './types.js';
|
|
8
8
|
import { IndexOptions } from './indexes/index-options.js';
|
|
9
9
|
import { BaseIndex, IndexResolver } from './indexes/base-index.js';
|
|
10
10
|
interface PendingSyncedTransaction<T extends object = Record<string, unknown>> {
|
|
@@ -26,11 +26,9 @@ export interface Collection<T extends object = Record<string, unknown>, TKey ext
|
|
|
26
26
|
/**
|
|
27
27
|
* Creates a new Collection instance with the given configuration
|
|
28
28
|
*
|
|
29
|
-
* @template
|
|
29
|
+
* @template T - The schema type if a schema is provided, otherwise the type of items in the collection
|
|
30
30
|
* @template TKey - The type of the key for the collection
|
|
31
31
|
* @template TUtils - The utilities record type
|
|
32
|
-
* @template TSchema - The schema type for validation and type inference (second priority)
|
|
33
|
-
* @template TFallback - The fallback type if no explicit or schema type is provided
|
|
34
32
|
* @param options - Collection options with optional utilities
|
|
35
33
|
* @returns A new Collection with utilities exposed both at top level and under .utils
|
|
36
34
|
*
|
|
@@ -94,26 +92,22 @@ export interface Collection<T extends object = Record<string, unknown>, TKey ext
|
|
|
94
92
|
* sync: { sync: () => {} }
|
|
95
93
|
* })
|
|
96
94
|
*
|
|
97
|
-
* // Note: You can provide an explicit type, a schema, or both. When both are provided, the explicit type takes precedence.
|
|
98
95
|
*/
|
|
99
|
-
export declare function createCollection<
|
|
100
|
-
schema:
|
|
96
|
+
export declare function createCollection<T extends StandardSchemaV1, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}>(options: CollectionConfig<InferSchemaOutput<T>, TKey, T> & {
|
|
97
|
+
schema: T;
|
|
101
98
|
utils?: TUtils;
|
|
102
|
-
}): Collection<
|
|
103
|
-
export declare function createCollection<
|
|
104
|
-
schema
|
|
99
|
+
}): Collection<InferSchemaOutput<T>, TKey, TUtils, T, InferSchemaInput<T>>;
|
|
100
|
+
export declare function createCollection<T extends object, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}>(options: CollectionConfig<T, TKey, never> & {
|
|
101
|
+
schema?: never;
|
|
105
102
|
utils?: TUtils;
|
|
106
|
-
}): Collection<
|
|
107
|
-
export declare
|
|
108
|
-
|
|
109
|
-
}): Collection<ResolveType<TExplicit, TSchema, TFallback>, TKey, TUtils, TSchema, ResolveInsertInput<TExplicit, TSchema, TFallback>>;
|
|
110
|
-
export declare class CollectionImpl<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}, TSchema extends StandardSchemaV1 = StandardSchemaV1, TInsertInput extends object = T> {
|
|
111
|
-
config: CollectionConfig<T, TKey, TSchema, TInsertInput>;
|
|
103
|
+
}): Collection<T, TKey, TUtils, never, T>;
|
|
104
|
+
export declare class CollectionImpl<TOutput extends object = Record<string, unknown>, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}, TSchema extends StandardSchemaV1 = StandardSchemaV1, TInput extends object = TOutput> {
|
|
105
|
+
config: CollectionConfig<TOutput, TKey, TSchema>;
|
|
112
106
|
transactions: SortedMap<string, Transaction<any>>;
|
|
113
|
-
pendingSyncedTransactions: Array<PendingSyncedTransaction<
|
|
114
|
-
syncedData: Map<TKey,
|
|
107
|
+
pendingSyncedTransactions: Array<PendingSyncedTransaction<TOutput>>;
|
|
108
|
+
syncedData: Map<TKey, TOutput> | SortedMap<TKey, TOutput>;
|
|
115
109
|
syncedMetadata: Map<TKey, unknown>;
|
|
116
|
-
optimisticUpserts: Map<TKey,
|
|
110
|
+
optimisticUpserts: Map<TKey, TOutput>;
|
|
117
111
|
optimisticDeletes: Set<TKey>;
|
|
118
112
|
private _size;
|
|
119
113
|
private lazyIndexes;
|
|
@@ -194,7 +188,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
194
188
|
* @param config - Configuration object for the collection
|
|
195
189
|
* @throws Error if sync config is missing
|
|
196
190
|
*/
|
|
197
|
-
constructor(config: CollectionConfig<
|
|
191
|
+
constructor(config: CollectionConfig<TOutput, TKey, TSchema>);
|
|
198
192
|
/**
|
|
199
193
|
* Start sync immediately - internal method for compiled queries
|
|
200
194
|
* This bypasses lazy loading for special cases like live query results
|
|
@@ -261,7 +255,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
261
255
|
/**
|
|
262
256
|
* Get the current value for a key (virtual derived state)
|
|
263
257
|
*/
|
|
264
|
-
get(key: TKey):
|
|
258
|
+
get(key: TKey): TOutput | undefined;
|
|
265
259
|
/**
|
|
266
260
|
* Check if a key exists in the collection (virtual derived state)
|
|
267
261
|
*/
|
|
@@ -277,23 +271,23 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
277
271
|
/**
|
|
278
272
|
* Get all values (virtual derived state)
|
|
279
273
|
*/
|
|
280
|
-
values(): IterableIterator<
|
|
274
|
+
values(): IterableIterator<TOutput>;
|
|
281
275
|
/**
|
|
282
276
|
* Get all entries (virtual derived state)
|
|
283
277
|
*/
|
|
284
|
-
entries(): IterableIterator<[TKey,
|
|
278
|
+
entries(): IterableIterator<[TKey, TOutput]>;
|
|
285
279
|
/**
|
|
286
280
|
* Get all entries (virtual derived state)
|
|
287
281
|
*/
|
|
288
|
-
[Symbol.iterator](): IterableIterator<[TKey,
|
|
282
|
+
[Symbol.iterator](): IterableIterator<[TKey, TOutput]>;
|
|
289
283
|
/**
|
|
290
284
|
* Execute a callback for each entry in the collection
|
|
291
285
|
*/
|
|
292
|
-
forEach(callbackfn: (value:
|
|
286
|
+
forEach(callbackfn: (value: TOutput, key: TKey, index: number) => void): void;
|
|
293
287
|
/**
|
|
294
288
|
* Create a new array with the results of calling a function for each entry in the collection
|
|
295
289
|
*/
|
|
296
|
-
map<U>(callbackfn: (value:
|
|
290
|
+
map<U>(callbackfn: (value: TOutput, key: TKey, index: number) => U): Array<U>;
|
|
297
291
|
/**
|
|
298
292
|
* Attempts to commit pending synced transactions if there are no active transactions
|
|
299
293
|
* This method processes operations from pending transactions and applies them to the synced data
|
|
@@ -305,7 +299,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
305
299
|
*/
|
|
306
300
|
private scheduleTransactionCleanup;
|
|
307
301
|
private ensureStandardSchema;
|
|
308
|
-
getKeyFromItem(item:
|
|
302
|
+
getKeyFromItem(item: TOutput): TKey;
|
|
309
303
|
generateGlobalKey(key: any, item: any): string;
|
|
310
304
|
/**
|
|
311
305
|
* Creates an index on a collection for faster queries.
|
|
@@ -337,7 +331,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
337
331
|
* options: { language: 'en' }
|
|
338
332
|
* })
|
|
339
333
|
*/
|
|
340
|
-
createIndex<TResolver extends IndexResolver<TKey> = typeof BTreeIndex>(indexCallback: (row: SingleRowRefProxy<
|
|
334
|
+
createIndex<TResolver extends IndexResolver<TKey> = typeof BTreeIndex>(indexCallback: (row: SingleRowRefProxy<TOutput>) => any, config?: IndexOptions<TResolver>): IndexProxy<TKey>;
|
|
341
335
|
/**
|
|
342
336
|
* Resolve all lazy indexes (called when collection first syncs)
|
|
343
337
|
* @private
|
|
@@ -357,7 +351,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
357
351
|
* @private
|
|
358
352
|
*/
|
|
359
353
|
private updateIndexes;
|
|
360
|
-
validateData(data: unknown, type: `insert` | `update`, key?: TKey):
|
|
354
|
+
validateData(data: unknown, type: `insert` | `update`, key?: TKey): TOutput | never;
|
|
361
355
|
/**
|
|
362
356
|
* Inserts one or more items into the collection
|
|
363
357
|
* @param items - Single item or array of items to insert
|
|
@@ -394,7 +388,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
394
388
|
* console.log('Insert failed:', error)
|
|
395
389
|
* }
|
|
396
390
|
*/
|
|
397
|
-
insert: (data:
|
|
391
|
+
insert: (data: TInput | Array<TInput>, config?: InsertConfig) => Transaction<Record<string, unknown>> | Transaction<TOutput>;
|
|
398
392
|
/**
|
|
399
393
|
* Updates one or more items in the collection using a callback function
|
|
400
394
|
* @param keys - Single key or array of keys to update
|
|
@@ -434,10 +428,10 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
434
428
|
* console.log('Update failed:', error)
|
|
435
429
|
* }
|
|
436
430
|
*/
|
|
437
|
-
update
|
|
438
|
-
update
|
|
439
|
-
update
|
|
440
|
-
update
|
|
431
|
+
update(key: Array<TKey | unknown>, callback: (drafts: Array<WritableDeep<TInput>>) => void): TransactionType;
|
|
432
|
+
update(keys: Array<TKey | unknown>, config: OperationConfig, callback: (drafts: Array<WritableDeep<TInput>>) => void): TransactionType;
|
|
433
|
+
update(id: TKey | unknown, callback: (draft: WritableDeep<TInput>) => void): TransactionType;
|
|
434
|
+
update(id: TKey | unknown, config: OperationConfig, callback: (draft: WritableDeep<TInput>) => void): TransactionType;
|
|
441
435
|
/**
|
|
442
436
|
* Deletes one or more items from the collection
|
|
443
437
|
* @param keys - Single key or array of keys to delete
|
|
@@ -485,27 +479,27 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
485
479
|
* console.log("Todo 1 exists:", itemsMap.get("todo-1"))
|
|
486
480
|
* }
|
|
487
481
|
*/
|
|
488
|
-
get state(): Map<TKey,
|
|
482
|
+
get state(): Map<TKey, TOutput>;
|
|
489
483
|
/**
|
|
490
484
|
* Gets the current state of the collection as a Map, but only resolves when data is available
|
|
491
485
|
* Waits for the first sync commit to complete before resolving
|
|
492
486
|
*
|
|
493
487
|
* @returns Promise that resolves to a Map containing all items in the collection
|
|
494
488
|
*/
|
|
495
|
-
stateWhenReady(): Promise<Map<TKey,
|
|
489
|
+
stateWhenReady(): Promise<Map<TKey, TOutput>>;
|
|
496
490
|
/**
|
|
497
491
|
* Gets the current state of the collection as an Array
|
|
498
492
|
*
|
|
499
493
|
* @returns An Array containing all items in the collection
|
|
500
494
|
*/
|
|
501
|
-
get toArray():
|
|
495
|
+
get toArray(): TOutput[];
|
|
502
496
|
/**
|
|
503
497
|
* Gets the current state of the collection as an Array, but only resolves when data is available
|
|
504
498
|
* Waits for the first sync commit to complete before resolving
|
|
505
499
|
*
|
|
506
500
|
* @returns Promise that resolves to an Array containing all items in the collection
|
|
507
501
|
*/
|
|
508
|
-
toArrayWhenReady(): Promise<Array<
|
|
502
|
+
toArrayWhenReady(): Promise<Array<TOutput>>;
|
|
509
503
|
/**
|
|
510
504
|
* Returns the current state of the collection as an array of changes
|
|
511
505
|
* @param options - Options including optional where filter
|
|
@@ -524,7 +518,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
524
518
|
* whereExpression: eq(row.status, 'active')
|
|
525
519
|
* })
|
|
526
520
|
*/
|
|
527
|
-
currentStateAsChanges(options?: CurrentStateAsChangesOptions<
|
|
521
|
+
currentStateAsChanges(options?: CurrentStateAsChangesOptions<TOutput>): Array<ChangeMessage<TOutput>>;
|
|
528
522
|
/**
|
|
529
523
|
* Subscribe to changes in the collection
|
|
530
524
|
* @param callback - Function called when items change
|
|
@@ -564,11 +558,11 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
564
558
|
* whereExpression: eq(row.status, 'active')
|
|
565
559
|
* })
|
|
566
560
|
*/
|
|
567
|
-
subscribeChanges(callback: (changes: Array<ChangeMessage<
|
|
561
|
+
subscribeChanges(callback: (changes: Array<ChangeMessage<TOutput>>) => void, options?: SubscribeChangesOptions<TOutput>): () => void;
|
|
568
562
|
/**
|
|
569
563
|
* Subscribe to changes for a specific key
|
|
570
564
|
*/
|
|
571
|
-
subscribeChangesKey(key: TKey, listener: ChangeListener<
|
|
565
|
+
subscribeChangesKey(key: TKey, listener: ChangeListener<TOutput, TKey>, { includeInitialState }?: {
|
|
572
566
|
includeInitialState?: boolean;
|
|
573
567
|
}): () => void;
|
|
574
568
|
/**
|
package/dist/esm/collection.js
CHANGED
|
@@ -9,7 +9,9 @@ import { getActiveTransaction, createTransaction } from "./transactions.js";
|
|
|
9
9
|
import { MissingInsertHandlerError, DuplicateKeyError, MissingDeleteHandlerError, NoKeysPassedToDeleteError, DeleteKeyNotFoundError, CollectionRequiresConfigError, CollectionRequiresSyncConfigError, CollectionInErrorStateError, InvalidCollectionStatusTransitionError, NoPendingSyncTransactionWriteError, SyncTransactionAlreadyCommittedWriteError, NoPendingSyncTransactionCommitError, SyncTransactionAlreadyCommittedError, DuplicateKeySyncError, CollectionIsInErrorStateError, SyncCleanupError, NegativeActiveSubscribersError, InvalidSchemaError, UndefinedKeyError, SchemaMustBeSynchronousError, SchemaValidationError, MissingUpdateArgumentError, MissingUpdateHandlerError, NoKeysPassedToUpdateError, UpdateKeyNotFoundError, KeyUpdateNotAllowedError } from "./errors.js";
|
|
10
10
|
import { currentStateAsChanges, createFilteredCallback } from "./change-events.js";
|
|
11
11
|
function createCollection(options) {
|
|
12
|
-
const collection = new CollectionImpl(
|
|
12
|
+
const collection = new CollectionImpl(
|
|
13
|
+
options
|
|
14
|
+
);
|
|
13
15
|
if (options.utils) {
|
|
14
16
|
collection.utils = { ...options.utils };
|
|
15
17
|
} else {
|
|
@@ -802,7 +804,10 @@ class CollectionImpl {
|
|
|
802
804
|
switch (mutation.type) {
|
|
803
805
|
case `insert`:
|
|
804
806
|
case `update`:
|
|
805
|
-
this.optimisticUpserts.set(
|
|
807
|
+
this.optimisticUpserts.set(
|
|
808
|
+
mutation.key,
|
|
809
|
+
mutation.modified
|
|
810
|
+
);
|
|
806
811
|
this.optimisticDeletes.delete(mutation.key);
|
|
807
812
|
break;
|
|
808
813
|
case `delete`:
|
|
@@ -1234,7 +1239,12 @@ class CollectionImpl {
|
|
|
1234
1239
|
});
|
|
1235
1240
|
throw new SchemaValidationError(type, typedIssues);
|
|
1236
1241
|
}
|
|
1237
|
-
|
|
1242
|
+
const validatedMergedData = result2.value;
|
|
1243
|
+
const modifiedKeys = Object.keys(data);
|
|
1244
|
+
const extractedChanges = Object.fromEntries(
|
|
1245
|
+
modifiedKeys.map((k) => [k, validatedMergedData[k]])
|
|
1246
|
+
);
|
|
1247
|
+
return extractedChanges;
|
|
1238
1248
|
}
|
|
1239
1249
|
}
|
|
1240
1250
|
const result = standardSchema[`~standard`].validate(data);
|
|
@@ -1315,7 +1325,16 @@ class CollectionImpl {
|
|
|
1315
1325
|
mutationId: crypto.randomUUID(),
|
|
1316
1326
|
original: originalItem,
|
|
1317
1327
|
modified: modifiedItem,
|
|
1318
|
-
|
|
1328
|
+
// Pick the values from modifiedItem based on what's passed in - this is for cases
|
|
1329
|
+
// where a schema has default values or transforms. The modified data has the extra
|
|
1330
|
+
// default or transformed values but for changes, we just want to show the data that
|
|
1331
|
+
// was actually passed in.
|
|
1332
|
+
changes: Object.fromEntries(
|
|
1333
|
+
Object.keys(itemChanges).map((k) => [
|
|
1334
|
+
k,
|
|
1335
|
+
modifiedItem[k]
|
|
1336
|
+
])
|
|
1337
|
+
),
|
|
1319
1338
|
globalKey,
|
|
1320
1339
|
key,
|
|
1321
1340
|
metadata: config.metadata,
|