@tanstack/db 0.0.21 → 0.0.23
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 +14 -6
- package/dist/cjs/collection.cjs.map +1 -1
- package/dist/cjs/collection.d.cts +10 -9
- package/dist/cjs/local-storage.cjs +1 -1
- package/dist/cjs/local-storage.cjs.map +1 -1
- package/dist/cjs/query/builder/index.cjs +20 -0
- package/dist/cjs/query/builder/index.cjs.map +1 -1
- package/dist/cjs/query/builder/index.d.cts +15 -0
- package/dist/cjs/query/compiler/index.cjs +6 -0
- package/dist/cjs/query/compiler/index.cjs.map +1 -1
- package/dist/cjs/query/ir.cjs.map +1 -1
- package/dist/cjs/query/ir.d.cts +1 -0
- package/dist/cjs/transactions.cjs.map +1 -1
- package/dist/cjs/transactions.d.cts +5 -5
- package/dist/cjs/types.d.cts +35 -10
- package/dist/esm/collection.d.ts +10 -9
- package/dist/esm/collection.js +14 -6
- package/dist/esm/collection.js.map +1 -1
- package/dist/esm/local-storage.js +1 -1
- package/dist/esm/local-storage.js.map +1 -1
- package/dist/esm/query/builder/index.d.ts +15 -0
- package/dist/esm/query/builder/index.js +20 -0
- package/dist/esm/query/builder/index.js.map +1 -1
- package/dist/esm/query/compiler/index.js +7 -1
- package/dist/esm/query/compiler/index.js.map +1 -1
- package/dist/esm/query/ir.d.ts +1 -0
- package/dist/esm/query/ir.js.map +1 -1
- package/dist/esm/transactions.d.ts +5 -5
- package/dist/esm/transactions.js.map +1 -1
- package/dist/esm/types.d.ts +35 -10
- package/package.json +2 -2
- package/src/collection.ts +62 -21
- package/src/local-storage.ts +2 -2
- package/src/query/builder/index.ts +21 -0
- package/src/query/compiler/index.ts +11 -2
- package/src/query/ir.ts +1 -0
- package/src/transactions.ts +8 -12
- package/src/types.ts +69 -14
package/dist/cjs/types.d.cts
CHANGED
|
@@ -8,6 +8,24 @@ import { Transaction } from './transactions.cjs';
|
|
|
8
8
|
* @internal This is used by the type resolution system
|
|
9
9
|
*/
|
|
10
10
|
export type InferSchemaOutput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> extends object ? StandardSchemaV1.InferOutput<T> : Record<string, unknown> : Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Helper type to extract the input type from a standard schema
|
|
13
|
+
*
|
|
14
|
+
* @internal This is used for collection insert type inference
|
|
15
|
+
*/
|
|
16
|
+
export type InferSchemaInput<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferInput<T> extends object ? StandardSchemaV1.InferInput<T> : Record<string, unknown> : Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Helper type to determine the insert input type
|
|
19
|
+
* This takes the raw generics (TExplicit, TSchema, TFallback) instead of the resolved T.
|
|
20
|
+
*
|
|
21
|
+
* Priority:
|
|
22
|
+
* 1. Explicit generic TExplicit (if not 'unknown')
|
|
23
|
+
* 2. Schema input type (if schema provided)
|
|
24
|
+
* 3. Fallback type TFallback
|
|
25
|
+
*
|
|
26
|
+
* @internal This is used for collection insert type inference
|
|
27
|
+
*/
|
|
28
|
+
export type ResolveInsertInput<TExplicit = unknown, TSchema extends StandardSchemaV1 = never, TFallback extends object = Record<string, unknown>> = unknown extends TExplicit ? [TSchema] extends [never] ? TFallback : InferSchemaInput<TSchema> : TExplicit extends object ? TExplicit : Record<string, unknown>;
|
|
11
29
|
/**
|
|
12
30
|
* Helper type to determine the final type based on priority:
|
|
13
31
|
* 1. Explicit generic TExplicit (if not 'unknown')
|
|
@@ -28,25 +46,32 @@ export type Fn = (...args: Array<any>) => any;
|
|
|
28
46
|
* A record of utility functions that can be attached to a collection
|
|
29
47
|
*/
|
|
30
48
|
export type UtilsRecord = Record<string, Fn>;
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @remarks `update` and `insert` are both represented as `Partial<T>`, but changes for `insert` could me made more precise by inferring the schema input type. In practice, this has almost 0 real world impact so it's not worth the added type complexity.
|
|
52
|
+
*
|
|
53
|
+
* @see https://github.com/TanStack/db/pull/209#issuecomment-3053001206
|
|
54
|
+
*/
|
|
55
|
+
export type ResolveTransactionChanges<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType> = TOperation extends `delete` ? T : Partial<T>;
|
|
31
56
|
/**
|
|
32
57
|
* Represents a pending mutation within a transaction
|
|
33
58
|
* Contains information about the original and modified data, as well as metadata
|
|
34
59
|
*/
|
|
35
|
-
export interface PendingMutation<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType> {
|
|
60
|
+
export interface PendingMutation<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType, TCollection extends Collection<T, any, any, any, any> = Collection<T, any, any, any, any>> {
|
|
36
61
|
mutationId: string;
|
|
37
62
|
original: TOperation extends `insert` ? {} : T;
|
|
38
63
|
modified: T;
|
|
39
|
-
changes:
|
|
64
|
+
changes: ResolveTransactionChanges<T, TOperation>;
|
|
40
65
|
globalKey: string;
|
|
41
66
|
key: any;
|
|
42
|
-
type:
|
|
67
|
+
type: TOperation;
|
|
43
68
|
metadata: unknown;
|
|
44
69
|
syncMetadata: Record<string, unknown>;
|
|
45
70
|
/** Whether this mutation should be applied optimistically (defaults to true) */
|
|
46
71
|
optimistic: boolean;
|
|
47
72
|
createdAt: Date;
|
|
48
73
|
updatedAt: Date;
|
|
49
|
-
collection:
|
|
74
|
+
collection: TCollection;
|
|
50
75
|
}
|
|
51
76
|
/**
|
|
52
77
|
* Configuration options for creating a new transaction
|
|
@@ -63,7 +88,7 @@ export type NonEmptyArray<T> = [T, ...Array<T>];
|
|
|
63
88
|
* Utility type for a Transaction with at least one mutation
|
|
64
89
|
* This is used internally by the Transaction.commit method
|
|
65
90
|
*/
|
|
66
|
-
export type TransactionWithMutations<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType> = Transaction<T
|
|
91
|
+
export type TransactionWithMutations<T extends object = Record<string, unknown>, TOperation extends OperationType = OperationType> = Transaction<T> & {
|
|
67
92
|
mutations: NonEmptyArray<PendingMutation<T, TOperation>>;
|
|
68
93
|
};
|
|
69
94
|
export interface TransactionConfig<T extends object = Record<string, unknown>> {
|
|
@@ -77,11 +102,11 @@ export interface TransactionConfig<T extends object = Record<string, unknown>> {
|
|
|
77
102
|
/**
|
|
78
103
|
* Options for the createOptimisticAction helper
|
|
79
104
|
*/
|
|
80
|
-
export interface CreateOptimisticActionsOptions<TVars = unknown
|
|
105
|
+
export interface CreateOptimisticActionsOptions<TVars = unknown, T extends object = Record<string, unknown>> extends Omit<TransactionConfig<T>, `mutationFn`> {
|
|
81
106
|
/** Function to apply optimistic updates locally before the mutation completes */
|
|
82
107
|
onMutate: (vars: TVars) => void;
|
|
83
108
|
/** Function to execute the mutation on the server */
|
|
84
|
-
mutationFn: (vars: TVars, params: MutationFnParams) => Promise<any>;
|
|
109
|
+
mutationFn: (vars: TVars, params: MutationFnParams<T>) => Promise<any>;
|
|
85
110
|
}
|
|
86
111
|
export type { Transaction };
|
|
87
112
|
type Value<TExtensions = never> = string | number | boolean | bigint | null | TExtensions | Array<Value<TExtensions>> | {
|
|
@@ -91,7 +116,7 @@ export type Row<TExtensions = never> = Record<string, Value<TExtensions>>;
|
|
|
91
116
|
export type OperationType = `insert` | `update` | `delete`;
|
|
92
117
|
export interface SyncConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number> {
|
|
93
118
|
sync: (params: {
|
|
94
|
-
collection: Collection<T, TKey>;
|
|
119
|
+
collection: Collection<T, TKey, any, any, any>;
|
|
95
120
|
begin: () => void;
|
|
96
121
|
write: (message: Omit<ChangeMessage<T>, `key`>) => void;
|
|
97
122
|
commit: () => void;
|
|
@@ -189,7 +214,7 @@ export type CollectionStatus =
|
|
|
189
214
|
| `error`
|
|
190
215
|
/** Collection has been cleaned up and resources freed */
|
|
191
216
|
| `cleaned-up`;
|
|
192
|
-
export interface CollectionConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TSchema extends StandardSchemaV1 = StandardSchemaV1> {
|
|
217
|
+
export interface CollectionConfig<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TSchema extends StandardSchemaV1 = StandardSchemaV1, TInsertInput extends object = T> {
|
|
193
218
|
id?: string;
|
|
194
219
|
sync: SyncConfig<T, TKey>;
|
|
195
220
|
schema?: TSchema;
|
|
@@ -265,7 +290,7 @@ export interface CollectionConfig<T extends object = Record<string, unknown>, TK
|
|
|
265
290
|
* })
|
|
266
291
|
* }
|
|
267
292
|
*/
|
|
268
|
-
onInsert?: InsertMutationFn<
|
|
293
|
+
onInsert?: InsertMutationFn<TInsertInput, TKey>;
|
|
269
294
|
/**
|
|
270
295
|
* Optional asynchronous handler function called before an update operation
|
|
271
296
|
* @param params Object containing transaction and collection information
|
package/dist/esm/collection.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SortedMap } from './SortedMap.js';
|
|
2
2
|
import { Transaction } from './transactions.js';
|
|
3
|
-
import { ChangeListener, ChangeMessage, CollectionConfig, CollectionStatus, Fn, InsertConfig, OperationConfig, OptimisticChangeMessage, ResolveType, Transaction as TransactionType, UtilsRecord } from './types.js';
|
|
3
|
+
import { ChangeListener, ChangeMessage, CollectionConfig, CollectionStatus, Fn, InsertConfig, OperationConfig, OptimisticChangeMessage, ResolveInsertInput, ResolveType, Transaction as TransactionType, UtilsRecord } from './types.js';
|
|
4
4
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
5
|
-
export declare const collectionsStore: Map<string, CollectionImpl<any, any,
|
|
5
|
+
export declare const collectionsStore: Map<string, CollectionImpl<any, any, any, StandardSchemaV1<unknown, unknown>, any>>;
|
|
6
6
|
interface PendingSyncedTransaction<T extends object = Record<string, unknown>> {
|
|
7
7
|
committed: boolean;
|
|
8
8
|
operations: Array<OptimisticChangeMessage<T>>;
|
|
@@ -12,8 +12,9 @@ interface PendingSyncedTransaction<T extends object = Record<string, unknown>> {
|
|
|
12
12
|
* @template T - The type of items in the collection
|
|
13
13
|
* @template TKey - The type of the key for the collection
|
|
14
14
|
* @template TUtils - The utilities record type
|
|
15
|
+
* @template TInsertInput - The type for insert operations (can be different from T for schemas with defaults)
|
|
15
16
|
*/
|
|
16
|
-
export interface Collection<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}> extends CollectionImpl<T, TKey> {
|
|
17
|
+
export interface Collection<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}, TSchema extends StandardSchemaV1 = StandardSchemaV1, TInsertInput extends object = T> extends CollectionImpl<T, TKey, TUtils, TSchema, TInsertInput> {
|
|
17
18
|
readonly utils: TUtils;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
@@ -89,9 +90,9 @@ export interface Collection<T extends object = Record<string, unknown>, TKey ext
|
|
|
89
90
|
*
|
|
90
91
|
* // Note: You must provide either an explicit type or a schema, but not both.
|
|
91
92
|
*/
|
|
92
|
-
export declare function createCollection<TExplicit = unknown, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}, TSchema extends StandardSchemaV1 = StandardSchemaV1, TFallback extends object = Record<string, unknown>>(options: CollectionConfig<ResolveType<TExplicit, TSchema, TFallback>, TKey, TSchema
|
|
93
|
+
export declare function createCollection<TExplicit = unknown, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}, TSchema extends StandardSchemaV1 = StandardSchemaV1, TFallback extends object = Record<string, unknown>>(options: CollectionConfig<ResolveType<TExplicit, TSchema, TFallback>, TKey, TSchema, ResolveInsertInput<TExplicit, TSchema, TFallback>> & {
|
|
93
94
|
utils?: TUtils;
|
|
94
|
-
}): Collection<ResolveType<TExplicit, TSchema, TFallback>, TKey, TUtils
|
|
95
|
+
}): Collection<ResolveType<TExplicit, TSchema, TFallback>, TKey, TUtils, TSchema, ResolveInsertInput<TExplicit, TSchema, TFallback>>;
|
|
95
96
|
/**
|
|
96
97
|
* Custom error class for schema validation errors
|
|
97
98
|
*/
|
|
@@ -106,8 +107,8 @@ export declare class SchemaValidationError extends Error {
|
|
|
106
107
|
path?: ReadonlyArray<string | number | symbol>;
|
|
107
108
|
}>, message?: string);
|
|
108
109
|
}
|
|
109
|
-
export declare class CollectionImpl<T extends object = Record<string, unknown>, TKey extends string | number = string | number, TUtils extends UtilsRecord = {}> {
|
|
110
|
-
config: CollectionConfig<T, TKey,
|
|
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>;
|
|
111
112
|
transactions: SortedMap<string, Transaction<any>>;
|
|
112
113
|
pendingSyncedTransactions: Array<PendingSyncedTransaction<T>>;
|
|
113
114
|
syncedData: Map<TKey, T> | SortedMap<TKey, T>;
|
|
@@ -168,7 +169,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
168
169
|
* @param config - Configuration object for the collection
|
|
169
170
|
* @throws Error if sync config is missing
|
|
170
171
|
*/
|
|
171
|
-
constructor(config: CollectionConfig<T, TKey,
|
|
172
|
+
constructor(config: CollectionConfig<T, TKey, TSchema, TInsertInput>);
|
|
172
173
|
/**
|
|
173
174
|
* Start sync immediately - internal method for compiled queries
|
|
174
175
|
* This bypasses lazy loading for special cases like live query results
|
|
@@ -309,7 +310,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
309
310
|
* console.log('Insert failed:', error)
|
|
310
311
|
* }
|
|
311
312
|
*/
|
|
312
|
-
insert: (data:
|
|
313
|
+
insert: (data: TInsertInput | Array<TInsertInput>, config?: InsertConfig) => Transaction<Record<string, unknown>> | Transaction<T>;
|
|
313
314
|
/**
|
|
314
315
|
* Updates one or more items in the collection using a callback function
|
|
315
316
|
* @param keys - Single key or array of keys to update
|
package/dist/esm/collection.js
CHANGED
|
@@ -218,7 +218,7 @@ class CollectionImpl {
|
|
|
218
218
|
items.forEach((item) => {
|
|
219
219
|
var _a, _b;
|
|
220
220
|
const validatedData = this.validateData(item, `insert`);
|
|
221
|
-
const key = this.getKeyFromItem(
|
|
221
|
+
const key = this.getKeyFromItem(validatedData);
|
|
222
222
|
if (this.has(key)) {
|
|
223
223
|
throw `Cannot insert document with ID "${key}" because it already exists in the collection`;
|
|
224
224
|
}
|
|
@@ -227,7 +227,15 @@ class CollectionImpl {
|
|
|
227
227
|
mutationId: crypto.randomUUID(),
|
|
228
228
|
original: {},
|
|
229
229
|
modified: validatedData,
|
|
230
|
-
|
|
230
|
+
// Pick the values from validatedData based on what's passed in - this is for cases
|
|
231
|
+
// where a schema has default values. The validated data has the extra default
|
|
232
|
+
// values but for changes, we just want to show the data that was actually passed in.
|
|
233
|
+
changes: Object.fromEntries(
|
|
234
|
+
Object.keys(item).map((k) => [
|
|
235
|
+
k,
|
|
236
|
+
validatedData[k]
|
|
237
|
+
])
|
|
238
|
+
),
|
|
231
239
|
globalKey,
|
|
232
240
|
key,
|
|
233
241
|
metadata: config2 == null ? void 0 : config2.metadata,
|
|
@@ -248,8 +256,8 @@ class CollectionImpl {
|
|
|
248
256
|
} else {
|
|
249
257
|
const directOpTransaction = createTransaction({
|
|
250
258
|
mutationFn: async (params) => {
|
|
251
|
-
return this.config.onInsert({
|
|
252
|
-
|
|
259
|
+
return await this.config.onInsert({
|
|
260
|
+
transaction: params.transaction,
|
|
253
261
|
collection: this
|
|
254
262
|
});
|
|
255
263
|
}
|
|
@@ -308,7 +316,7 @@ class CollectionImpl {
|
|
|
308
316
|
autoCommit: true,
|
|
309
317
|
mutationFn: async (params) => {
|
|
310
318
|
return this.config.onDelete({
|
|
311
|
-
|
|
319
|
+
transaction: params.transaction,
|
|
312
320
|
collection: this
|
|
313
321
|
});
|
|
314
322
|
}
|
|
@@ -1050,7 +1058,7 @@ class CollectionImpl {
|
|
|
1050
1058
|
const directOpTransaction = createTransaction({
|
|
1051
1059
|
mutationFn: async (params) => {
|
|
1052
1060
|
return this.config.onUpdate({
|
|
1053
|
-
|
|
1061
|
+
transaction: params.transaction,
|
|
1054
1062
|
collection: this
|
|
1055
1063
|
});
|
|
1056
1064
|
}
|