@signaldb/core 2.0.0-beta.18 → 2.0.0-beta.19

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/index33.mjs CHANGED
@@ -1,72 +1,53 @@
1
- //#region src/utils/batchOnNextTick.ts
1
+ import getMatchingKeys from "./index14.mjs";
2
+ //#region src/utils/storageIndexQuery.ts
2
3
  /**
3
- * Groups multiple calls by key and flushes them on the next tick (macrotask).
4
- * @param onFlush - Function that will be called with the key and all queued items when flushing.
5
- * @returns An object with `enqueue` and `flush` methods.
6
- * @example
7
- * const batcher = batchOnNextTick<string>(async (key, items) => {
8
- * // items is an array of { args, resolve, reject }
9
- * // do something once with all args...
10
- * })
4
+ * Builds the index provider a data adapter uses to narrow a selector down through
5
+ * a storage adapter's index.
11
6
  *
12
- * batcher.enqueue("my-key", [arg1, arg2])
7
+ * Every adapter that keeps its data in a `StorageAdapter` needs exactly this, and
8
+ * each of them used to carry its own copy — three transcriptions of one set of
9
+ * rules about null, `$exists`, inclusion and exclusion, which is how they drift
10
+ * apart without anyone noticing. The index is keyed by `serializeValue(value)`,
11
+ * which is what `getMatchingKeys` produces, so the two only agree while they stay
12
+ * in one place.
13
+ * @template T - The type of the items in the collection.
14
+ * @template I - The type of the unique identifier for the items.
15
+ * @param storage - The storage adapter holding the index.
16
+ * @param field - The indexed field this provider answers for.
17
+ * @returns A query function for `getIndexInfo`.
13
18
  */
14
- function batchOnNextTick(onFlush) {
15
- const queues = /* @__PURE__ */ new Map();
16
- /**
17
- * Enqueue a call with the given key and arguments.
18
- * @param key key to group calls
19
- * @param args arguments for the call
20
- * @returns A promise that resolves or rejects when the call is flushed.
21
- */
22
- function enqueue(key, args) {
23
- return new Promise((resolve, reject) => {
24
- let q = queues.get(key);
25
- if (!q) {
26
- q = {
27
- timer: null,
28
- items: [],
29
- flush: () => flush(key)
30
- };
31
- queues.set(key, q);
32
- }
33
- q.items.push({
34
- args,
35
- resolve,
36
- reject
37
- });
38
- if (q.timer == null) q.timer = setTimeout(() => {
39
- q.timer = null;
40
- q.flush();
41
- }, 0);
42
- });
43
- }
44
- /**
45
- * Flush the queue for the given key immediately.
46
- * @param key key to flush
47
- * @returns A promise that resolves when the flush is complete.
48
- */
49
- async function flush(key) {
50
- const q = queues.get(key);
51
- if (!q || q.items.length === 0) return;
52
- if (q.timer != null) {
53
- clearTimeout(q.timer);
54
- q.timer = null;
19
+ function storageIndexQuery(storage, field) {
20
+ return async (flatSelector) => {
21
+ if (!Object.hasOwnProperty.call(flatSelector, field)) return { matched: false };
22
+ const index = await storage.readIndex(field);
23
+ const fieldSelector = flatSelector[field];
24
+ const filtersForNull = fieldSelector == null || fieldSelector.$exists === false;
25
+ const keys = filtersForNull ? {
26
+ include: null,
27
+ exclude: [...index.keys()].filter((key) => key != null)
28
+ } : getMatchingKeys(field, flatSelector);
29
+ if (keys.include == null && keys.exclude == null) return { matched: false };
30
+ let includedIds = [];
31
+ if (keys.include == null) for (const set of index.values()) for (const id of set) includedIds.push(id);
32
+ else for (const key of keys.include) {
33
+ const idSet = index.get(key);
34
+ if (idSet) for (const id of idSet) includedIds.push(id);
55
35
  }
56
- const items = q.items.splice(0);
57
- onFlush(key, items.map((i) => i.args)).then((results) => {
58
- for (const [index, result] of results.entries()) {
59
- const { resolve } = items[index];
60
- resolve(result);
36
+ if (keys.exclude != null) {
37
+ const excludedIds = /* @__PURE__ */ new Set();
38
+ for (const key of keys.exclude) {
39
+ const idSet = index.get(key);
40
+ if (idSet) for (const id of idSet) excludedIds.add(id);
61
41
  }
62
- }).catch((error) => {
63
- for (const { reject } of items) reject(error);
64
- });
65
- }
66
- return {
67
- enqueue,
68
- flush
42
+ includedIds = includedIds.filter((id) => !excludedIds.has(id));
43
+ }
44
+ return {
45
+ matched: true,
46
+ ids: includedIds,
47
+ fields: [field],
48
+ keepSelector: filtersForNull
49
+ };
69
50
  };
70
51
  }
71
52
  //#endregion
72
- export { batchOnNextTick as default };
53
+ export { storageIndexQuery as default };