@tanstack/db 0.0.14 → 0.0.15
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 +117 -104
- package/dist/cjs/collection.cjs.map +1 -1
- package/dist/cjs/collection.d.cts +18 -21
- package/dist/cjs/index.cjs +35 -13
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +0 -1
- package/dist/cjs/query/builder/functions.cjs +107 -0
- package/dist/cjs/query/builder/functions.cjs.map +1 -0
- package/dist/cjs/query/builder/functions.d.cts +38 -0
- package/dist/cjs/query/builder/index.cjs +499 -0
- package/dist/cjs/query/builder/index.cjs.map +1 -0
- package/dist/cjs/query/builder/index.d.cts +324 -0
- package/dist/cjs/query/builder/ref-proxy.cjs +96 -0
- package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -0
- package/dist/cjs/query/builder/ref-proxy.d.cts +28 -0
- package/dist/cjs/query/builder/types.d.cts +80 -0
- package/dist/cjs/query/compiler/evaluators.cjs +261 -0
- package/dist/cjs/query/compiler/evaluators.cjs.map +1 -0
- package/dist/cjs/query/compiler/evaluators.d.cts +11 -0
- package/dist/cjs/query/compiler/group-by.cjs +271 -0
- package/dist/cjs/query/compiler/group-by.cjs.map +1 -0
- package/dist/cjs/query/compiler/group-by.d.cts +7 -0
- package/dist/cjs/query/compiler/index.cjs +181 -0
- package/dist/cjs/query/compiler/index.cjs.map +1 -0
- package/dist/cjs/query/compiler/index.d.cts +15 -0
- package/dist/cjs/query/compiler/joins.cjs +116 -0
- package/dist/cjs/query/compiler/joins.cjs.map +1 -0
- package/dist/cjs/query/compiler/joins.d.cts +11 -0
- package/dist/cjs/query/compiler/order-by.cjs +89 -0
- package/dist/cjs/query/compiler/order-by.cjs.map +1 -0
- package/dist/cjs/query/compiler/order-by.d.cts +9 -0
- package/dist/cjs/query/compiler/select.cjs +57 -0
- package/dist/cjs/query/compiler/select.cjs.map +1 -0
- package/dist/cjs/query/compiler/select.d.cts +15 -0
- package/dist/cjs/query/index.d.cts +6 -5
- package/dist/cjs/query/ir.cjs +57 -0
- package/dist/cjs/query/ir.cjs.map +1 -0
- package/dist/cjs/query/ir.d.cts +81 -0
- package/dist/cjs/query/live-query-collection.cjs +224 -0
- package/dist/cjs/query/live-query-collection.cjs.map +1 -0
- package/dist/cjs/query/live-query-collection.d.cts +124 -0
- package/dist/cjs/transactions.cjs +20 -13
- package/dist/cjs/transactions.cjs.map +1 -1
- package/dist/cjs/transactions.d.cts +10 -1
- package/dist/cjs/types.d.cts +13 -0
- package/dist/esm/collection.d.ts +18 -21
- package/dist/esm/collection.js +118 -105
- package/dist/esm/collection.js.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +34 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/query/builder/functions.d.ts +38 -0
- package/dist/esm/query/builder/functions.js +107 -0
- package/dist/esm/query/builder/functions.js.map +1 -0
- package/dist/esm/query/builder/index.d.ts +324 -0
- package/dist/esm/query/builder/index.js +499 -0
- package/dist/esm/query/builder/index.js.map +1 -0
- package/dist/esm/query/builder/ref-proxy.d.ts +28 -0
- package/dist/esm/query/builder/ref-proxy.js +96 -0
- package/dist/esm/query/builder/ref-proxy.js.map +1 -0
- package/dist/esm/query/builder/types.d.ts +80 -0
- package/dist/esm/query/compiler/evaluators.d.ts +11 -0
- package/dist/esm/query/compiler/evaluators.js +261 -0
- package/dist/esm/query/compiler/evaluators.js.map +1 -0
- package/dist/esm/query/compiler/group-by.d.ts +7 -0
- package/dist/esm/query/compiler/group-by.js +271 -0
- package/dist/esm/query/compiler/group-by.js.map +1 -0
- package/dist/esm/query/compiler/index.d.ts +15 -0
- package/dist/esm/query/compiler/index.js +181 -0
- package/dist/esm/query/compiler/index.js.map +1 -0
- package/dist/esm/query/compiler/joins.d.ts +11 -0
- package/dist/esm/query/compiler/joins.js +116 -0
- package/dist/esm/query/compiler/joins.js.map +1 -0
- package/dist/esm/query/compiler/order-by.d.ts +9 -0
- package/dist/esm/query/compiler/order-by.js +89 -0
- package/dist/esm/query/compiler/order-by.js.map +1 -0
- package/dist/esm/query/compiler/select.d.ts +15 -0
- package/dist/esm/query/compiler/select.js +57 -0
- package/dist/esm/query/compiler/select.js.map +1 -0
- package/dist/esm/query/index.d.ts +6 -5
- package/dist/esm/query/ir.d.ts +81 -0
- package/dist/esm/query/ir.js +57 -0
- package/dist/esm/query/ir.js.map +1 -0
- package/dist/esm/query/live-query-collection.d.ts +124 -0
- package/dist/esm/query/live-query-collection.js +224 -0
- package/dist/esm/query/live-query-collection.js.map +1 -0
- package/dist/esm/transactions.d.ts +10 -1
- package/dist/esm/transactions.js +20 -13
- package/dist/esm/transactions.js.map +1 -1
- package/dist/esm/types.d.ts +13 -0
- package/package.json +3 -4
- package/src/collection.ts +152 -129
- package/src/index.ts +0 -1
- package/src/query/builder/functions.ts +267 -0
- package/src/query/builder/index.ts +648 -0
- package/src/query/builder/ref-proxy.ts +156 -0
- package/src/query/builder/types.ts +278 -0
- package/src/query/compiler/evaluators.ts +315 -0
- package/src/query/compiler/group-by.ts +428 -0
- package/src/query/compiler/index.ts +276 -0
- package/src/query/compiler/joins.ts +228 -0
- package/src/query/compiler/order-by.ts +139 -0
- package/src/query/compiler/select.ts +173 -0
- package/src/query/index.ts +64 -5
- package/src/query/ir.ts +128 -0
- package/src/query/live-query-collection.ts +509 -0
- package/src/transactions.ts +27 -16
- package/src/types.ts +15 -0
- package/dist/cjs/query/compiled-query.cjs +0 -160
- package/dist/cjs/query/compiled-query.cjs.map +0 -1
- package/dist/cjs/query/compiled-query.d.cts +0 -20
- package/dist/cjs/query/evaluators.cjs +0 -161
- package/dist/cjs/query/evaluators.cjs.map +0 -1
- package/dist/cjs/query/evaluators.d.cts +0 -14
- package/dist/cjs/query/extractors.cjs +0 -122
- package/dist/cjs/query/extractors.cjs.map +0 -1
- package/dist/cjs/query/extractors.d.cts +0 -22
- package/dist/cjs/query/functions.cjs +0 -152
- package/dist/cjs/query/functions.cjs.map +0 -1
- package/dist/cjs/query/functions.d.cts +0 -21
- package/dist/cjs/query/group-by.cjs +0 -88
- package/dist/cjs/query/group-by.cjs.map +0 -1
- package/dist/cjs/query/group-by.d.cts +0 -40
- package/dist/cjs/query/joins.cjs +0 -141
- package/dist/cjs/query/joins.cjs.map +0 -1
- package/dist/cjs/query/joins.d.cts +0 -14
- package/dist/cjs/query/order-by.cjs +0 -185
- package/dist/cjs/query/order-by.cjs.map +0 -1
- package/dist/cjs/query/order-by.d.cts +0 -3
- package/dist/cjs/query/pipeline-compiler.cjs +0 -89
- package/dist/cjs/query/pipeline-compiler.cjs.map +0 -1
- package/dist/cjs/query/pipeline-compiler.d.cts +0 -10
- package/dist/cjs/query/query-builder.cjs +0 -307
- package/dist/cjs/query/query-builder.cjs.map +0 -1
- package/dist/cjs/query/query-builder.d.cts +0 -225
- package/dist/cjs/query/schema.d.cts +0 -100
- package/dist/cjs/query/select.cjs +0 -130
- package/dist/cjs/query/select.cjs.map +0 -1
- package/dist/cjs/query/select.d.cts +0 -3
- package/dist/cjs/query/types.d.cts +0 -189
- package/dist/cjs/query/utils.cjs +0 -154
- package/dist/cjs/query/utils.cjs.map +0 -1
- package/dist/cjs/query/utils.d.cts +0 -37
- package/dist/cjs/utils.cjs +0 -17
- package/dist/cjs/utils.cjs.map +0 -1
- package/dist/cjs/utils.d.cts +0 -3
- package/dist/esm/query/compiled-query.d.ts +0 -20
- package/dist/esm/query/compiled-query.js +0 -160
- package/dist/esm/query/compiled-query.js.map +0 -1
- package/dist/esm/query/evaluators.d.ts +0 -14
- package/dist/esm/query/evaluators.js +0 -161
- package/dist/esm/query/evaluators.js.map +0 -1
- package/dist/esm/query/extractors.d.ts +0 -22
- package/dist/esm/query/extractors.js +0 -122
- package/dist/esm/query/extractors.js.map +0 -1
- package/dist/esm/query/functions.d.ts +0 -21
- package/dist/esm/query/functions.js +0 -152
- package/dist/esm/query/functions.js.map +0 -1
- package/dist/esm/query/group-by.d.ts +0 -40
- package/dist/esm/query/group-by.js +0 -88
- package/dist/esm/query/group-by.js.map +0 -1
- package/dist/esm/query/joins.d.ts +0 -14
- package/dist/esm/query/joins.js +0 -141
- package/dist/esm/query/joins.js.map +0 -1
- package/dist/esm/query/order-by.d.ts +0 -3
- package/dist/esm/query/order-by.js +0 -185
- package/dist/esm/query/order-by.js.map +0 -1
- package/dist/esm/query/pipeline-compiler.d.ts +0 -10
- package/dist/esm/query/pipeline-compiler.js +0 -89
- package/dist/esm/query/pipeline-compiler.js.map +0 -1
- package/dist/esm/query/query-builder.d.ts +0 -225
- package/dist/esm/query/query-builder.js +0 -307
- package/dist/esm/query/query-builder.js.map +0 -1
- package/dist/esm/query/schema.d.ts +0 -100
- package/dist/esm/query/select.d.ts +0 -3
- package/dist/esm/query/select.js +0 -130
- package/dist/esm/query/select.js.map +0 -1
- package/dist/esm/query/types.d.ts +0 -189
- package/dist/esm/query/utils.d.ts +0 -37
- package/dist/esm/query/utils.js +0 -154
- package/dist/esm/query/utils.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -3
- package/dist/esm/utils.js +0 -17
- package/dist/esm/utils.js.map +0 -1
- package/src/query/compiled-query.ts +0 -234
- package/src/query/evaluators.ts +0 -250
- package/src/query/extractors.ts +0 -214
- package/src/query/functions.ts +0 -297
- package/src/query/group-by.ts +0 -139
- package/src/query/joins.ts +0 -260
- package/src/query/order-by.ts +0 -264
- package/src/query/pipeline-compiler.ts +0 -149
- package/src/query/query-builder.ts +0 -902
- package/src/query/schema.ts +0 -268
- package/src/query/select.ts +0 -208
- package/src/query/types.ts +0 -418
- package/src/query/utils.ts +0 -245
- package/src/utils.ts +0 -15
package/dist/esm/collection.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Store } from '@tanstack/store';
|
|
2
|
-
import { Transaction } from './transactions.js';
|
|
3
1
|
import { SortedMap } from './SortedMap.js';
|
|
2
|
+
import { Transaction } from './transactions.js';
|
|
4
3
|
import { ChangeListener, ChangeMessage, CollectionConfig, CollectionStatus, Fn, InsertConfig, OperationConfig, OptimisticChangeMessage, ResolveType, Transaction as TransactionType, UtilsRecord } from './types.js';
|
|
5
4
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
5
|
export declare const collectionsStore: Map<string, CollectionImpl<any, any>>;
|
|
@@ -73,8 +72,8 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
73
72
|
pendingSyncedTransactions: Array<PendingSyncedTransaction<T>>;
|
|
74
73
|
syncedData: Map<TKey, T> | SortedMap<TKey, T>;
|
|
75
74
|
syncedMetadata: Map<TKey, unknown>;
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
optimisticUpserts: Map<TKey, T>;
|
|
76
|
+
optimisticDeletes: Set<TKey>;
|
|
78
77
|
private _size;
|
|
79
78
|
private changeListeners;
|
|
80
79
|
private changeKeyListeners;
|
|
@@ -85,6 +84,8 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
85
84
|
private hasReceivedFirstCommit;
|
|
86
85
|
private isCommittingSyncTransactions;
|
|
87
86
|
private onFirstCommitCallbacks;
|
|
87
|
+
private batchedEvents;
|
|
88
|
+
private shouldBatchEvents;
|
|
88
89
|
private _status;
|
|
89
90
|
private activeSubscribersCount;
|
|
90
91
|
private gcTimeoutId;
|
|
@@ -178,7 +179,7 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
178
179
|
*/
|
|
179
180
|
private getPreviousValue;
|
|
180
181
|
/**
|
|
181
|
-
* Emit
|
|
182
|
+
* Emit events either immediately or batch them for later emission
|
|
182
183
|
*/
|
|
183
184
|
private emitEvents;
|
|
184
185
|
/**
|
|
@@ -205,6 +206,18 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
205
206
|
* Get all entries (virtual derived state)
|
|
206
207
|
*/
|
|
207
208
|
entries(): IterableIterator<[TKey, T]>;
|
|
209
|
+
/**
|
|
210
|
+
* Get all entries (virtual derived state)
|
|
211
|
+
*/
|
|
212
|
+
[Symbol.iterator](): IterableIterator<[TKey, T]>;
|
|
213
|
+
/**
|
|
214
|
+
* Execute a callback for each entry in the collection
|
|
215
|
+
*/
|
|
216
|
+
forEach(callbackfn: (value: T, key: TKey, index: number) => void): void;
|
|
217
|
+
/**
|
|
218
|
+
* Create a new array with the results of calling a function for each entry in the collection
|
|
219
|
+
*/
|
|
220
|
+
map<U>(callbackfn: (value: T, key: TKey, index: number) => U): Array<U>;
|
|
208
221
|
/**
|
|
209
222
|
* Attempts to commit pending synced transactions if there are no active transactions
|
|
210
223
|
* This method processes operations from pending transactions and applies them to the synced data
|
|
@@ -348,21 +361,5 @@ export declare class CollectionImpl<T extends object = Record<string, unknown>,
|
|
|
348
361
|
* This method should be called by the Transaction class when state changes
|
|
349
362
|
*/
|
|
350
363
|
onTransactionStateChange(): void;
|
|
351
|
-
private _storeMap;
|
|
352
|
-
/**
|
|
353
|
-
* Returns a Tanstack Store Map that is updated when the collection changes
|
|
354
|
-
* This is a temporary solution to enable the existing framework hooks to work
|
|
355
|
-
* with the new internals of Collection until they are rewritten.
|
|
356
|
-
* TODO: Remove this once the framework hooks are rewritten.
|
|
357
|
-
*/
|
|
358
|
-
asStoreMap(): Store<Map<TKey, T>>;
|
|
359
|
-
private _storeArray;
|
|
360
|
-
/**
|
|
361
|
-
* Returns a Tanstack Store Array that is updated when the collection changes
|
|
362
|
-
* This is a temporary solution to enable the existing framework hooks to work
|
|
363
|
-
* with the new internals of Collection until they are rewritten.
|
|
364
|
-
* TODO: Remove this once the framework hooks are rewritten.
|
|
365
|
-
*/
|
|
366
|
-
asStoreArray(): Store<Array<T>>;
|
|
367
364
|
}
|
|
368
365
|
export {};
|
package/dist/esm/collection.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Store } from "@tanstack/store";
|
|
2
1
|
import { withArrayChangeTracking, withChangeTracking } from "./proxy.js";
|
|
3
|
-
import { getActiveTransaction,
|
|
2
|
+
import { getActiveTransaction, createTransaction } from "./transactions.js";
|
|
4
3
|
import { SortedMap } from "./SortedMap.js";
|
|
5
4
|
const collectionsStore = /* @__PURE__ */ new Map();
|
|
6
5
|
function createCollection(options) {
|
|
@@ -32,8 +31,8 @@ class CollectionImpl {
|
|
|
32
31
|
constructor(config) {
|
|
33
32
|
this.pendingSyncedTransactions = [];
|
|
34
33
|
this.syncedMetadata = /* @__PURE__ */ new Map();
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
34
|
+
this.optimisticUpserts = /* @__PURE__ */ new Map();
|
|
35
|
+
this.optimisticDeletes = /* @__PURE__ */ new Set();
|
|
37
36
|
this._size = 0;
|
|
38
37
|
this.changeListeners = /* @__PURE__ */ new Set();
|
|
39
38
|
this.changeKeyListeners = /* @__PURE__ */ new Map();
|
|
@@ -44,6 +43,8 @@ class CollectionImpl {
|
|
|
44
43
|
this.hasReceivedFirstCommit = false;
|
|
45
44
|
this.isCommittingSyncTransactions = false;
|
|
46
45
|
this.onFirstCommitCallbacks = [];
|
|
46
|
+
this.batchedEvents = [];
|
|
47
|
+
this.shouldBatchEvents = false;
|
|
47
48
|
this._status = `idle`;
|
|
48
49
|
this.activeSubscribersCount = 0;
|
|
49
50
|
this.gcTimeoutId = null;
|
|
@@ -77,6 +78,7 @@ class CollectionImpl {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
const events = [];
|
|
81
|
+
const rowUpdateMode = this.config.sync.rowUpdateMode || `partial`;
|
|
80
82
|
for (const transaction of this.pendingSyncedTransactions) {
|
|
81
83
|
for (const operation of transaction.operations) {
|
|
82
84
|
const key = operation.key;
|
|
@@ -104,12 +106,16 @@ class CollectionImpl {
|
|
|
104
106
|
this.syncedData.set(key, operation.value);
|
|
105
107
|
break;
|
|
106
108
|
case `update`: {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
if (rowUpdateMode === `partial`) {
|
|
110
|
+
const updatedValue = Object.assign(
|
|
111
|
+
{},
|
|
112
|
+
this.syncedData.get(key),
|
|
113
|
+
operation.value
|
|
114
|
+
);
|
|
115
|
+
this.syncedData.set(key, updatedValue);
|
|
116
|
+
} else {
|
|
117
|
+
this.syncedData.set(key, operation.value);
|
|
118
|
+
}
|
|
113
119
|
break;
|
|
114
120
|
}
|
|
115
121
|
case `delete`:
|
|
@@ -118,8 +124,8 @@ class CollectionImpl {
|
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
|
-
this.
|
|
122
|
-
this.
|
|
127
|
+
this.optimisticUpserts.clear();
|
|
128
|
+
this.optimisticDeletes.clear();
|
|
123
129
|
this.isCommittingSyncTransactions = false;
|
|
124
130
|
for (const transaction of this.transactions.values()) {
|
|
125
131
|
if (![`completed`, `failed`].includes(transaction.state)) {
|
|
@@ -128,12 +134,15 @@ class CollectionImpl {
|
|
|
128
134
|
switch (mutation.type) {
|
|
129
135
|
case `insert`:
|
|
130
136
|
case `update`:
|
|
131
|
-
this.
|
|
132
|
-
|
|
137
|
+
this.optimisticUpserts.set(
|
|
138
|
+
mutation.key,
|
|
139
|
+
mutation.modified
|
|
140
|
+
);
|
|
141
|
+
this.optimisticDeletes.delete(mutation.key);
|
|
133
142
|
break;
|
|
134
143
|
case `delete`:
|
|
135
|
-
this.
|
|
136
|
-
this.
|
|
144
|
+
this.optimisticUpserts.delete(mutation.key);
|
|
145
|
+
this.optimisticDeletes.add(mutation.key);
|
|
137
146
|
break;
|
|
138
147
|
}
|
|
139
148
|
}
|
|
@@ -182,7 +191,7 @@ class CollectionImpl {
|
|
|
182
191
|
}
|
|
183
192
|
}
|
|
184
193
|
this._size = this.calculateSize();
|
|
185
|
-
this.emitEvents(events);
|
|
194
|
+
this.emitEvents(events, true);
|
|
186
195
|
this.pendingSyncedTransactions = [];
|
|
187
196
|
this.preSyncVisibleState.clear();
|
|
188
197
|
Promise.resolve().then(() => {
|
|
@@ -236,7 +245,7 @@ class CollectionImpl {
|
|
|
236
245
|
this.recomputeOptimisticState();
|
|
237
246
|
return ambientTransaction;
|
|
238
247
|
} else {
|
|
239
|
-
const directOpTransaction =
|
|
248
|
+
const directOpTransaction = createTransaction({
|
|
240
249
|
mutationFn: async (params) => {
|
|
241
250
|
return this.config.onInsert(params);
|
|
242
251
|
}
|
|
@@ -290,7 +299,7 @@ class CollectionImpl {
|
|
|
290
299
|
this.recomputeOptimisticState();
|
|
291
300
|
return ambientTransaction;
|
|
292
301
|
}
|
|
293
|
-
const directOpTransaction =
|
|
302
|
+
const directOpTransaction = createTransaction({
|
|
294
303
|
autoCommit: true,
|
|
295
304
|
mutationFn: async (params) => {
|
|
296
305
|
return this.config.onDelete(params);
|
|
@@ -314,7 +323,7 @@ class CollectionImpl {
|
|
|
314
323
|
throw new Error(`Collection requires a sync config`);
|
|
315
324
|
}
|
|
316
325
|
this.transactions = new SortedMap(
|
|
317
|
-
(a, b) => a.
|
|
326
|
+
(a, b) => a.compareCreatedAt(b)
|
|
318
327
|
);
|
|
319
328
|
this.config = config;
|
|
320
329
|
collectionsStore.set(this.id, this);
|
|
@@ -448,10 +457,10 @@ class CollectionImpl {
|
|
|
448
457
|
);
|
|
449
458
|
}
|
|
450
459
|
pendingTransaction.committed = true;
|
|
451
|
-
this.commitPendingTransactions();
|
|
452
460
|
if (this._status === `loading`) {
|
|
453
461
|
this.setStatus(`ready`);
|
|
454
462
|
}
|
|
463
|
+
this.commitPendingTransactions();
|
|
455
464
|
}
|
|
456
465
|
});
|
|
457
466
|
this.syncCleanupFn = typeof cleanupFn === `function` ? cleanupFn : null;
|
|
@@ -523,14 +532,16 @@ class CollectionImpl {
|
|
|
523
532
|
}
|
|
524
533
|
this.syncedData.clear();
|
|
525
534
|
this.syncedMetadata.clear();
|
|
526
|
-
this.
|
|
527
|
-
this.
|
|
535
|
+
this.optimisticUpserts.clear();
|
|
536
|
+
this.optimisticDeletes.clear();
|
|
528
537
|
this._size = 0;
|
|
529
538
|
this.pendingSyncedTransactions = [];
|
|
530
539
|
this.syncedKeys.clear();
|
|
531
540
|
this.hasReceivedFirstCommit = false;
|
|
532
541
|
this.onFirstCommitCallbacks = [];
|
|
533
542
|
this.preloadPromise = null;
|
|
543
|
+
this.batchedEvents = [];
|
|
544
|
+
this.shouldBatchEvents = false;
|
|
534
545
|
this.setStatus(`cleaned-up`);
|
|
535
546
|
return Promise.resolve();
|
|
536
547
|
}
|
|
@@ -590,10 +601,10 @@ class CollectionImpl {
|
|
|
590
601
|
if (this.isCommittingSyncTransactions) {
|
|
591
602
|
return;
|
|
592
603
|
}
|
|
593
|
-
const previousState = new Map(this.
|
|
594
|
-
const previousDeletes = new Set(this.
|
|
595
|
-
this.
|
|
596
|
-
this.
|
|
604
|
+
const previousState = new Map(this.optimisticUpserts);
|
|
605
|
+
const previousDeletes = new Set(this.optimisticDeletes);
|
|
606
|
+
this.optimisticUpserts.clear();
|
|
607
|
+
this.optimisticDeletes.clear();
|
|
597
608
|
const activeTransactions = [];
|
|
598
609
|
const completedTransactions = [];
|
|
599
610
|
for (const transaction of this.transactions.values()) {
|
|
@@ -609,12 +620,12 @@ class CollectionImpl {
|
|
|
609
620
|
switch (mutation.type) {
|
|
610
621
|
case `insert`:
|
|
611
622
|
case `update`:
|
|
612
|
-
this.
|
|
613
|
-
this.
|
|
623
|
+
this.optimisticUpserts.set(mutation.key, mutation.modified);
|
|
624
|
+
this.optimisticDeletes.delete(mutation.key);
|
|
614
625
|
break;
|
|
615
626
|
case `delete`:
|
|
616
|
-
this.
|
|
617
|
-
this.
|
|
627
|
+
this.optimisticUpserts.delete(mutation.key);
|
|
628
|
+
this.optimisticDeletes.add(mutation.key);
|
|
618
629
|
break;
|
|
619
630
|
}
|
|
620
631
|
}
|
|
@@ -664,10 +675,10 @@ class CollectionImpl {
|
|
|
664
675
|
*/
|
|
665
676
|
calculateSize() {
|
|
666
677
|
const syncedSize = this.syncedData.size;
|
|
667
|
-
const deletesFromSynced = Array.from(this.
|
|
668
|
-
(key) => this.syncedData.has(key) && !this.
|
|
678
|
+
const deletesFromSynced = Array.from(this.optimisticDeletes).filter(
|
|
679
|
+
(key) => this.syncedData.has(key) && !this.optimisticUpserts.has(key)
|
|
669
680
|
).length;
|
|
670
|
-
const upsertsNotInSynced = Array.from(this.
|
|
681
|
+
const upsertsNotInSynced = Array.from(this.optimisticUpserts.keys()).filter(
|
|
671
682
|
(key) => !this.syncedData.has(key)
|
|
672
683
|
).length;
|
|
673
684
|
return syncedSize - deletesFromSynced + upsertsNotInSynced;
|
|
@@ -678,9 +689,9 @@ class CollectionImpl {
|
|
|
678
689
|
collectOptimisticChanges(previousUpserts, previousDeletes, events) {
|
|
679
690
|
const allKeys = /* @__PURE__ */ new Set([
|
|
680
691
|
...previousUpserts.keys(),
|
|
681
|
-
...this.
|
|
692
|
+
...this.optimisticUpserts.keys(),
|
|
682
693
|
...previousDeletes,
|
|
683
|
-
...this.
|
|
694
|
+
...this.optimisticDeletes
|
|
684
695
|
]);
|
|
685
696
|
for (const key of allKeys) {
|
|
686
697
|
const currentValue = this.get(key);
|
|
@@ -716,28 +727,39 @@ class CollectionImpl {
|
|
|
716
727
|
return this.syncedData.get(key);
|
|
717
728
|
}
|
|
718
729
|
/**
|
|
719
|
-
* Emit
|
|
730
|
+
* Emit events either immediately or batch them for later emission
|
|
720
731
|
*/
|
|
721
|
-
emitEvents(changes) {
|
|
722
|
-
if (
|
|
723
|
-
|
|
724
|
-
|
|
732
|
+
emitEvents(changes, endBatching = false) {
|
|
733
|
+
if (this.shouldBatchEvents && !endBatching) {
|
|
734
|
+
this.batchedEvents.push(...changes);
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
let eventsToEmit = changes;
|
|
738
|
+
if (endBatching) {
|
|
739
|
+
if (this.batchedEvents.length > 0) {
|
|
740
|
+
eventsToEmit = [...this.batchedEvents, ...changes];
|
|
725
741
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
742
|
+
this.batchedEvents = [];
|
|
743
|
+
this.shouldBatchEvents = false;
|
|
744
|
+
}
|
|
745
|
+
if (eventsToEmit.length === 0) return;
|
|
746
|
+
for (const listener of this.changeListeners) {
|
|
747
|
+
listener(eventsToEmit);
|
|
748
|
+
}
|
|
749
|
+
if (this.changeKeyListeners.size > 0) {
|
|
750
|
+
const changesByKey = /* @__PURE__ */ new Map();
|
|
751
|
+
for (const change of eventsToEmit) {
|
|
752
|
+
if (this.changeKeyListeners.has(change.key)) {
|
|
753
|
+
if (!changesByKey.has(change.key)) {
|
|
754
|
+
changesByKey.set(change.key, []);
|
|
734
755
|
}
|
|
756
|
+
changesByKey.get(change.key).push(change);
|
|
735
757
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
758
|
+
}
|
|
759
|
+
for (const [key, keyChanges] of changesByKey) {
|
|
760
|
+
const keyListeners = this.changeKeyListeners.get(key);
|
|
761
|
+
for (const listener of keyListeners) {
|
|
762
|
+
listener(keyChanges);
|
|
741
763
|
}
|
|
742
764
|
}
|
|
743
765
|
}
|
|
@@ -746,11 +768,11 @@ class CollectionImpl {
|
|
|
746
768
|
* Get the current value for a key (virtual derived state)
|
|
747
769
|
*/
|
|
748
770
|
get(key) {
|
|
749
|
-
if (this.
|
|
771
|
+
if (this.optimisticDeletes.has(key)) {
|
|
750
772
|
return void 0;
|
|
751
773
|
}
|
|
752
|
-
if (this.
|
|
753
|
-
return this.
|
|
774
|
+
if (this.optimisticUpserts.has(key)) {
|
|
775
|
+
return this.optimisticUpserts.get(key);
|
|
754
776
|
}
|
|
755
777
|
return this.syncedData.get(key);
|
|
756
778
|
}
|
|
@@ -758,10 +780,10 @@ class CollectionImpl {
|
|
|
758
780
|
* Check if a key exists in the collection (virtual derived state)
|
|
759
781
|
*/
|
|
760
782
|
has(key) {
|
|
761
|
-
if (this.
|
|
783
|
+
if (this.optimisticDeletes.has(key)) {
|
|
762
784
|
return false;
|
|
763
785
|
}
|
|
764
|
-
if (this.
|
|
786
|
+
if (this.optimisticUpserts.has(key)) {
|
|
765
787
|
return true;
|
|
766
788
|
}
|
|
767
789
|
return this.syncedData.has(key);
|
|
@@ -777,12 +799,12 @@ class CollectionImpl {
|
|
|
777
799
|
*/
|
|
778
800
|
*keys() {
|
|
779
801
|
for (const key of this.syncedData.keys()) {
|
|
780
|
-
if (!this.
|
|
802
|
+
if (!this.optimisticDeletes.has(key)) {
|
|
781
803
|
yield key;
|
|
782
804
|
}
|
|
783
805
|
}
|
|
784
|
-
for (const key of this.
|
|
785
|
-
if (!this.syncedData.has(key) && !this.
|
|
806
|
+
for (const key of this.optimisticUpserts.keys()) {
|
|
807
|
+
if (!this.syncedData.has(key) && !this.optimisticDeletes.has(key)) {
|
|
786
808
|
yield key;
|
|
787
809
|
}
|
|
788
810
|
}
|
|
@@ -794,8 +816,7 @@ class CollectionImpl {
|
|
|
794
816
|
for (const key of this.keys()) {
|
|
795
817
|
const value = this.get(key);
|
|
796
818
|
if (value !== void 0) {
|
|
797
|
-
|
|
798
|
-
yield copy;
|
|
819
|
+
yield value;
|
|
799
820
|
}
|
|
800
821
|
}
|
|
801
822
|
}
|
|
@@ -806,11 +827,38 @@ class CollectionImpl {
|
|
|
806
827
|
for (const key of this.keys()) {
|
|
807
828
|
const value = this.get(key);
|
|
808
829
|
if (value !== void 0) {
|
|
809
|
-
|
|
810
|
-
yield [key, copy];
|
|
830
|
+
yield [key, value];
|
|
811
831
|
}
|
|
812
832
|
}
|
|
813
833
|
}
|
|
834
|
+
/**
|
|
835
|
+
* Get all entries (virtual derived state)
|
|
836
|
+
*/
|
|
837
|
+
*[Symbol.iterator]() {
|
|
838
|
+
for (const [key, value] of this.entries()) {
|
|
839
|
+
yield [key, value];
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Execute a callback for each entry in the collection
|
|
844
|
+
*/
|
|
845
|
+
forEach(callbackfn) {
|
|
846
|
+
let index = 0;
|
|
847
|
+
for (const [key, value] of this.entries()) {
|
|
848
|
+
callbackfn(value, key, index++);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Create a new array with the results of calling a function for each entry in the collection
|
|
853
|
+
*/
|
|
854
|
+
map(callbackfn) {
|
|
855
|
+
const result = [];
|
|
856
|
+
let index = 0;
|
|
857
|
+
for (const [key, value] of this.entries()) {
|
|
858
|
+
result.push(callbackfn(value, key, index++));
|
|
859
|
+
}
|
|
860
|
+
return result;
|
|
861
|
+
}
|
|
814
862
|
ensureStandardSchema(schema) {
|
|
815
863
|
if (schema && typeof schema === `object` && `~standard` in schema) {
|
|
816
864
|
return schema;
|
|
@@ -968,7 +1016,7 @@ class CollectionImpl {
|
|
|
968
1016
|
};
|
|
969
1017
|
}).filter(Boolean);
|
|
970
1018
|
if (mutations.length === 0) {
|
|
971
|
-
const emptyTransaction =
|
|
1019
|
+
const emptyTransaction = createTransaction({
|
|
972
1020
|
mutationFn: async () => {
|
|
973
1021
|
}
|
|
974
1022
|
});
|
|
@@ -981,7 +1029,7 @@ class CollectionImpl {
|
|
|
981
1029
|
this.recomputeOptimisticState();
|
|
982
1030
|
return ambientTransaction;
|
|
983
1031
|
}
|
|
984
|
-
const directOpTransaction =
|
|
1032
|
+
const directOpTransaction = createTransaction({
|
|
985
1033
|
mutationFn: async (params) => {
|
|
986
1034
|
return this.config.onUpdate(params);
|
|
987
1035
|
}
|
|
@@ -1026,13 +1074,7 @@ class CollectionImpl {
|
|
|
1026
1074
|
* @returns An Array containing all items in the collection
|
|
1027
1075
|
*/
|
|
1028
1076
|
get toArray() {
|
|
1029
|
-
|
|
1030
|
-
if (array[0] && array[0]._orderByIndex) {
|
|
1031
|
-
return array.sort(
|
|
1032
|
-
(a, b) => a._orderByIndex - b._orderByIndex
|
|
1033
|
-
);
|
|
1034
|
-
}
|
|
1035
|
-
return array;
|
|
1077
|
+
return Array.from(this.values());
|
|
1036
1078
|
}
|
|
1037
1079
|
/**
|
|
1038
1080
|
* Gets the current state of the collection as an Array, but only resolves when data is available
|
|
@@ -1134,39 +1176,10 @@ class CollectionImpl {
|
|
|
1134
1176
|
* This method should be called by the Transaction class when state changes
|
|
1135
1177
|
*/
|
|
1136
1178
|
onTransactionStateChange() {
|
|
1179
|
+
this.shouldBatchEvents = this.pendingSyncedTransactions.length > 0;
|
|
1137
1180
|
this.capturePreSyncVisibleState();
|
|
1138
1181
|
this.recomputeOptimisticState();
|
|
1139
1182
|
}
|
|
1140
|
-
/**
|
|
1141
|
-
* Returns a Tanstack Store Map that is updated when the collection changes
|
|
1142
|
-
* This is a temporary solution to enable the existing framework hooks to work
|
|
1143
|
-
* with the new internals of Collection until they are rewritten.
|
|
1144
|
-
* TODO: Remove this once the framework hooks are rewritten.
|
|
1145
|
-
*/
|
|
1146
|
-
asStoreMap() {
|
|
1147
|
-
if (!this._storeMap) {
|
|
1148
|
-
this._storeMap = new Store(new Map(this.entries()));
|
|
1149
|
-
this.changeListeners.add(() => {
|
|
1150
|
-
this._storeMap.setState(() => new Map(this.entries()));
|
|
1151
|
-
});
|
|
1152
|
-
}
|
|
1153
|
-
return this._storeMap;
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* Returns a Tanstack Store Array that is updated when the collection changes
|
|
1157
|
-
* This is a temporary solution to enable the existing framework hooks to work
|
|
1158
|
-
* with the new internals of Collection until they are rewritten.
|
|
1159
|
-
* TODO: Remove this once the framework hooks are rewritten.
|
|
1160
|
-
*/
|
|
1161
|
-
asStoreArray() {
|
|
1162
|
-
if (!this._storeArray) {
|
|
1163
|
-
this._storeArray = new Store(this.toArray);
|
|
1164
|
-
this.changeListeners.add(() => {
|
|
1165
|
-
this._storeArray.setState(() => this.toArray);
|
|
1166
|
-
});
|
|
1167
|
-
}
|
|
1168
|
-
return this._storeArray;
|
|
1169
|
-
}
|
|
1170
1183
|
}
|
|
1171
1184
|
export {
|
|
1172
1185
|
CollectionImpl,
|