@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.
Files changed (52) hide show
  1. package/dist/.vite/manifest.json +25 -12
  2. package/dist/AutoFetchDataAdapter.d.ts +0 -1
  3. package/dist/Collection/index.d.ts +2 -0
  4. package/dist/DataAdapter.d.ts +7 -6
  5. package/dist/DefaultDataAdapter.d.ts +1 -0
  6. package/dist/WorkerDataAdapter.d.ts +4 -1
  7. package/dist/WorkerDataAdapterHost.d.ts +9 -6
  8. package/dist/index.cjs12.js +32 -21
  9. package/dist/index.cjs13.js +25 -13
  10. package/dist/index.cjs14.js +31 -37
  11. package/dist/index.cjs15.js +120 -75
  12. package/dist/index.cjs16.js +45 -36
  13. package/dist/index.cjs17.js +1 -1
  14. package/dist/index.cjs2.js +5 -2
  15. package/dist/index.cjs20.js +5 -102
  16. package/dist/index.cjs21.js +93 -118
  17. package/dist/index.cjs22.js +127 -5
  18. package/dist/index.cjs23.js +5 -25
  19. package/dist/index.cjs24.js +25 -5
  20. package/dist/index.cjs26.js +1 -1
  21. package/dist/index.cjs27.js +44 -3
  22. package/dist/index.cjs28.js +6 -5
  23. package/dist/index.cjs29.js +7 -27
  24. package/dist/index.cjs3.js +25 -21
  25. package/dist/index.cjs30.js +3 -40
  26. package/dist/index.cjs31.js +5 -7
  27. package/dist/index.cjs32.js +29 -0
  28. package/dist/index.cjs33.js +42 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index12.mjs +32 -21
  31. package/dist/index13.mjs +25 -13
  32. package/dist/index14.mjs +31 -37
  33. package/dist/index15.mjs +120 -75
  34. package/dist/index16.mjs +45 -36
  35. package/dist/index17.mjs +1 -1
  36. package/dist/index2.mjs +5 -2
  37. package/dist/index20.mjs +5 -102
  38. package/dist/index21.mjs +93 -117
  39. package/dist/index22.mjs +126 -5
  40. package/dist/index23.mjs +5 -25
  41. package/dist/index24.mjs +25 -5
  42. package/dist/index26.mjs +1 -1
  43. package/dist/index27.mjs +44 -3
  44. package/dist/index28.mjs +6 -5
  45. package/dist/index29.mjs +7 -27
  46. package/dist/index3.mjs +25 -21
  47. package/dist/index30.mjs +3 -40
  48. package/dist/index31.mjs +5 -7
  49. package/dist/index32.mjs +30 -0
  50. package/dist/index33.mjs +43 -0
  51. package/dist/utils/batchOnNextTick.d.ts +16 -0
  52. 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 "./index22.mjs";
2
+ import match from "./index23.mjs";
3
3
  import modify from "./index7.mjs";
4
- import queryId from "./index24.mjs";
4
+ import queryId from "./index20.mjs";
5
5
  import isEqual from "./index6.mjs";
6
- import getIndexInfo from "./index21.mjs";
6
+ import getIndexInfo from "./index22.mjs";
7
7
  import getMatchingKeys from "./index26.mjs";
8
8
  import sortItems from "./index25.mjs";
