@signaldb/core 2.0.0-beta.0 → 2.0.0-beta.2
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 +24 -11
- package/dist/AsyncDataAdapter.d.ts +1 -1
- package/dist/AutoFetchDataAdapter.d.ts +1 -2
- package/dist/Collection/Cursor.d.ts +3 -2
- package/dist/Collection/index.d.ts +17 -12
- package/dist/Collection/types.d.ts +1 -0
- package/dist/DataAdapter.d.ts +9 -7
- package/dist/DefaultDataAdapter.d.ts +2 -1
- package/dist/WorkerDataAdapter.d.ts +5 -2
- package/dist/WorkerDataAdapterHost.d.ts +9 -6
- package/dist/index.cjs12.js +35 -21
- package/dist/index.cjs13.js +27 -15
- package/dist/index.cjs14.js +72 -56
- package/dist/index.cjs15.js +122 -75
- package/dist/index.cjs16.js +45 -36
- package/dist/index.cjs17.js +4 -2
- package/dist/index.cjs19.js +0 -1
- package/dist/index.cjs2.js +6 -2
- package/dist/index.cjs20.js +14 -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.cjs27.js +44 -3
- package/dist/index.cjs28.js +6 -5
- package/dist/index.cjs29.js +5 -27
- package/dist/index.cjs3.js +41 -22
- package/dist/index.cjs31.js +27 -7
- package/dist/index.cjs32.js +9 -0
- package/dist/index.cjs33.js +5 -0
- package/dist/index.d.ts +2 -1
- package/dist/index12.mjs +35 -21
- package/dist/index13.mjs +27 -15
- package/dist/index14.mjs +72 -56
- package/dist/index15.mjs +122 -75
- package/dist/index16.mjs +45 -36
- package/dist/index17.mjs +4 -2
- package/dist/index19.mjs +0 -1
- package/dist/index2.mjs +6 -2
- package/dist/index20.mjs +14 -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/index27.mjs +44 -3
- package/dist/index28.mjs +6 -5
- package/dist/index29.mjs +5 -27
- package/dist/index3.mjs +41 -22
- package/dist/index31.mjs +27 -7
- package/dist/index32.mjs +10 -0
- package/dist/index33.mjs +6 -0
- package/dist/utils/batchOnNextTick.d.ts +16 -0
- package/dist/utils/deepClone.d.ts +1 -1
- package/package.json +3 -3
package/dist/index.cjs16.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const deepClone = require("./index.cjs19.js");
|
|
3
|
-
const match = require("./index.
|
|
3
|
+
const match = require("./index.cjs23.js");
|
|
4
4
|
const modify = require("./index.cjs7.js");
|
|
5
|
-
const queryId = require("./index.
|
|
5
|
+
const queryId = require("./index.cjs20.js");
|
|
6
6
|
const isEqual = require("./index.cjs6.js");
|
|
7
|
-
const getIndexInfo = require("./index.
|
|
7
|
+
const getIndexInfo = require("./index.cjs22.js");
|
|
8
8
|
const getMatchingKeys = require("./index.cjs26.js");
|
|
9
9
|
const sortItems = require("./index.cjs25.js");
|
|
10
|
-
const project = require("./index.
|
|
10
|
+
const project = require("./index.cjs24.js");
|
|
11
11
|
function defaultMergeItems(a, b) {
|
|
12
12
|
return { ...a, ...b };
|
|
13
13
|
}
|
|
14
|
+
function selectorId(selector) {
|
|
15
|
+
return JSON.stringify(selector ?? {});
|
|
16
|
+
}
|
|
14
17
|
class AutoFetchDataAdapter {
|
|
15
18
|
options;
|
|
16
19
|
id;
|
|
@@ -74,7 +77,7 @@ class AutoFetchDataAdapter {
|
|
|
74
77
|
state: "active",
|
|
75
78
|
error: null
|
|
76
79
|
});
|
|
77
|
-
const key =
|
|
80
|
+
const key = selectorId(selector);
|
|
78
81
|
const perColObservers = this.activeObservers.get(collection.name);
|
|
79
82
|
const current = perColObservers?.get(key)?.count ?? 0;
|
|
80
83
|
perColObservers?.set(key, { selector, count: current + 1 });
|
|
@@ -91,7 +94,7 @@ class AutoFetchDataAdapter {
|
|
|
91
94
|
const qid = queryId(selector, options);
|
|
92
95
|
const registry = this.queries.get(collection.name);
|
|
93
96
|
registry?.delete(qid);
|
|
94
|
-
const key =
|
|
97
|
+
const key = selectorId(selector);
|
|
95
98
|
const perColObservers = this.activeObservers.get(collection.name);
|
|
96
99
|
const current = perColObservers?.get(key)?.count ?? 0;
|
|
97
100
|
const remaining = Math.max(0, current - 1);
|
|
@@ -141,7 +144,9 @@ class AutoFetchDataAdapter {
|
|
|
141
144
|
});
|
|
142
145
|
}
|
|
143
146
|
registry.get(qid)?.listeners.add(callback);
|
|
144
|
-
return () =>
|
|
147
|
+
return () => {
|
|
148
|
+
registry.get(qid)?.listeners.delete(callback);
|
|
149
|
+
};
|
|
145
150
|
};
|
|
146
151
|
return {
|
|
147
152
|
insert: async (item) => {
|
|
@@ -175,6 +180,23 @@ class AutoFetchDataAdapter {
|
|
|
175
180
|
getQueryError,
|
|
176
181
|
getQueryResult,
|
|
177
182
|
onQueryStateChange,
|
|
183
|
+
executeQuery: async (selector, options) => {
|
|
184
|
+
await ready;
|
|
185
|
+
registerQuery(selector, options);
|
|
186
|
+
await new Promise((resolve) => {
|
|
187
|
+
let stop = () => {
|
|
188
|
+
};
|
|
189
|
+
stop = onQueryStateChange(selector, options, (state) => {
|
|
190
|
+
if (state === "active")
|
|
191
|
+
return;
|
|
192
|
+
resolve();
|
|
193
|
+
stop();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
const result = getQueryResult(selector, options);
|
|
197
|
+
unregisterQuery(selector, options);
|
|
198
|
+
return result;
|
|
199
|
+
},
|
|
178
200
|
dispose: async () => {
|
|
179
201
|
this.storageAdapters.delete(collection.name);
|
|
180
202
|
this.queries.delete(collection.name);
|
|
@@ -192,9 +214,6 @@ class AutoFetchDataAdapter {
|
|
|
192
214
|
};
|
|
193
215
|
}
|
|
194
216
|
// ===== Auto-fetch mechanics =====
|
|
195
|
-
selectorKey(selector) {
|
|
196
|
-
return JSON.stringify(selector ?? {});
|
|
197
|
-
}
|
|
198
217
|
async forceRefetchAll() {
|
|
199
218
|
const tasks = [];
|
|
200
219
|
for (const [collectionName, observers] of this.activeObservers.entries()) {
|
|
@@ -213,7 +232,7 @@ class AutoFetchDataAdapter {
|
|
|
213
232
|
throw new Error("AutoFetchDataAdapter: fetchQueryItems must resolve to { items: T[] }");
|
|
214
233
|
}
|
|
215
234
|
const ids = items.map((i) => i.id);
|
|
216
|
-
const selectorKey =
|
|
235
|
+
const selectorKey = selectorId(selector);
|
|
217
236
|
const selMap = this.selectorIds.get(collectionName);
|
|
218
237
|
const previous = selMap?.get(selectorKey) ?? /* @__PURE__ */ new Set();
|
|
219
238
|
ids.forEach((id) => previous.add(id));
|
|
@@ -226,7 +245,7 @@ class AutoFetchDataAdapter {
|
|
|
226
245
|
}
|
|
227
246
|
}
|
|
228
247
|
async purgeSelector(collectionName, selector) {
|
|
229
|
-
const selectorKey =
|
|
248
|
+
const selectorKey = selectorId(selector);
|
|
230
249
|
const selMap = this.selectorIds.get(collectionName);
|
|
231
250
|
const ids = selMap?.get(selectorKey);
|
|
232
251
|
selMap?.delete(selectorKey);
|
|
@@ -263,10 +282,7 @@ class AutoFetchDataAdapter {
|
|
|
263
282
|
const storage = this.storageAdapters.get(collectionName);
|
|
264
283
|
if (!storage)
|
|
265
284
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
266
|
-
await Promise.all(
|
|
267
|
-
storage.createIndex("id"),
|
|
268
|
-
...indices.map((field) => storage.createIndex(field))
|
|
269
|
-
]);
|
|
285
|
+
await Promise.all(indices.map((field) => storage.createIndex(field)));
|
|
270
286
|
await storage.setup();
|
|
271
287
|
}
|
|
272
288
|
ensureStorageAdapter(name) {
|
|
@@ -284,24 +300,16 @@ class AutoFetchDataAdapter {
|
|
|
284
300
|
for (const query of registry.values()) {
|
|
285
301
|
if (!isEqual(query.selector, selector))
|
|
286
302
|
continue;
|
|
287
|
-
query.
|
|
288
|
-
query.error = error;
|
|
289
|
-
for (const callback of query.listeners) {
|
|
290
|
-
try {
|
|
291
|
-
callback(state);
|
|
292
|
-
} catch (error_) {
|
|
293
|
-
this.onError(error_);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
303
|
+
this.publishState(collectionName, queryId(query.selector, query.options), state, error);
|
|
296
304
|
}
|
|
297
305
|
}
|
|
298
306
|
publishState(collectionName, qid, state, error) {
|
|
299
|
-
const
|
|
300
|
-
if (!
|
|
307
|
+
const query = this.queries.get(collectionName)?.get(qid);
|
|
308
|
+
if (!query)
|
|
301
309
|
return;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
for (const callback of
|
|
310
|
+
query.state = state;
|
|
311
|
+
query.error = error;
|
|
312
|
+
for (const callback of query.listeners) {
|
|
305
313
|
try {
|
|
306
314
|
callback(state);
|
|
307
315
|
} catch (error_) {
|
|
@@ -310,10 +318,11 @@ class AutoFetchDataAdapter {
|
|
|
310
318
|
}
|
|
311
319
|
}
|
|
312
320
|
publishResult(collectionName, qid, items) {
|
|
313
|
-
const
|
|
314
|
-
if (!
|
|
321
|
+
const query = this.queries.get(collectionName)?.get(qid);
|
|
322
|
+
if (!query)
|
|
315
323
|
return;
|
|
316
|
-
|
|
324
|
+
query.items = items;
|
|
325
|
+
this.queries.get(collectionName)?.set(qid, query);
|
|
317
326
|
}
|
|
318
327
|
async fulfillQuery(collectionName, selector, options) {
|
|
319
328
|
const qid = queryId(selector, options);
|
|
@@ -472,7 +481,7 @@ class AutoFetchDataAdapter {
|
|
|
472
481
|
throw new Error(`Item with id ${String(modified.id)} already exists`);
|
|
473
482
|
}
|
|
474
483
|
await storage.replace([modified]);
|
|
475
|
-
await this.checkQueryUpdates(collectionName, [modified]);
|
|
484
|
+
await this.checkQueryUpdates(collectionName, [item, modified]);
|
|
476
485
|
return [modified];
|
|
477
486
|
}
|
|
478
487
|
async updateMany(collectionName, selector, modifier) {
|
|
@@ -493,7 +502,7 @@ class AutoFetchDataAdapter {
|
|
|
493
502
|
return modified;
|
|
494
503
|
}));
|
|
495
504
|
await storage.replace(changed);
|
|
496
|
-
await this.checkQueryUpdates(collectionName, changed);
|
|
505
|
+
await this.checkQueryUpdates(collectionName, [...items, ...changed]);
|
|
497
506
|
return changed;
|
|
498
507
|
}
|
|
499
508
|
async replaceOne(collectionName, selector, replacement) {
|
|
@@ -511,7 +520,7 @@ class AutoFetchDataAdapter {
|
|
|
511
520
|
throw new Error(`Item with id ${String(modified.id)} already exists`);
|
|
512
521
|
}
|
|
513
522
|
await storage.replace([modified]);
|
|
514
|
-
await this.checkQueryUpdates(collectionName, [modified]);
|
|
523
|
+
await this.checkQueryUpdates(collectionName, [item, modified]);
|
|
515
524
|
return [modified];
|
|
516
525
|
}
|
|
517
526
|
async removeOne(collectionName, selector) {
|
package/dist/index.cjs17.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const isEqual = require("./index.cjs6.js");
|
|
3
|
-
const uniqueBy = require("./index.
|
|
3
|
+
const uniqueBy = require("./index.cjs32.js");
|
|
4
4
|
class Observer {
|
|
5
5
|
previousItems = [];
|
|
6
6
|
callbacks;
|
|
@@ -53,7 +53,9 @@ class Observer {
|
|
|
53
53
|
runChecks(getItems) {
|
|
54
54
|
const result = getItems();
|
|
55
55
|
if (result instanceof Promise) {
|
|
56
|
-
|
|
56
|
+
result.then((newItems) => this.checkItems(newItems)).catch((error) => {
|
|
57
|
+
console.error("Error while asynchronously querying items", error);
|
|
58
|
+
});
|
|
57
59
|
} else {
|
|
58
60
|
this.checkItems(result);
|
|
59
61
|
}
|
package/dist/index.cjs19.js
CHANGED
package/dist/index.cjs2.js
CHANGED
|
@@ -28,6 +28,7 @@ class Cursor {
|
|
|
28
28
|
* @param options.limit - The maximum number of items to return in the result set.
|
|
29
29
|
* @param options.reactive - A reactivity adapter to enable observing changes in the cursor's result set.
|
|
30
30
|
* @param options.fieldTracking - A boolean to enable fine-grained field tracking for reactivity.
|
|
31
|
+
* @param options.transformAll - A function that will be able to solve the n+1 problem
|
|
31
32
|
*/
|
|
32
33
|
constructor(getItems, options) {
|
|
33
34
|
this.getItems = getItems;
|
|
@@ -62,9 +63,12 @@ class Cursor {
|
|
|
62
63
|
return this.options.transform(item);
|
|
63
64
|
}
|
|
64
65
|
depend(changeEvents) {
|
|
65
|
-
if (
|
|
66
|
+
if (this.options?.async)
|
|
66
67
|
return;
|
|
67
|
-
if (!isInReactiveScope(this.options.reactive))
|
|
68
|
+
if (!isInReactiveScope(this.options.reactive)) {
|
|
69
|
+
console.warn("Cursor.depend() called outside of a reactive scope without async option; consider using { async: true } or wrapping in a reactive scope");
|
|
70
|
+
}
|
|
71
|
+
if (!this.options.reactive)
|
|
68
72
|
return;
|
|
69
73
|
const signal = this.options.reactive.create();
|
|
70
74
|
signal.depend();
|
package/dist/index.cjs20.js
CHANGED
|
@@ -1,104 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (!set) {
|
|
11
|
-
set = /* @__PURE__ */ new Set();
|
|
12
|
-
index.set(key, set);
|
|
13
|
-
}
|
|
14
|
-
return set;
|
|
15
|
-
};
|
|
16
|
-
return createIndexProvider({
|
|
17
|
-
query(selector) {
|
|
18
|
-
if (!Object.hasOwnProperty.call(selector, field)) {
|
|
19
|
-
return { matched: false };
|
|
20
|
-
}
|
|
21
|
-
const fieldSelector = selector[field];
|
|
22
|
-
const filteresForNull = fieldSelector == null || fieldSelector.$exists === false;
|
|
23
|
-
const keys = filteresForNull ? { include: null, exclude: [...index.keys()].filter((key) => key != null) } : getMatchingKeys(field, selector);
|
|
24
|
-
if (keys.include == null && keys.exclude == null)
|
|
25
|
-
return { matched: false };
|
|
26
|
-
let includedIds = [];
|
|
27
|
-
if (keys.include == null) {
|
|
28
|
-
for (const set of index.values()) {
|
|
29
|
-
for (const pos of set) {
|
|
30
|
-
includedIds.push(pos);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
} else {
|
|
34
|
-
for (const key of keys.include) {
|
|
35
|
-
const posSet = index.get(key);
|
|
36
|
-
if (posSet) {
|
|
37
|
-
for (const pos of posSet) {
|
|
38
|
-
includedIds.push(pos);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (keys.exclude != null) {
|
|
44
|
-
const excludeIds = /* @__PURE__ */ new Set();
|
|
45
|
-
for (const key of keys.exclude) {
|
|
46
|
-
const posSet = index.get(key);
|
|
47
|
-
if (posSet) {
|
|
48
|
-
for (const pos of posSet) {
|
|
49
|
-
excludeIds.add(pos);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
includedIds = includedIds.filter((pos) => !excludeIds.has(pos));
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
matched: true,
|
|
57
|
-
ids: includedIds,
|
|
58
|
-
fields: [field],
|
|
59
|
-
keepSelector: filteresForNull
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
rebuild(items) {
|
|
63
|
-
index.clear();
|
|
64
|
-
items.forEach((item) => {
|
|
65
|
-
const value = serializeValue(get(item, field));
|
|
66
|
-
ensureSet(value).add(item.id);
|
|
67
|
-
});
|
|
68
|
-
},
|
|
69
|
-
// NEW: delta methods
|
|
70
|
-
insert(items) {
|
|
71
|
-
for (const item of items) {
|
|
72
|
-
const value = serializeValue(get(item, field));
|
|
73
|
-
ensureSet(value).add(item.id);
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
remove(items) {
|
|
77
|
-
for (const item of items) {
|
|
78
|
-
const value = serializeValue(get(item, field));
|
|
79
|
-
const set = index.get(value);
|
|
80
|
-
if (!set)
|
|
81
|
-
continue;
|
|
82
|
-
set.delete(item.id);
|
|
83
|
-
if (set.size === 0)
|
|
84
|
-
index.delete(value);
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
update(pairs) {
|
|
88
|
-
for (const { oldItem, newItem } of pairs) {
|
|
89
|
-
const oldValue = serializeValue(get(oldItem, field));
|
|
90
|
-
const newValue = serializeValue(get(newItem, field));
|
|
91
|
-
if (oldValue === newValue)
|
|
92
|
-
continue;
|
|
93
|
-
const oldSet = index.get(oldValue);
|
|
94
|
-
if (oldSet) {
|
|
95
|
-
oldSet.delete(oldItem.id);
|
|
96
|
-
if (oldSet.size === 0)
|
|
97
|
-
index.delete(oldValue);
|
|
98
|
-
}
|
|
99
|
-
ensureSet(newValue).add(newItem.id);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
2
|
+
function isEmptyOptions(options) {
|
|
3
|
+
if (options == null)
|
|
4
|
+
return true;
|
|
5
|
+
if (typeof options !== "object")
|
|
6
|
+
return false;
|
|
7
|
+
if (Array.isArray(options))
|
|
8
|
+
return false;
|
|
9
|
+
return Object.keys(options).length === 0;
|
|
103
10
|
}
|
|
104
|
-
|
|
11
|
+
function queryId(selector, options) {
|
|
12
|
+
const selectorId = JSON.stringify(selector);
|
|
13
|
+
const optionsId = isEmptyOptions(options) ? -1 : JSON.stringify(options);
|
|
14
|
+
return `${selectorId}:${optionsId}`;
|
|
15
|
+
}
|
|
16
|
+
module.exports = queryId;
|
package/dist/index.cjs21.js
CHANGED
|
@@ -1,129 +1,104 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
ids: [...new Set(memo2.matched ? intersection(memo2.ids, result.ids) : result.ids)],
|
|
14
|
-
optimizedSelector
|
|
15
|
-
};
|
|
16
|
-
};
|
|
17
|
-
if (resultOrPromise instanceof Promise) {
|
|
18
|
-
return resultOrPromise.then(async (result) => {
|
|
19
|
-
const memo2 = memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise;
|
|
20
|
-
return processResult(memo2, result);
|
|
21
|
-
});
|
|
2
|
+
const createIndexProvider = require("./index.cjs33.js");
|
|
3
|
+
const get = require("./index.cjs10.js");
|
|
4
|
+
const getMatchingKeys = require("./index.cjs26.js");
|
|
5
|
+
const serializeValue = require("./index.cjs11.js");
|
|
6
|
+
function createIndex(field) {
|
|
7
|
+
const index = /* @__PURE__ */ new Map();
|
|
8
|
+
const ensureSet = (key) => {
|
|
9
|
+
let set = index.get(key);
|
|
10
|
+
if (!set) {
|
|
11
|
+
set = /* @__PURE__ */ new Set();
|
|
12
|
+
index.set(key, set);
|
|
22
13
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
14
|
+
return set;
|
|
15
|
+
};
|
|
16
|
+
return createIndexProvider({
|
|
17
|
+
query(selector) {
|
|
18
|
+
if (!Object.hasOwnProperty.call(selector, field)) {
|
|
19
|
+
return { matched: false };
|
|
20
|
+
}
|
|
21
|
+
const fieldSelector = selector[field];
|
|
22
|
+
const filteresForNull = fieldSelector == null || fieldSelector.$exists === false;
|
|
23
|
+
const keys = filteresForNull ? { include: null, exclude: [...index.keys()].filter((key) => key != null) } : getMatchingKeys(field, selector);
|
|
24
|
+
if (keys.include == null && keys.exclude == null)
|
|
25
|
+
return { matched: false };
|
|
26
|
+
let includedIds = [];
|
|
27
|
+
if (keys.include == null) {
|
|
28
|
+
for (const set of index.values()) {
|
|
29
|
+
for (const pos of set) {
|
|
30
|
+
includedIds.push(pos);
|
|
31
|
+
}
|
|
41
32
|
}
|
|
42
33
|
} else {
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
for (const key of keys.include) {
|
|
35
|
+
const posSet = index.get(key);
|
|
36
|
+
if (posSet) {
|
|
37
|
+
for (const pos of posSet) {
|
|
38
|
+
includedIds.push(pos);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
45
42
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
const memo = memoOrPromise;
|
|
58
|
-
if (memo instanceof Promise)
|
|
59
|
-
throw new Error("Mixing async and sync index providers is not supported");
|
|
60
|
-
const optimizedSelector = getSelector(indexInfoOrPromise);
|
|
61
|
-
if (optimizedSelector)
|
|
62
|
-
memo.push(optimizedSelector);
|
|
63
|
-
return memo;
|
|
64
|
-
}, []);
|
|
65
|
-
}
|
|
66
|
-
function getIndexInfo(queryFunctions, selector) {
|
|
67
|
-
if (selector == null || Object.keys(selector).length <= 0) {
|
|
68
|
-
return {
|
|
69
|
-
matched: false,
|
|
70
|
-
ids: [],
|
|
71
|
-
optimizedSelector: selector
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
const { $and, $or, ...rest } = selector;
|
|
75
|
-
const flatInfoOrPromise = getMergedIndexInfo(queryFunctions, rest);
|
|
76
|
-
const processFlatInfo = (flatInfo) => {
|
|
77
|
-
let { matched, ids } = flatInfo;
|
|
78
|
-
const newSelector = flatInfo.optimizedSelector;
|
|
79
|
-
const $andNewOrPromise = Array.isArray($and) ? optimizeLogicGate(queryFunctions, $and, (match, selIds) => {
|
|
80
|
-
if (!match)
|
|
81
|
-
return;
|
|
82
|
-
ids = matched ? intersection(ids, selIds) : selIds;
|
|
83
|
-
matched = true;
|
|
84
|
-
}) : void 0;
|
|
85
|
-
const process$and = ($andNew) => {
|
|
86
|
-
if ($andNew && $andNew.length > 0)
|
|
87
|
-
newSelector.$and = $andNew;
|
|
88
|
-
let hasNonIndexField = false;
|
|
89
|
-
const matchedBefore = matched;
|
|
90
|
-
const idsBefore = ids;
|
|
91
|
-
const process$or = ($orNew) => {
|
|
92
|
-
if ($orNew && $orNew.length > 0)
|
|
93
|
-
newSelector.$or = $orNew;
|
|
94
|
-
if (hasNonIndexField) {
|
|
95
|
-
newSelector.$or = $or;
|
|
96
|
-
matched = matchedBefore;
|
|
97
|
-
ids = idsBefore;
|
|
43
|
+
if (keys.exclude != null) {
|
|
44
|
+
const excludeIds = /* @__PURE__ */ new Set();
|
|
45
|
+
for (const key of keys.exclude) {
|
|
46
|
+
const posSet = index.get(key);
|
|
47
|
+
if (posSet) {
|
|
48
|
+
for (const pos of posSet) {
|
|
49
|
+
excludeIds.add(pos);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
98
52
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
53
|
+
includedIds = includedIds.filter((pos) => !excludeIds.has(pos));
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
matched: true,
|
|
57
|
+
ids: includedIds,
|
|
58
|
+
fields: [field],
|
|
59
|
+
keepSelector: filteresForNull
|
|
104
60
|
};
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
61
|
+
},
|
|
62
|
+
rebuild(items) {
|
|
63
|
+
index.clear();
|
|
64
|
+
items.forEach((item) => {
|
|
65
|
+
const value = serializeValue(get(item, field));
|
|
66
|
+
ensureSet(value).add(item.id);
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
// NEW: delta methods
|
|
70
|
+
insert(items) {
|
|
71
|
+
for (const item of items) {
|
|
72
|
+
const value = serializeValue(get(item, field));
|
|
73
|
+
ensureSet(value).add(item.id);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
remove(items) {
|
|
77
|
+
for (const item of items) {
|
|
78
|
+
const value = serializeValue(get(item, field));
|
|
79
|
+
const set = index.get(value);
|
|
80
|
+
if (!set)
|
|
81
|
+
continue;
|
|
82
|
+
set.delete(item.id);
|
|
83
|
+
if (set.size === 0)
|
|
84
|
+
index.delete(value);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
update(pairs) {
|
|
88
|
+
for (const { oldItem, newItem } of pairs) {
|
|
89
|
+
const oldValue = serializeValue(get(oldItem, field));
|
|
90
|
+
const newValue = serializeValue(get(newItem, field));
|
|
91
|
+
if (oldValue === newValue)
|
|
92
|
+
continue;
|
|
93
|
+
const oldSet = index.get(oldValue);
|
|
94
|
+
if (oldSet) {
|
|
95
|
+
oldSet.delete(oldItem.id);
|
|
96
|
+
if (oldSet.size === 0)
|
|
97
|
+
index.delete(oldValue);
|
|
111
98
|
}
|
|
112
|
-
|
|
113
|
-
if ($orNewOrPromise instanceof Promise) {
|
|
114
|
-
return $orNewOrPromise.then(($orNew) => process$or($orNew));
|
|
99
|
+
ensureSet(newValue).add(newItem.id);
|
|
115
100
|
}
|
|
116
|
-
return process$or($orNewOrPromise);
|
|
117
|
-
};
|
|
118
|
-
if ($andNewOrPromise instanceof Promise) {
|
|
119
|
-
return $andNewOrPromise.then(($andNew) => process$and($andNew));
|
|
120
101
|
}
|
|
121
|
-
|
|
122
|
-
};
|
|
123
|
-
if (flatInfoOrPromise instanceof Promise) {
|
|
124
|
-
return flatInfoOrPromise.then(processFlatInfo);
|
|
125
|
-
}
|
|
126
|
-
return processFlatInfo(flatInfoOrPromise);
|
|
102
|
+
});
|
|
127
103
|
}
|
|
128
|
-
exports
|
|
129
|
-
exports.getMergedIndexInfo = getMergedIndexInfo;
|
|
104
|
+
module.exports = createIndex;
|