@signaldb/core 2.0.0-beta.0 → 2.0.0-beta.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/dist/.vite/manifest.json +25 -12
- package/dist/AutoFetchDataAdapter.d.ts +0 -1
- package/dist/Collection/index.d.ts +2 -0
- package/dist/DataAdapter.d.ts +7 -6
- package/dist/DefaultDataAdapter.d.ts +1 -0
- package/dist/WorkerDataAdapter.d.ts +4 -1
- package/dist/WorkerDataAdapterHost.d.ts +9 -6
- package/dist/index.cjs12.js +32 -21
- package/dist/index.cjs13.js +25 -13
- package/dist/index.cjs14.js +31 -37
- package/dist/index.cjs15.js +120 -75
- package/dist/index.cjs16.js +45 -36
- package/dist/index.cjs17.js +1 -1
- package/dist/index.cjs2.js +5 -2
- package/dist/index.cjs20.js +5 -102
- package/dist/index.cjs21.js +93 -118
- package/dist/index.cjs22.js +127 -5
- package/dist/index.cjs23.js +5 -25
- package/dist/index.cjs24.js +25 -5
- package/dist/index.cjs26.js +1 -1
- package/dist/index.cjs27.js +44 -3
- package/dist/index.cjs28.js +6 -5
- package/dist/index.cjs29.js +7 -27
- package/dist/index.cjs3.js +25 -21
- package/dist/index.cjs30.js +3 -40
- package/dist/index.cjs31.js +5 -7
- package/dist/index.cjs32.js +29 -0
- package/dist/index.cjs33.js +42 -0
- package/dist/index.d.ts +1 -0
- package/dist/index12.mjs +32 -21
- package/dist/index13.mjs +25 -13
- package/dist/index14.mjs +31 -37
- package/dist/index15.mjs +120 -75
- package/dist/index16.mjs +45 -36
- package/dist/index17.mjs +1 -1
- package/dist/index2.mjs +5 -2
- package/dist/index20.mjs +5 -102
- package/dist/index21.mjs +93 -117
- package/dist/index22.mjs +126 -5
- package/dist/index23.mjs +5 -25
- package/dist/index24.mjs +25 -5
- package/dist/index26.mjs +1 -1
- package/dist/index27.mjs +44 -3
- package/dist/index28.mjs +6 -5
- package/dist/index29.mjs +7 -27
- package/dist/index3.mjs +25 -21
- package/dist/index30.mjs +3 -40
- package/dist/index31.mjs +5 -7
- package/dist/index32.mjs +30 -0
- package/dist/index33.mjs +43 -0
- package/dist/utils/batchOnNextTick.d.ts +16 -0
- package/package.json +1 -1
package/dist/index15.mjs
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import deepClone from "./index19.mjs";
|
|
2
|
-
import match from "./
|
|
2
|
+
import match from "./index23.mjs";
|
|
3
3
|
import modify from "./index7.mjs";
|
|
4
|
-
import queryId from "./
|
|
4
|
+
import queryId from "./index20.mjs";
|
|
5
5
|
import isEqual from "./index6.mjs";
|
|
6
|
-
import getIndexInfo from "./
|
|
6
|
+
import getIndexInfo from "./index22.mjs";
|
|
7
7
|
import getMatchingKeys from "./index26.mjs";
|
|
8
8
|
import sortItems from "./index25.mjs";
|
|
9
|
-
import project from "./
|
|
9
|
+
import project from "./index24.mjs";
|
|
10
|
+
import compact from "./index28.mjs";
|
|
10
11
|
class WorkerDataAdapterHost {
|
|
11
12
|
workerContext;
|
|
12
13
|
options;
|
|
13
14
|
id;
|
|
15
|
+
log = () => {
|
|
16
|
+
};
|
|
14
17
|
storageAdapters = /* @__PURE__ */ new Map();
|
|
15
18
|
storageAdapterReady = /* @__PURE__ */ new Map();
|
|
16
19
|
collectionIndices = /* @__PURE__ */ new Map();
|
|
@@ -25,6 +28,8 @@ class WorkerDataAdapterHost {
|
|
|
25
28
|
if (this.options.onError) {
|
|
26
29
|
this.onError = this.options.onError;
|
|
27
30
|
}
|
|
31
|
+
if (this.options.log)
|
|
32
|
+
this.log = this.options.log;
|
|
28
33
|
if (typeof addEventListener === "undefined" || typeof postMessage === "undefined") {
|
|
29
34
|
throw new TypeError("WorkerDataAdapterHost can only be used in a Web Worker context");
|
|
30
35
|
}
|
|
@@ -49,6 +54,8 @@ class WorkerDataAdapterHost {
|
|
|
49
54
|
this.respond(id, null, new Error(`Method ${method} not found`));
|
|
50
55
|
return;
|
|
51
56
|
}
|
|
57
|
+
this.log(method, ...args);
|
|
58
|
+
await this.isReady(args[0]);
|
|
52
59
|
try {
|
|
53
60
|
const result = await fn.apply(this, args);
|
|
54
61
|
this.respond(id, result);
|
|
@@ -63,7 +70,7 @@ class WorkerDataAdapterHost {
|
|
|
63
70
|
if (selector != null && Object.keys(selector).length === 1 && "id" in selector && typeof selector.id !== "object") {
|
|
64
71
|
return {
|
|
65
72
|
matched: true,
|
|
66
|
-
ids: [selector.id],
|
|
73
|
+
ids: compact([selector.id]),
|
|
67
74
|
optimizedSelector: {}
|
|
68
75
|
};
|
|
69
76
|
}
|
|
@@ -213,10 +220,7 @@ class WorkerDataAdapterHost {
|
|
|
213
220
|
if (!storageAdapter)
|
|
214
221
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
215
222
|
const setupPromise = (async () => {
|
|
216
|
-
await Promise.all(
|
|
217
|
-
storageAdapter.createIndex("id"),
|
|
218
|
-
...indices.map((index) => storageAdapter.createIndex(index))
|
|
219
|
-
]);
|
|
223
|
+
await Promise.all(indices.map((index) => storageAdapter.createIndex(index)));
|
|
220
224
|
await storageAdapter.setup();
|
|
221
225
|
})();
|
|
222
226
|
this.storageAdapterReady.set(collectionName, setupPromise);
|
|
@@ -237,101 +241,142 @@ class WorkerDataAdapterHost {
|
|
|
237
241
|
throw new Error(`Collection ${collectionName} not initialized!`);
|
|
238
242
|
this.queries.get(collectionName)?.delete(id);
|
|
239
243
|
};
|
|
240
|
-
insert = async (collectionName,
|
|
241
|
-
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
242
|
-
if (!storageAdapter)
|
|
243
|
-
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
244
|
-
const existingItems = await this.executeQuery(collectionName, { id: newItem.id }, { limit: 1 });
|
|
245
|
-
if (existingItems.length > 0) {
|
|
246
|
-
throw new Error(`Item with id ${newItem.id} already exists`);
|
|
247
|
-
}
|
|
248
|
-
await storageAdapter.insert([newItem]);
|
|
249
|
-
await this.checkQueryUpdates(collectionName, [newItem]);
|
|
250
|
-
return newItem;
|
|
251
|
-
};
|
|
252
|
-
updateOne = async (collectionName, selector, modifier) => {
|
|
244
|
+
insert = async (collectionName, input) => {
|
|
253
245
|
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
254
246
|
if (!storageAdapter)
|
|
255
247
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
256
|
-
const
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const existingItems = await this.executeQuery(collectionName, { id: modifiedItem.id }, { limit: 1 });
|
|
263
|
-
if (existingItems.length > 0) {
|
|
264
|
-
throw new Error(`Item with id ${modifiedItem.id} already exists`);
|
|
248
|
+
const existingItems = await this.executeQuery(collectionName, { id: { $in: input.map((i) => i[0].id) } });
|
|
249
|
+
const result = input.map(([item]) => {
|
|
250
|
+
if (item.id == null)
|
|
251
|
+
throw new Error("Item must have an id");
|
|
252
|
+
if (existingItems.some((existing) => existing.id === item.id)) {
|
|
253
|
+
return new Error(`Item with id ${item.id} already exists`);
|
|
265
254
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
255
|
+
return item;
|
|
256
|
+
});
|
|
257
|
+
const newItems = result.filter((item) => !(item instanceof Error));
|
|
258
|
+
await storageAdapter.insert(newItems);
|
|
259
|
+
await this.checkQueryUpdates(collectionName, newItems);
|
|
260
|
+
return result;
|
|
270
261
|
};
|
|
271
|
-
|
|
262
|
+
updateOne = async (collectionName, parameters) => {
|
|
272
263
|
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
273
264
|
if (!storageAdapter)
|
|
274
265
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
266
|
+
const previousItems = [];
|
|
267
|
+
const result = await Promise.all(parameters.map(async ([selector, modifier]) => {
|
|
268
|
+
const item = await this.executeQuery(collectionName, selector, { limit: 1 }).then((items) => items[0] ?? null);
|
|
269
|
+
const { $setOnInsert, ...restModifier } = modifier;
|
|
270
|
+
if (item == null)
|
|
271
|
+
return [];
|
|
272
|
+
previousItems.push(item);
|
|
280
273
|
const modifiedItem = modify(deepClone(item), restModifier);
|
|
281
274
|
if (item.id !== modifiedItem.id) {
|
|
282
275
|
const existingItems = await this.executeQuery(collectionName, { id: modifiedItem.id }, { limit: 1 });
|
|
283
276
|
if (existingItems.length > 0) {
|
|
284
|
-
|
|
277
|
+
return new Error(`Item with id ${modifiedItem.id} already exists`);
|
|
285
278
|
}
|
|
286
279
|
}
|
|
287
|
-
return modifiedItem;
|
|
280
|
+
return [modifiedItem];
|
|
288
281
|
}));
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
282
|
+
const modifiedItems = compact(result.filter((item) => !(item instanceof Error)).flat());
|
|
283
|
+
if (modifiedItems.length > 0) {
|
|
284
|
+
await storageAdapter.replace(modifiedItems);
|
|
285
|
+
await this.checkQueryUpdates(collectionName, [...modifiedItems, ...previousItems]);
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
292
288
|
};
|
|
293
|
-
|
|
289
|
+
updateMany = async (collectionName, parameters) => {
|
|
294
290
|
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
295
291
|
if (!storageAdapter)
|
|
296
292
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
293
|
+
const previousItems = [];
|
|
294
|
+
const result = await Promise.all(parameters.map(async ([selector, modifier]) => {
|
|
295
|
+
const items = await this.executeQuery(collectionName, selector);
|
|
296
|
+
if (items.length === 0)
|
|
297
|
+
return [];
|
|
298
|
+
const { $setOnInsert, ...restModifier } = modifier;
|
|
299
|
+
try {
|
|
300
|
+
const changedItems = await Promise.all(items.map(async (item) => {
|
|
301
|
+
const modifiedItem = modify(deepClone(item), restModifier);
|
|
302
|
+
if (item.id !== modifiedItem.id) {
|
|
303
|
+
const existingItems = await this.executeQuery(collectionName, { id: modifiedItem.id }, { limit: 1 });
|
|
304
|
+
if (existingItems.length > 0) {
|
|
305
|
+
throw new Error(`Item with id ${modifiedItem.id} already exists`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
previousItems.push(item);
|
|
309
|
+
return modifiedItem;
|
|
310
|
+
}));
|
|
311
|
+
return changedItems;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
return error;
|
|
314
|
+
}
|
|
315
|
+
}));
|
|
316
|
+
const modifiedItems = compact(result.filter((item) => !(item instanceof Error)).flat());
|
|
317
|
+
if (modifiedItems.length > 0) {
|
|
318
|
+
await storageAdapter.replace(modifiedItems);
|
|
319
|
+
await this.checkQueryUpdates(collectionName, [...modifiedItems, ...previousItems]);
|
|
320
|
+
}
|
|
321
|
+
return result;
|
|
322
|
+
};
|
|
323
|
+
replaceOne = async (collectionName, parameters) => {
|
|
324
|
+
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
325
|
+
if (!storageAdapter)
|
|
326
|
+
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
327
|
+
const previousItems = [];
|
|
328
|
+
const result = await Promise.all(parameters.map(async ([selector, replacement]) => {
|
|
329
|
+
const item = await this.executeQuery(collectionName, selector, { limit: 1 }).then((items) => items[0] ?? null);
|
|
330
|
+
if (item == null)
|
|
331
|
+
return [];
|
|
332
|
+
previousItems.push(item);
|
|
333
|
+
const modifiedItem = {
|
|
334
|
+
...replacement,
|
|
335
|
+
id: replacement.id ?? item.id
|
|
336
|
+
};
|
|
337
|
+
if (item.id !== modifiedItem.id) {
|
|
338
|
+
const existingItems = await this.executeQuery(collectionName, { id: modifiedItem.id }, { limit: 1 });
|
|
339
|
+
if (existingItems.length > 0) {
|
|
340
|
+
return new Error(`Item with id ${modifiedItem.id} already exists`);
|
|
341
|
+
}
|
|
308
342
|
}
|
|
343
|
+
return [modifiedItem];
|
|
344
|
+
}));
|
|
345
|
+
const modifiedItems = compact(result.filter((item) => !(item instanceof Error)).flat());
|
|
346
|
+
if (modifiedItems.length > 0) {
|
|
347
|
+
await storageAdapter.replace(modifiedItems);
|
|
348
|
+
await this.checkQueryUpdates(collectionName, [...modifiedItems, ...previousItems]);
|
|
309
349
|
}
|
|
310
|
-
|
|
311
|
-
await this.checkQueryUpdates(collectionName, [modifiedItem]);
|
|
312
|
-
return [modifiedItem];
|
|
350
|
+
return result;
|
|
313
351
|
};
|
|
314
|
-
removeOne = async (collectionName,
|
|
352
|
+
removeOne = async (collectionName, selectors) => {
|
|
315
353
|
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
316
354
|
if (!storageAdapter)
|
|
317
355
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
356
|
+
const result = await Promise.all(selectors.map(async ([selector]) => {
|
|
357
|
+
const item = await this.executeQuery(collectionName, selector, { limit: 1 }).then((items2) => items2[0] ?? null);
|
|
358
|
+
if (item == null)
|
|
359
|
+
return [];
|
|
360
|
+
return [item];
|
|
361
|
+
}));
|
|
362
|
+
const items = result.flat();
|
|
363
|
+
if (items.length > 0) {
|
|
364
|
+
await storageAdapter.remove(items);
|
|
365
|
+
await this.checkQueryUpdates(collectionName, items);
|
|
366
|
+
}
|
|
367
|
+
return result;
|
|
324
368
|
};
|
|
325
|
-
removeMany = async (collectionName,
|
|
369
|
+
removeMany = async (collectionName, selectors) => {
|
|
326
370
|
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
327
371
|
if (!storageAdapter)
|
|
328
372
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
373
|
+
const result = await Promise.all(selectors.map(async ([selector]) => this.executeQuery(collectionName, selector)));
|
|
374
|
+
const items = result.flat();
|
|
375
|
+
if (items.length > 0) {
|
|
376
|
+
await storageAdapter.remove(items);
|
|
377
|
+
await this.checkQueryUpdates(collectionName, items);
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
335
380
|
};
|
|
336
381
|
isReady = async (collectionName) => {
|
|
337
382
|
return this.storageAdapterReady.get(collectionName);
|
package/dist/index16.mjs
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import deepClone from "./index19.mjs";
|
|
2
|
-
import match from "./
|
|
2
|
+
import match from "./index23.mjs";
|
|
3
3
|
import modify from "./index7.mjs";
|
|
4
|
-
import queryId from "./
|
|
4
|
+
import queryId from "./index20.mjs";
|
|
5
5
|
import isEqual from "./index6.mjs";
|
|
6
|
-
import getIndexInfo from "./
|
|
6
|
+
import getIndexInfo from "./index22.mjs";
|
|
7
7
|
import getMatchingKeys from "./index26.mjs";
|
|
8
8
|
import sortItems from "./index25.mjs";
|
|
9
|
-
import project from "./
|
|
9
|
+
import project from "./index24.mjs";
|
|
10
10
|
function defaultMergeItems(a, b) {
|
|
11
11
|
return { ...a, ...b };
|
|
12
12
|
}
|
|
13
|
+
function selectorId(selector) {
|
|
14
|
+
return JSON.stringify(selector ?? {});
|
|
15
|
+
}
|
|
13
16
|
class AutoFetchDataAdapter {
|
|
14
17
|
options;
|
|
15
18
|
id;
|
|
@@ -73,7 +76,7 @@ class AutoFetchDataAdapter {
|
|
|
73
76
|
state: "active",
|
|
74
77
|
error: null
|
|
75
78
|
});
|
|
76
|
-
const key =
|
|
79
|
+
const key = selectorId(selector);
|
|
77
80
|
const perColObservers = this.activeObservers.get(collection.name);
|
|
78
81
|
const current = perColObservers?.get(key)?.count ?? 0;
|
|
79
82
|
perColObservers?.set(key, { selector, count: current + 1 });
|
|
@@ -90,7 +93,7 @@ class AutoFetchDataAdapter {
|
|
|
90
93
|
const qid = queryId(selector, options);
|
|
91
94
|
const registry = this.queries.get(collection.name);
|
|
92
95
|
registry?.delete(qid);
|
|
93
|
-
const key =
|
|
96
|
+
const key = selectorId(selector);
|
|
94
97
|
const perColObservers = this.activeObservers.get(collection.name);
|
|
95
98
|
const current = perColObservers?.get(key)?.count ?? 0;
|
|
96
99
|
const remaining = Math.max(0, current - 1);
|
|
@@ -140,7 +143,9 @@ class AutoFetchDataAdapter {
|
|
|
140
143
|
});
|
|
141
144
|
}
|
|
142
145
|
registry.get(qid)?.listeners.add(callback);
|
|
143
|
-
return () =>
|
|
146
|
+
return () => {
|
|
147
|
+
registry.get(qid)?.listeners.delete(callback);
|
|
148
|
+
};
|
|
144
149
|
};
|
|
145
150
|
return {
|
|
146
151
|
insert: async (item) => {
|
|
@@ -174,6 +179,23 @@ class AutoFetchDataAdapter {
|
|
|
174
179
|
getQueryError,
|
|
175
180
|
getQueryResult,
|
|
176
181
|
onQueryStateChange,
|
|
182
|
+
executeQuery: async (selector, options) => {
|
|
183
|
+
await ready;
|
|
184
|
+
registerQuery(selector, options);
|
|
185
|
+
await new Promise((resolve) => {
|
|
186
|
+
let stop = () => {
|
|
187
|
+
};
|
|
188
|
+
stop = onQueryStateChange(selector, options, (state) => {
|
|
189
|
+
if (state === "active")
|
|
190
|
+
return;
|
|
191
|
+
resolve();
|
|
192
|
+
stop();
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
const result = getQueryResult(selector, options);
|
|
196
|
+
unregisterQuery(selector, options);
|
|
197
|
+
return result;
|
|
198
|
+
},
|
|
177
199
|
dispose: async () => {
|
|
178
200
|
this.storageAdapters.delete(collection.name);
|
|
179
201
|
this.queries.delete(collection.name);
|
|
@@ -191,9 +213,6 @@ class AutoFetchDataAdapter {
|
|
|
191
213
|
};
|
|
192
214
|
}
|
|
193
215
|
// ===== Auto-fetch mechanics =====
|
|
194
|
-
selectorKey(selector) {
|
|
195
|
-
return JSON.stringify(selector ?? {});
|
|
196
|
-
}
|
|
197
216
|
async forceRefetchAll() {
|
|
198
217
|
const tasks = [];
|
|
199
218
|
for (const [collectionName, observers] of this.activeObservers.entries()) {
|
|
@@ -212,7 +231,7 @@ class AutoFetchDataAdapter {
|
|
|
212
231
|
throw new Error("AutoFetchDataAdapter: fetchQueryItems must resolve to { items: T[] }");
|
|
213
232
|
}
|
|
214
233
|
const ids = items.map((i) => i.id);
|
|
215
|
-
const selectorKey =
|
|
234
|
+
const selectorKey = selectorId(selector);
|
|
216
235
|
const selMap = this.selectorIds.get(collectionName);
|
|
217
236
|
const previous = selMap?.get(selectorKey) ?? /* @__PURE__ */ new Set();
|
|
218
237
|
ids.forEach((id) => previous.add(id));
|
|
@@ -225,7 +244,7 @@ class AutoFetchDataAdapter {
|
|
|
225
244
|
}
|
|
226
245
|
}
|
|
227
246
|
async purgeSelector(collectionName, selector) {
|
|
228
|
-
const selectorKey =
|
|
247
|
+
const selectorKey = selectorId(selector);
|
|
229
248
|
const selMap = this.selectorIds.get(collectionName);
|
|
230
249
|
const ids = selMap?.get(selectorKey);
|
|
231
250
|
selMap?.delete(selectorKey);
|
|
@@ -262,10 +281,7 @@ class AutoFetchDataAdapter {
|
|
|
262
281
|
const storage = this.storageAdapters.get(collectionName);
|
|
263
282
|
if (!storage)
|
|
264
283
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
265
|
-
await Promise.all(
|
|
266
|
-
storage.createIndex("id"),
|
|
267
|
-
...indices.map((field) => storage.createIndex(field))
|
|
268
|
-
]);
|
|
284
|
+
await Promise.all(indices.map((field) => storage.createIndex(field)));
|
|
269
285
|
await storage.setup();
|
|
270
286
|
}
|
|
271
287
|
ensureStorageAdapter(name) {
|
|
@@ -283,24 +299,16 @@ class AutoFetchDataAdapter {
|
|
|
283
299
|
for (const query of registry.values()) {
|
|
284
300
|
if (!isEqual(query.selector, selector))
|
|
285
301
|
continue;
|
|
286
|
-
query.
|
|
287
|
-
query.error = error;
|
|
288
|
-
for (const callback of query.listeners) {
|
|
289
|
-
try {
|
|
290
|
-
callback(state);
|
|
291
|
-
} catch (error_) {
|
|
292
|
-
this.onError(error_);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
302
|
+
this.publishState(collectionName, queryId(query.selector, query.options), state, error);
|
|
295
303
|
}
|
|
296
304
|
}
|
|
297
305
|
publishState(collectionName, qid, state, error) {
|
|
298
|
-
const
|
|
299
|
-
if (!
|
|
306
|
+
const query = this.queries.get(collectionName)?.get(qid);
|
|
307
|
+
if (!query)
|
|
300
308
|
return;
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
for (const callback of
|
|
309
|
+
query.state = state;
|
|
310
|
+
query.error = error;
|
|
311
|
+
for (const callback of query.listeners) {
|
|
304
312
|
try {
|
|
305
313
|
callback(state);
|
|
306
314
|
} catch (error_) {
|
|
@@ -309,10 +317,11 @@ class AutoFetchDataAdapter {
|
|
|
309
317
|
}
|
|
310
318
|
}
|
|
311
319
|
publishResult(collectionName, qid, items) {
|
|
312
|
-
const
|
|
313
|
-
if (!
|
|
320
|
+
const query = this.queries.get(collectionName)?.get(qid);
|
|
321
|
+
if (!query)
|
|
314
322
|
return;
|
|
315
|
-
|
|
323
|
+
query.items = items;
|
|
324
|
+
this.queries.get(collectionName)?.set(qid, query);
|
|
316
325
|
}
|
|
317
326
|
async fulfillQuery(collectionName, selector, options) {
|
|
318
327
|
const qid = queryId(selector, options);
|
|
@@ -471,7 +480,7 @@ class AutoFetchDataAdapter {
|
|
|
471
480
|
throw new Error(`Item with id ${String(modified.id)} already exists`);
|
|
472
481
|
}
|
|
473
482
|
await storage.replace([modified]);
|
|
474
|
-
await this.checkQueryUpdates(collectionName, [modified]);
|
|
483
|
+
await this.checkQueryUpdates(collectionName, [item, modified]);
|
|
475
484
|
return [modified];
|
|
476
485
|
}
|
|
477
486
|
async updateMany(collectionName, selector, modifier) {
|
|
@@ -492,7 +501,7 @@ class AutoFetchDataAdapter {
|
|
|
492
501
|
return modified;
|
|
493
502
|
}));
|
|
494
503
|
await storage.replace(changed);
|
|
495
|
-
await this.checkQueryUpdates(collectionName, changed);
|
|
504
|
+
await this.checkQueryUpdates(collectionName, [...items, ...changed]);
|
|
496
505
|
return changed;
|
|
497
506
|
}
|
|
498
507
|
async replaceOne(collectionName, selector, replacement) {
|
|
@@ -510,7 +519,7 @@ class AutoFetchDataAdapter {
|
|
|
510
519
|
throw new Error(`Item with id ${String(modified.id)} already exists`);
|
|
511
520
|
}
|
|
512
521
|
await storage.replace([modified]);
|
|
513
|
-
await this.checkQueryUpdates(collectionName, [modified]);
|
|
522
|
+
await this.checkQueryUpdates(collectionName, [item, modified]);
|
|
514
523
|
return [modified];
|
|
515
524
|
}
|
|
516
525
|
async removeOne(collectionName, selector) {
|
package/dist/index17.mjs
CHANGED
package/dist/index2.mjs
CHANGED
|
@@ -60,9 +60,12 @@ class Cursor {
|
|
|
60
60
|
return this.options.transform(item);
|
|
61
61
|
}
|
|
62
62
|
depend(changeEvents) {
|
|
63
|
-
if (
|
|
63
|
+
if (this.options?.async)
|
|
64
64
|
return;
|
|
65
|
-
if (!isInReactiveScope(this.options.reactive))
|
|
65
|
+
if (!isInReactiveScope(this.options.reactive)) {
|
|
66
|
+
console.warn("Cursor.depend() called outside of a reactive scope without async option; consider using { async: true } or wrapping in a reactive scope");
|
|
67
|
+
}
|
|
68
|
+
if (!this.options.reactive)
|
|
66
69
|
return;
|
|
67
70
|
const signal = this.options.reactive.create();
|
|
68
71
|
signal.depend();
|
package/dist/index20.mjs
CHANGED
|
@@ -1,105 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function createIndex(field) {
|
|
6
|
-
const index = /* @__PURE__ */ new Map();
|
|
7
|
-
const ensureSet = (key) => {
|
|
8
|
-
let set = index.get(key);
|
|
9
|
-
if (!set) {
|
|
10
|
-
set = /* @__PURE__ */ new Set();
|
|
11
|
-
index.set(key, set);
|
|
12
|
-
}
|
|
13
|
-
return set;
|
|
14
|
-
};
|
|
15
|
-
return createIndexProvider({
|
|
16
|
-
query(selector) {
|
|
17
|
-
if (!Object.hasOwnProperty.call(selector, field)) {
|
|
18
|
-
return { matched: false };
|
|
19
|
-
}
|
|
20
|
-
const fieldSelector = selector[field];
|
|
21
|
-
const filteresForNull = fieldSelector == null || fieldSelector.$exists === false;
|
|
22
|
-
const keys = filteresForNull ? { include: null, exclude: [...index.keys()].filter((key) => key != null) } : getMatchingKeys(field, selector);
|
|
23
|
-
if (keys.include == null && keys.exclude == null)
|
|
24
|
-
return { matched: false };
|
|
25
|
-
let includedIds = [];
|
|
26
|
-
if (keys.include == null) {
|
|
27
|
-
for (const set of index.values()) {
|
|
28
|
-
for (const pos of set) {
|
|
29
|
-
includedIds.push(pos);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
} else {
|
|
33
|
-
for (const key of keys.include) {
|
|
34
|
-
const posSet = index.get(key);
|
|
35
|
-
if (posSet) {
|
|
36
|
-
for (const pos of posSet) {
|
|
37
|
-
includedIds.push(pos);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (keys.exclude != null) {
|
|
43
|
-
const excludeIds = /* @__PURE__ */ new Set();
|
|
44
|
-
for (const key of keys.exclude) {
|
|
45
|
-
const posSet = index.get(key);
|
|
46
|
-
if (posSet) {
|
|
47
|
-
for (const pos of posSet) {
|
|
48
|
-
excludeIds.add(pos);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
includedIds = includedIds.filter((pos) => !excludeIds.has(pos));
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
matched: true,
|
|
56
|
-
ids: includedIds,
|
|
57
|
-
fields: [field],
|
|
58
|
-
keepSelector: filteresForNull
|
|
59
|
-
};
|
|
60
|
-
},
|
|
61
|
-
rebuild(items) {
|
|
62
|
-
index.clear();
|
|
63
|
-
items.forEach((item) => {
|
|
64
|
-
const value = serializeValue(get(item, field));
|
|
65
|
-
ensureSet(value).add(item.id);
|
|
66
|
-
});
|
|
67
|
-
},
|
|
68
|
-
// NEW: delta methods
|
|
69
|
-
insert(items) {
|
|
70
|
-
for (const item of items) {
|
|
71
|
-
const value = serializeValue(get(item, field));
|
|
72
|
-
ensureSet(value).add(item.id);
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
remove(items) {
|
|
76
|
-
for (const item of items) {
|
|
77
|
-
const value = serializeValue(get(item, field));
|
|
78
|
-
const set = index.get(value);
|
|
79
|
-
if (!set)
|
|
80
|
-
continue;
|
|
81
|
-
set.delete(item.id);
|
|
82
|
-
if (set.size === 0)
|
|
83
|
-
index.delete(value);
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
update(pairs) {
|
|
87
|
-
for (const { oldItem, newItem } of pairs) {
|
|
88
|
-
const oldValue = serializeValue(get(oldItem, field));
|
|
89
|
-
const newValue = serializeValue(get(newItem, field));
|
|
90
|
-
if (oldValue === newValue)
|
|
91
|
-
continue;
|
|
92
|
-
const oldSet = index.get(oldValue);
|
|
93
|
-
if (oldSet) {
|
|
94
|
-
oldSet.delete(oldItem.id);
|
|
95
|
-
if (oldSet.size === 0)
|
|
96
|
-
index.delete(oldValue);
|
|
97
|
-
}
|
|
98
|
-
ensureSet(newValue).add(newItem.id);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
});
|
|
1
|
+
function queryId(selector, options) {
|
|
2
|
+
const selectorId = JSON.stringify(selector);
|
|
3
|
+
const optionsId = options == null ? -1 : JSON.stringify(options);
|
|
4
|
+
return `${selectorId}:${optionsId}`;
|
|
102
5
|
}
|
|
103
6
|
export {
|
|
104
|
-
|
|
7
|
+
queryId as default
|
|
105
8
|
};
|