9
- import project from "./index23.mjs";
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, newItem) => {
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 item = await this.executeQuery(collectionName, selector, { limit: 1 }).then((items) => items[0] ?? null);
257
- const { $setOnInsert, ...restModifier } = modifier;
258
- if (item == null)
259
- return [];
260
- const modifiedItem = modify(deepClone(item), restModifier);
261
- if (item.id !== modifiedItem.id) {
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
- await storageAdapter.replace([modifiedItem]);
268
- await this.checkQueryUpdates(collectionName, [modifiedItem]);
269
- return [modifiedItem];
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
- updateMany = async (collectionName, selector, modifier) => {
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 items = await this.executeQuery(collectionName, selector);
276
- if (items.length === 0)
277
- return [];
278
- const { $setOnInsert, ...restModifier } = modifier;
279
- const changedItems = await Promise.all(items.map(async (item) => {
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
- throw new Error(`Item with id ${modifiedItem.id} already exists`);
277
+ return new Error(`Item with id ${modifiedItem.id} already exists`);
285
278
  }
286
279
  }
287
- return modifiedItem;
280
+ return [modifiedItem];
288
281
  }));
289
- await storageAdapter.replace(changedItems);
290
- await this.checkQueryUpdates(collectionName, changedItems);
291
- return changedItems;
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
- replaceOne = async (collectionName, selector, replacement) => {
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 item = await this.executeQuery(collectionName, selector, { limit: 1 }).then((items) => items[0] ?? null);
298
- if (item == null)
299
- return [];
300
- const modifiedItem = {
301
- ...replacement,
302
- id: replacement.id ?? item.id
303
- };
304
- if (item.id !== modifiedItem.id) {
305
- const existingItems = await this.executeQuery(collectionName, { id: modifiedItem.id }, { limit: 1 });
306
- if (existingItems.length > 0) {
307
- throw new Error(`Item with id ${modifiedItem.id} already exists`);
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
- await storageAdapter.replace([modifiedItem]);
311
- await this.checkQueryUpdates(collectionName, [modifiedItem]);
312
- return [modifiedItem];
350
+ return result;
313
351
  };
314
- removeOne = async (collectionName, selector) => {
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 item = await this.executeQuery(collectionName, selector, { limit: 1 }).then((items) => items[0] ?? null);
319
- if (item == null)
320
- return [];
321
- await storageAdapter.remove([item]);
322
- await this.checkQueryUpdates(collectionName, [item]);
323
- return [item];
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, selector) => {
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 items = await this.executeQuery(collectionName, selector);
330
- if (items.length === 0)
331
- return [];
332
- await storageAdapter.remove(items);
333
- await this.checkQueryUpdates(collectionName, items);
334
- return items;
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 "./index22.mjs";
2
+ import match from "./index23.mjs";
3
3
  import modify from "./index7.mjs";
4
- import queryId from "./index24.mjs";
4
+ import queryId from "./index20.mjs";
5
5
  import isEqual from "./index6.mjs";
6
- import getIndexInfo from "./index21.mjs";
6
+ import getIndexInfo from "./index22.mjs";
7
7
  import getMatchingKeys from "./index26.mjs";
8
8
  import sortItems from "./index25.mjs";
9
- import project from "./index23.mjs";
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 = this.selectorKey(selector);
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 = this.selectorKey(selector);
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 () => registry.get(qid)?.listeners.delete(callback);
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 = this.selectorKey(selector);
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 = this.selectorKey(selector);
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.state = state;
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 rec = this.queries.get(collectionName)?.get(qid);
299
- if (!rec)
306
+ const query = this.queries.get(collectionName)?.get(qid);
307
+ if (!query)
300
308
  return;
301
- rec.state = state;
302
- rec.error = error;
303
- for (const callback of rec.listeners) {
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 rec = this.queries.get(collectionName)?.get(qid);
313
- if (!rec)
320
+ const query = this.queries.get(collectionName)?.get(qid);
321
+ if (!query)
314
322
  return;
315
- rec.items = items;
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
@@ -1,5 +1,5 @@
1
1
  import isEqual from "./index6.mjs";
2
- import uniqueBy from "./index31.mjs";
2
+ import uniqueBy from "./index29.mjs";
3
3
  class Observer {
4
4
  previousItems = [];
5
5
  callbacks;
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 (!this.options.reactive)
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
- import createIndexProvider from "./index27.mjs";
2
- import get from "./index10.mjs";
3
- import getMatchingKeys from "./index26.mjs";
4
- import serializeValue from "./index11.mjs";
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
- createIndex as default
7
+ queryId as default
105
8
  };