@signaldb/core 2.0.0-beta.13 → 2.0.0-beta.14
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 +72 -46
- package/dist/AsyncDataAdapter.d.ts +11 -2
- package/dist/Collection/Cursor.d.ts +11 -1
- package/dist/Collection/Observer.d.ts +31 -0
- package/dist/DataAdapter.d.ts +15 -2
- package/dist/WorkerDataAdapter.d.ts +25 -2
- package/dist/WorkerDataAdapterHost.d.ts +2 -0
- package/dist/index.cjs.js +15 -15
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +15 -15
- package/dist/index10.cjs.js +7 -19
- package/dist/index10.mjs +7 -19
- package/dist/index11.cjs.js +19 -41
- package/dist/index11.mjs +19 -41
- package/dist/index12.cjs.js +41 -18
- package/dist/index12.mjs +41 -18
- package/dist/index13.cjs.js +18 -41
- package/dist/index13.mjs +18 -41
- package/dist/index14.cjs.js +39 -80
- package/dist/index14.mjs +39 -80
- package/dist/index15.cjs.js +82 -11
- package/dist/index15.mjs +82 -11
- package/dist/index16.cjs.js +11 -132
- package/dist/index16.mjs +11 -132
- package/dist/index17.cjs.js +127 -38
- package/dist/index17.mjs +127 -38
- package/dist/index18.cjs.js +43 -11
- package/dist/index18.mjs +43 -11
- package/dist/index19.cjs.js +10 -18
- package/dist/index19.mjs +11 -19
- package/dist/index20.cjs.js +19 -33
- package/dist/index20.mjs +19 -33
- package/dist/index21.cjs.js +33 -31
- package/dist/index21.mjs +33 -31
- package/dist/index22.cjs.js +31 -21
- package/dist/index22.mjs +31 -21
- package/dist/index23.cjs.js +16 -14
- package/dist/index23.mjs +16 -14
- package/dist/index24.cjs.js +15 -338
- package/dist/index24.mjs +15 -338
- package/dist/index25.cjs.js +122 -554
- package/dist/index25.mjs +121 -554
- package/dist/index26.cjs.js +34 -7
- package/dist/index26.mjs +34 -7
- package/dist/index27.cjs.js +339 -7
- package/dist/index27.mjs +339 -7
- package/dist/index28.cjs.js +550 -83
- package/dist/index28.mjs +550 -82
- package/dist/index29.cjs.js +8 -422
- package/dist/index29.mjs +8 -422
- package/dist/index30.cjs.js +7 -68
- package/dist/index30.mjs +7 -68
- package/dist/index31.cjs.js +86 -28
- package/dist/index31.mjs +85 -28
- package/dist/index32.cjs.js +446 -278
- package/dist/index32.mjs +446 -278
- package/dist/index33.cjs.js +68 -17
- package/dist/index33.mjs +68 -17
- package/dist/index34.cjs.js +460 -304
- package/dist/index34.mjs +460 -304
- package/dist/index35.cjs.js +14 -532
- package/dist/index35.mjs +14 -532
- package/dist/index36.cjs.js +389 -0
- package/dist/index36.mjs +389 -0
- package/dist/index37.cjs.js +539 -0
- package/dist/index37.mjs +539 -0
- package/dist/index4.cjs.js +199 -140
- package/dist/index4.mjs +195 -140
- package/dist/index5.cjs.js +152 -253
- package/dist/index5.mjs +152 -253
- package/dist/index6.cjs.js +267 -89
- package/dist/index6.mjs +267 -89
- package/dist/index7.cjs.js +121 -29
- package/dist/index7.mjs +121 -29
- package/dist/index8.cjs.js +29 -8
- package/dist/index8.mjs +29 -8
- package/dist/index9.cjs.js +8 -7
- package/dist/index9.mjs +8 -7
- package/dist/utils/incrementalQueryUpdate.d.ts +60 -0
- package/dist/utils/projectItems.d.ts +12 -0
- package/dist/utils/queryDelta.d.ts +83 -0
- package/package.json +1 -1
package/dist/index14.mjs
CHANGED
|
@@ -1,86 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import getMatchingKeys from "./index13.mjs";
|
|
5
|
-
//#region src/createIndex.ts
|
|
1
|
+
import isFieldExpression from "./index12.mjs";
|
|
2
|
+
import serializeValue from "./index13.mjs";
|
|
3
|
+
//#region src/utils/getMatchingKeys.ts
|
|
6
4
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Extracts the matching and excluded keys for a given field in a selector.
|
|
6
|
+
* Supports serialized values and `$in`/`$nin` field expressions for optimization.
|
|
7
|
+
* Returns `null` for include/exclude if the field cannot be optimized.
|
|
8
|
+
* @template T - The type of the items in the selector.
|
|
9
|
+
* @template I - The type of the unique identifier for the items.
|
|
10
|
+
* @param field - The name of the field to extract matching keys for.
|
|
11
|
+
* @param selector - The selector object containing query criteria.
|
|
12
|
+
* @returns An object containing arrays of serialized included and excluded keys,
|
|
13
|
+
* or `null` if the field cannot be optimized.
|
|
10
14
|
*/
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!set) {
|
|
16
|
-
set = /* @__PURE__ */ new Set();
|
|
17
|
-
index.set(key, set);
|
|
18
|
-
}
|
|
19
|
-
return set;
|
|
15
|
+
function getMatchingKeys(field, selector) {
|
|
16
|
+
const result = {
|
|
17
|
+
include: null,
|
|
18
|
+
exclude: null
|
|
20
19
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
if (keys.exclude != null) {
|
|
38
|
-
const excludeIds = /* @__PURE__ */ new Set();
|
|
39
|
-
for (const key of keys.exclude) {
|
|
40
|
-
const posSet = index.get(key);
|
|
41
|
-
if (posSet) for (const pos of posSet) excludeIds.add(pos);
|
|
42
|
-
}
|
|
43
|
-
includedIds = includedIds.filter((pos) => !excludeIds.has(pos));
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
matched: true,
|
|
47
|
-
ids: includedIds,
|
|
48
|
-
fields: [field],
|
|
49
|
-
keepSelector: filteresForNull
|
|
50
|
-
};
|
|
51
|
-
},
|
|
52
|
-
rebuild(items) {
|
|
53
|
-
index.clear();
|
|
54
|
-
items.forEach((item) => {
|
|
55
|
-
ensureSet(serializeValue(get(item, field))).add(item.id);
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
insert(items) {
|
|
59
|
-
for (const item of items) ensureSet(serializeValue(get(item, field))).add(item.id);
|
|
60
|
-
},
|
|
61
|
-
remove(items) {
|
|
62
|
-
for (const item of items) {
|
|
63
|
-
const value = serializeValue(get(item, field));
|
|
64
|
-
const set = index.get(value);
|
|
65
|
-
if (!set) continue;
|
|
66
|
-
set.delete(item.id);
|
|
67
|
-
if (set.size === 0) index.delete(value);
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
update(pairs) {
|
|
71
|
-
for (const { oldItem, newItem } of pairs) {
|
|
72
|
-
const oldValue = serializeValue(get(oldItem, field));
|
|
73
|
-
const newValue = serializeValue(get(newItem, field));
|
|
74
|
-
if (oldValue === newValue) continue;
|
|
75
|
-
const oldSet = index.get(oldValue);
|
|
76
|
-
if (oldSet) {
|
|
77
|
-
oldSet.delete(oldItem.id);
|
|
78
|
-
if (oldSet.size === 0) index.delete(oldValue);
|
|
79
|
-
}
|
|
80
|
-
ensureSet(newValue).add(newItem.id);
|
|
81
|
-
}
|
|
20
|
+
const fieldSelector = selector[field];
|
|
21
|
+
if (fieldSelector instanceof RegExp) return result;
|
|
22
|
+
if (fieldSelector == null) return result;
|
|
23
|
+
if (isFieldExpression(fieldSelector)) {
|
|
24
|
+
if (fieldSelector.$ne != null) {
|
|
25
|
+
result.exclude = [serializeValue(fieldSelector.$ne)];
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(fieldSelector.$in) && fieldSelector.$in.length > 0) {
|
|
29
|
+
result.include = fieldSelector.$in.map(serializeValue);
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
if (Array.isArray(fieldSelector.$nin) && fieldSelector.$nin.length > 0) {
|
|
33
|
+
result.exclude = fieldSelector.$nin.map(serializeValue);
|
|
34
|
+
return result;
|
|
82
35
|
}
|
|
83
|
-
|
|
36
|
+
return {
|
|
37
|
+
include: null,
|
|
38
|
+
exclude: null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
result.include = [serializeValue(fieldSelector)];
|
|
42
|
+
return result;
|
|
84
43
|
}
|
|
85
44
|
//#endregion
|
|
86
|
-
export {
|
|
45
|
+
export { getMatchingKeys as default };
|
package/dist/index15.cjs.js
CHANGED
|
@@ -1,15 +1,86 @@
|
|
|
1
|
-
|
|
1
|
+
const require_createIndexProvider = require("./index10.cjs.js");
|
|
2
|
+
const require_get = require("./index11.cjs.js");
|
|
3
|
+
const require_serializeValue = require("./index13.cjs.js");
|
|
4
|
+
const require_getMatchingKeys = require("./index14.cjs.js");
|
|
5
|
+
//#region src/createIndex.ts
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
6
|
-
* @param arrays - A variable number of arrays to compute the intersection of.
|
|
7
|
-
* @returns An array containing the unique elements found in all the input arrays.
|
|
8
|
-
* - If no arrays are provided, returns an empty array.
|
|
7
|
+
* creates an index for a specific field
|
|
8
|
+
* @param field name of the field
|
|
9
|
+
* @returns an index provider to pass to the `indices` option of the collection constructor
|
|
9
10
|
*/
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
function createIndex(field) {
|
|
12
|
+
const index = /* @__PURE__ */ new Map();
|
|
13
|
+
const ensureSet = (key) => {
|
|
14
|
+
let set = index.get(key);
|
|
15
|
+
if (!set) {
|
|
16
|
+
set = /* @__PURE__ */ new Set();
|
|
17
|
+
index.set(key, set);
|
|
18
|
+
}
|
|
19
|
+
return set;
|
|
20
|
+
};
|
|
21
|
+
return require_createIndexProvider.default({
|
|
22
|
+
query(selector) {
|
|
23
|
+
if (!Object.hasOwnProperty.call(selector, field)) return { matched: false };
|
|
24
|
+
const fieldSelector = selector[field];
|
|
25
|
+
const filteresForNull = fieldSelector == null || fieldSelector.$exists === false;
|
|
26
|
+
const keys = filteresForNull ? {
|
|
27
|
+
include: null,
|
|
28
|
+
exclude: [...index.keys()].filter((key) => key != null)
|
|
29
|
+
} : require_getMatchingKeys.default(field, selector);
|
|
30
|
+
if (keys.include == null && keys.exclude == null) return { matched: false };
|
|
31
|
+
let includedIds = [];
|
|
32
|
+
if (keys.include == null) for (const set of index.values()) for (const pos of set) includedIds.push(pos);
|
|
33
|
+
else for (const key of keys.include) {
|
|
34
|
+
const posSet = index.get(key);
|
|
35
|
+
if (posSet) for (const pos of posSet) includedIds.push(pos);
|
|
36
|
+
}
|
|
37
|
+
if (keys.exclude != null) {
|
|
38
|
+
const excludeIds = /* @__PURE__ */ new Set();
|
|
39
|
+
for (const key of keys.exclude) {
|
|
40
|
+
const posSet = index.get(key);
|
|
41
|
+
if (posSet) for (const pos of posSet) excludeIds.add(pos);
|
|
42
|
+
}
|
|
43
|
+
includedIds = includedIds.filter((pos) => !excludeIds.has(pos));
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
matched: true,
|
|
47
|
+
ids: includedIds,
|
|
48
|
+
fields: [field],
|
|
49
|
+
keepSelector: filteresForNull
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
rebuild(items) {
|
|
53
|
+
index.clear();
|
|
54
|
+
items.forEach((item) => {
|
|
55
|
+
ensureSet(require_serializeValue.default(require_get.default(item, field))).add(item.id);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
insert(items) {
|
|
59
|
+
for (const item of items) ensureSet(require_serializeValue.default(require_get.default(item, field))).add(item.id);
|
|
60
|
+
},
|
|
61
|
+
remove(items) {
|
|
62
|
+
for (const item of items) {
|
|
63
|
+
const value = require_serializeValue.default(require_get.default(item, field));
|
|
64
|
+
const set = index.get(value);
|
|
65
|
+
if (!set) continue;
|
|
66
|
+
set.delete(item.id);
|
|
67
|
+
if (set.size === 0) index.delete(value);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
update(pairs) {
|
|
71
|
+
for (const { oldItem, newItem } of pairs) {
|
|
72
|
+
const oldValue = require_serializeValue.default(require_get.default(oldItem, field));
|
|
73
|
+
const newValue = require_serializeValue.default(require_get.default(newItem, field));
|
|
74
|
+
if (oldValue === newValue) continue;
|
|
75
|
+
const oldSet = index.get(oldValue);
|
|
76
|
+
if (oldSet) {
|
|
77
|
+
oldSet.delete(oldItem.id);
|
|
78
|
+
if (oldSet.size === 0) index.delete(oldValue);
|
|
79
|
+
}
|
|
80
|
+
ensureSet(newValue).add(newItem.id);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
13
84
|
}
|
|
14
85
|
//#endregion
|
|
15
|
-
exports.default =
|
|
86
|
+
exports.default = createIndex;
|
package/dist/index15.mjs
CHANGED
|
@@ -1,15 +1,86 @@
|
|
|
1
|
-
|
|
1
|
+
import createIndexProvider from "./index10.mjs";
|
|
2
|
+
import get from "./index11.mjs";
|
|
3
|
+
import serializeValue from "./index13.mjs";
|
|
4
|
+
import getMatchingKeys from "./index14.mjs";
|
|
5
|
+
//#region src/createIndex.ts
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* @
|
|
6
|
-
* @param arrays - A variable number of arrays to compute the intersection of.
|
|
7
|
-
* @returns An array containing the unique elements found in all the input arrays.
|
|
8
|
-
* - If no arrays are provided, returns an empty array.
|
|
7
|
+
* creates an index for a specific field
|
|
8
|
+
* @param field name of the field
|
|
9
|
+
* @returns an index provider to pass to the `indices` option of the collection constructor
|
|
9
10
|
*/
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
function createIndex(field) {
|
|
12
|
+
const index = /* @__PURE__ */ new Map();
|
|
13
|
+
const ensureSet = (key) => {
|
|
14
|
+
let set = index.get(key);
|
|
15
|
+
if (!set) {
|
|
16
|
+
set = /* @__PURE__ */ new Set();
|
|
17
|
+
index.set(key, set);
|
|
18
|
+
}
|
|
19
|
+
return set;
|
|
20
|
+
};
|
|
21
|
+
return createIndexProvider({
|
|
22
|
+
query(selector) {
|
|
23
|
+
if (!Object.hasOwnProperty.call(selector, field)) return { matched: false };
|
|
24
|
+
const fieldSelector = selector[field];
|
|
25
|
+
const filteresForNull = fieldSelector == null || fieldSelector.$exists === false;
|
|
26
|
+
const keys = filteresForNull ? {
|
|
27
|
+
include: null,
|
|
28
|
+
exclude: [...index.keys()].filter((key) => key != null)
|
|
29
|
+
} : getMatchingKeys(field, selector);
|
|
30
|
+
if (keys.include == null && keys.exclude == null) return { matched: false };
|
|
31
|
+
let includedIds = [];
|
|
32
|
+
if (keys.include == null) for (const set of index.values()) for (const pos of set) includedIds.push(pos);
|
|
33
|
+
else for (const key of keys.include) {
|
|
34
|
+
const posSet = index.get(key);
|
|
35
|
+
if (posSet) for (const pos of posSet) includedIds.push(pos);
|
|
36
|
+
}
|
|
37
|
+
if (keys.exclude != null) {
|
|
38
|
+
const excludeIds = /* @__PURE__ */ new Set();
|
|
39
|
+
for (const key of keys.exclude) {
|
|
40
|
+
const posSet = index.get(key);
|
|
41
|
+
if (posSet) for (const pos of posSet) excludeIds.add(pos);
|
|
42
|
+
}
|
|
43
|
+
includedIds = includedIds.filter((pos) => !excludeIds.has(pos));
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
matched: true,
|
|
47
|
+
ids: includedIds,
|
|
48
|
+
fields: [field],
|
|
49
|
+
keepSelector: filteresForNull
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
rebuild(items) {
|
|
53
|
+
index.clear();
|
|
54
|
+
items.forEach((item) => {
|
|
55
|
+
ensureSet(serializeValue(get(item, field))).add(item.id);
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
insert(items) {
|
|
59
|
+
for (const item of items) ensureSet(serializeValue(get(item, field))).add(item.id);
|
|
60
|
+
},
|
|
61
|
+
remove(items) {
|
|
62
|
+
for (const item of items) {
|
|
63
|
+
const value = serializeValue(get(item, field));
|
|
64
|
+
const set = index.get(value);
|
|
65
|
+
if (!set) continue;
|
|
66
|
+
set.delete(item.id);
|
|
67
|
+
if (set.size === 0) index.delete(value);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
update(pairs) {
|
|
71
|
+
for (const { oldItem, newItem } of pairs) {
|
|
72
|
+
const oldValue = serializeValue(get(oldItem, field));
|
|
73
|
+
const newValue = serializeValue(get(newItem, field));
|
|
74
|
+
if (oldValue === newValue) continue;
|
|
75
|
+
const oldSet = index.get(oldValue);
|
|
76
|
+
if (oldSet) {
|
|
77
|
+
oldSet.delete(oldItem.id);
|
|
78
|
+
if (oldSet.size === 0) index.delete(oldValue);
|
|
79
|
+
}
|
|
80
|
+
ensureSet(newValue).add(newItem.id);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
13
84
|
}
|
|
14
85
|
//#endregion
|
|
15
|
-
export {
|
|
86
|
+
export { createIndex as default };
|
package/dist/index16.cjs.js
CHANGED
|
@@ -1,136 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/getIndexInfo.ts
|
|
1
|
+
//#region src/utils/intersection.ts
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
* @param selector - The flat selector used to filter items.
|
|
11
|
-
* @returns An object containing:
|
|
12
|
-
* - `matched`: A boolean indicating if the selector matched any items.
|
|
13
|
-
* - `ids`: An array of matched item ids.
|
|
14
|
-
* - `optimizedSelector`: A flat selector optimized based on the index results.
|
|
3
|
+
* Computes the intersection of multiple arrays, returning an array of unique elements
|
|
4
|
+
* that are present in all the input arrays.
|
|
5
|
+
* @template T - The type of elements in the arrays.
|
|
6
|
+
* @param arrays - A variable number of arrays to compute the intersection of.
|
|
7
|
+
* @returns An array containing the unique elements found in all the input arrays.
|
|
8
|
+
* - If no arrays are provided, returns an empty array.
|
|
15
9
|
*/
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const processResult = (memo, result) => {
|
|
20
|
-
if (!result.matched) return memo;
|
|
21
|
-
const optimizedSelector = result.keepSelector ? memo.optimizedSelector : Object.fromEntries(Object.entries(memo.optimizedSelector).filter(([key]) => !result.fields.includes(key)));
|
|
22
|
-
return {
|
|
23
|
-
matched: true,
|
|
24
|
-
ids: [...new Set(memo.matched ? require_intersection.default(memo.ids, result.ids) : result.ids)],
|
|
25
|
-
optimizedSelector
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
if (resultOrPromise instanceof Promise) return resultOrPromise.then(async (result) => {
|
|
29
|
-
return processResult(memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise, result);
|
|
30
|
-
});
|
|
31
|
-
const memo = memoOrPromise;
|
|
32
|
-
if (memo instanceof Promise) throw new Error("Mixing async and sync index providers is not supported");
|
|
33
|
-
return processResult(memo, resultOrPromise);
|
|
34
|
-
}, {
|
|
35
|
-
matched: false,
|
|
36
|
-
ids: [],
|
|
37
|
-
optimizedSelector: { ...selector }
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Optimizes a logic gate ($and/$or) of selectors by querying multiple index providers.
|
|
42
|
-
* @param queryFunctions - An array of index providers to query.
|
|
43
|
-
* @param logicGate - An array of selectors representing the logic gate.
|
|
44
|
-
* @param idsCallback - A callback function called with matched ids.
|
|
45
|
-
* @returns An array of optimized selectors or a promise that resolves to such an array.
|
|
46
|
-
*/
|
|
47
|
-
function optimizeLogicGate(queryFunctions, logicGate, idsCallback) {
|
|
48
|
-
return logicGate.reduce((memoOrPromise, sel) => {
|
|
49
|
-
const getSelector = (indexInfo) => {
|
|
50
|
-
const { matched: selMatched, ids: selIds, optimizedSelector } = indexInfo;
|
|
51
|
-
if (selMatched) {
|
|
52
|
-
idsCallback(true, selIds);
|
|
53
|
-
if (Object.keys(optimizedSelector).length > 0) return optimizedSelector;
|
|
54
|
-
} else {
|
|
55
|
-
idsCallback(false, []);
|
|
56
|
-
return sel;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
const indexInfoOrPromise = getIndexInfo(queryFunctions, sel);
|
|
60
|
-
if (indexInfoOrPromise instanceof Promise) return indexInfoOrPromise.then(async (indexInfo) => {
|
|
61
|
-
const memo = memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise;
|
|
62
|
-
const optimizedSelector = getSelector(indexInfo);
|
|
63
|
-
if (optimizedSelector) memo.push(optimizedSelector);
|
|
64
|
-
return memo;
|
|
65
|
-
});
|
|
66
|
-
const memo = memoOrPromise;
|
|
67
|
-
if (memo instanceof Promise) throw new Error("Mixing async and sync index providers is not supported");
|
|
68
|
-
const optimizedSelector = getSelector(indexInfoOrPromise);
|
|
69
|
-
if (optimizedSelector) memo.push(optimizedSelector);
|
|
70
|
-
return memo;
|
|
71
|
-
}, []);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Retrieves index information for a given complex selector by querying multiple
|
|
75
|
-
* index providers. Handles nested `$and` and `$or` conditions in the selector and
|
|
76
|
-
* optimizes the selector to minimize processing overhead.
|
|
77
|
-
* @template T - The type of the items in the collection.
|
|
78
|
-
* @template I - The type of the unique identifier for the items.
|
|
79
|
-
* @param queryFunctions - An array of index providers to query.
|
|
80
|
-
* @param selector - The complex selector used to filter items.
|
|
81
|
-
* @returns An object containing:
|
|
82
|
-
* - `matched`: A boolean indicating if the selector matched any items.
|
|
83
|
-
* - `ids`: An array of matched item ids.
|
|
84
|
-
* - `optimizedSelector`: A selector optimized based on the index results, with unused
|
|
85
|
-
* conditions removed.
|
|
86
|
-
*/
|
|
87
|
-
function getIndexInfo(queryFunctions, selector) {
|
|
88
|
-
if (selector == null || Object.keys(selector).length <= 0) return {
|
|
89
|
-
matched: false,
|
|
90
|
-
ids: [],
|
|
91
|
-
optimizedSelector: selector
|
|
92
|
-
};
|
|
93
|
-
const { $and, $or, ...rest } = selector;
|
|
94
|
-
const flatInfoOrPromise = getMergedIndexInfo(queryFunctions, rest);
|
|
95
|
-
const processFlatInfo = (flatInfo) => {
|
|
96
|
-
let { matched, ids } = flatInfo;
|
|
97
|
-
const newSelector = flatInfo.optimizedSelector;
|
|
98
|
-
const $andNewOrPromise = Array.isArray($and) ? optimizeLogicGate(queryFunctions, $and, (match, selIds) => {
|
|
99
|
-
if (!match) return;
|
|
100
|
-
ids = matched ? require_intersection.default(ids, selIds) : selIds;
|
|
101
|
-
matched = true;
|
|
102
|
-
}) : void 0;
|
|
103
|
-
const process$and = ($andNew) => {
|
|
104
|
-
if ($andNew && $andNew.length > 0) newSelector.$and = $andNew;
|
|
105
|
-
let hasNonIndexField = false;
|
|
106
|
-
const matchedBefore = matched;
|
|
107
|
-
const idsBefore = ids;
|
|
108
|
-
const process$or = ($orNew) => {
|
|
109
|
-
if (hasNonIndexField || $orNew && $orNew.length > 0) {
|
|
110
|
-
newSelector.$or = $or;
|
|
111
|
-
matched = matchedBefore;
|
|
112
|
-
ids = idsBefore;
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
matched,
|
|
116
|
-
ids: ids || [],
|
|
117
|
-
optimizedSelector: newSelector
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
const $orNewOrPromise = Array.isArray($or) ? optimizeLogicGate(queryFunctions, $or, (match, selIds) => {
|
|
121
|
-
if (match) {
|
|
122
|
-
ids = [...new Set([...ids, ...selIds])];
|
|
123
|
-
matched = true;
|
|
124
|
-
} else hasNonIndexField = true;
|
|
125
|
-
}) : void 0;
|
|
126
|
-
if ($orNewOrPromise instanceof Promise) return $orNewOrPromise.then(($orNew) => process$or($orNew));
|
|
127
|
-
return process$or($orNewOrPromise);
|
|
128
|
-
};
|
|
129
|
-
if ($andNewOrPromise instanceof Promise) return $andNewOrPromise.then(($andNew) => process$and($andNew));
|
|
130
|
-
return process$and($andNewOrPromise);
|
|
131
|
-
};
|
|
132
|
-
if (flatInfoOrPromise instanceof Promise) return flatInfoOrPromise.then(processFlatInfo);
|
|
133
|
-
return processFlatInfo(flatInfoOrPromise);
|
|
10
|
+
function intersection(...arrays) {
|
|
11
|
+
if (arrays.length === 0) return [];
|
|
12
|
+
return [...new Set(arrays.reduce((a, b) => a.filter((c) => b.includes(c))))];
|
|
134
13
|
}
|
|
135
14
|
//#endregion
|
|
136
|
-
exports.default =
|
|
15
|
+
exports.default = intersection;
|
package/dist/index16.mjs
CHANGED
|
@@ -1,136 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
//#region src/getIndexInfo.ts
|
|
1
|
+
//#region src/utils/intersection.ts
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
* @param selector - The flat selector used to filter items.
|
|
11
|
-
* @returns An object containing:
|
|
12
|
-
* - `matched`: A boolean indicating if the selector matched any items.
|
|
13
|
-
* - `ids`: An array of matched item ids.
|
|
14
|
-
* - `optimizedSelector`: A flat selector optimized based on the index results.
|
|
3
|
+
* Computes the intersection of multiple arrays, returning an array of unique elements
|
|
4
|
+
* that are present in all the input arrays.
|
|
5
|
+
* @template T - The type of elements in the arrays.
|
|
6
|
+
* @param arrays - A variable number of arrays to compute the intersection of.
|
|
7
|
+
* @returns An array containing the unique elements found in all the input arrays.
|
|
8
|
+
* - If no arrays are provided, returns an empty array.
|
|
15
9
|
*/
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const processResult = (memo, result) => {
|
|
20
|
-
if (!result.matched) return memo;
|
|
21
|
-
const optimizedSelector = result.keepSelector ? memo.optimizedSelector : Object.fromEntries(Object.entries(memo.optimizedSelector).filter(([key]) => !result.fields.includes(key)));
|
|
22
|
-
return {
|
|
23
|
-
matched: true,
|
|
24
|
-
ids: [...new Set(memo.matched ? intersection(memo.ids, result.ids) : result.ids)],
|
|
25
|
-
optimizedSelector
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
if (resultOrPromise instanceof Promise) return resultOrPromise.then(async (result) => {
|
|
29
|
-
return processResult(memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise, result);
|
|
30
|
-
});
|
|
31
|
-
const memo = memoOrPromise;
|
|
32
|
-
if (memo instanceof Promise) throw new Error("Mixing async and sync index providers is not supported");
|
|
33
|
-
return processResult(memo, resultOrPromise);
|
|
34
|
-
}, {
|
|
35
|
-
matched: false,
|
|
36
|
-
ids: [],
|
|
37
|
-
optimizedSelector: { ...selector }
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Optimizes a logic gate ($and/$or) of selectors by querying multiple index providers.
|
|
42
|
-
* @param queryFunctions - An array of index providers to query.
|
|
43
|
-
* @param logicGate - An array of selectors representing the logic gate.
|
|
44
|
-
* @param idsCallback - A callback function called with matched ids.
|
|
45
|
-
* @returns An array of optimized selectors or a promise that resolves to such an array.
|
|
46
|
-
*/
|
|
47
|
-
function optimizeLogicGate(queryFunctions, logicGate, idsCallback) {
|
|
48
|
-
return logicGate.reduce((memoOrPromise, sel) => {
|
|
49
|
-
const getSelector = (indexInfo) => {
|
|
50
|
-
const { matched: selMatched, ids: selIds, optimizedSelector } = indexInfo;
|
|
51
|
-
if (selMatched) {
|
|
52
|
-
idsCallback(true, selIds);
|
|
53
|
-
if (Object.keys(optimizedSelector).length > 0) return optimizedSelector;
|
|
54
|
-
} else {
|
|
55
|
-
idsCallback(false, []);
|
|
56
|
-
return sel;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
const indexInfoOrPromise = getIndexInfo(queryFunctions, sel);
|
|
60
|
-
if (indexInfoOrPromise instanceof Promise) return indexInfoOrPromise.then(async (indexInfo) => {
|
|
61
|
-
const memo = memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise;
|
|
62
|
-
const optimizedSelector = getSelector(indexInfo);
|
|
63
|
-
if (optimizedSelector) memo.push(optimizedSelector);
|
|
64
|
-
return memo;
|
|
65
|
-
});
|
|
66
|
-
const memo = memoOrPromise;
|
|
67
|
-
if (memo instanceof Promise) throw new Error("Mixing async and sync index providers is not supported");
|
|
68
|
-
const optimizedSelector = getSelector(indexInfoOrPromise);
|
|
69
|
-
if (optimizedSelector) memo.push(optimizedSelector);
|
|
70
|
-
return memo;
|
|
71
|
-
}, []);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Retrieves index information for a given complex selector by querying multiple
|
|
75
|
-
* index providers. Handles nested `$and` and `$or` conditions in the selector and
|
|
76
|
-
* optimizes the selector to minimize processing overhead.
|
|
77
|
-
* @template T - The type of the items in the collection.
|
|
78
|
-
* @template I - The type of the unique identifier for the items.
|
|
79
|
-
* @param queryFunctions - An array of index providers to query.
|
|
80
|
-
* @param selector - The complex selector used to filter items.
|
|
81
|
-
* @returns An object containing:
|
|
82
|
-
* - `matched`: A boolean indicating if the selector matched any items.
|
|
83
|
-
* - `ids`: An array of matched item ids.
|
|
84
|
-
* - `optimizedSelector`: A selector optimized based on the index results, with unused
|
|
85
|
-
* conditions removed.
|
|
86
|
-
*/
|
|
87
|
-
function getIndexInfo(queryFunctions, selector) {
|
|
88
|
-
if (selector == null || Object.keys(selector).length <= 0) return {
|
|
89
|
-
matched: false,
|
|
90
|
-
ids: [],
|
|
91
|
-
optimizedSelector: selector
|
|
92
|
-
};
|
|
93
|
-
const { $and, $or, ...rest } = selector;
|
|
94
|
-
const flatInfoOrPromise = getMergedIndexInfo(queryFunctions, rest);
|
|
95
|
-
const processFlatInfo = (flatInfo) => {
|
|
96
|
-
let { matched, ids } = flatInfo;
|
|
97
|
-
const newSelector = flatInfo.optimizedSelector;
|
|
98
|
-
const $andNewOrPromise = Array.isArray($and) ? optimizeLogicGate(queryFunctions, $and, (match, selIds) => {
|
|
99
|
-
if (!match) return;
|
|
100
|
-
ids = matched ? intersection(ids, selIds) : selIds;
|
|
101
|
-
matched = true;
|
|
102
|
-
}) : void 0;
|
|
103
|
-
const process$and = ($andNew) => {
|
|
104
|
-
if ($andNew && $andNew.length > 0) newSelector.$and = $andNew;
|
|
105
|
-
let hasNonIndexField = false;
|
|
106
|
-
const matchedBefore = matched;
|
|
107
|
-
const idsBefore = ids;
|
|
108
|
-
const process$or = ($orNew) => {
|
|
109
|
-
if (hasNonIndexField || $orNew && $orNew.length > 0) {
|
|
110
|
-
newSelector.$or = $or;
|
|
111
|
-
matched = matchedBefore;
|
|
112
|
-
ids = idsBefore;
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
matched,
|
|
116
|
-
ids: ids || [],
|
|
117
|
-
optimizedSelector: newSelector
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
|
-
const $orNewOrPromise = Array.isArray($or) ? optimizeLogicGate(queryFunctions, $or, (match, selIds) => {
|
|
121
|
-
if (match) {
|
|
122
|
-
ids = [...new Set([...ids, ...selIds])];
|
|
123
|
-
matched = true;
|
|
124
|
-
} else hasNonIndexField = true;
|
|
125
|
-
}) : void 0;
|
|
126
|
-
if ($orNewOrPromise instanceof Promise) return $orNewOrPromise.then(($orNew) => process$or($orNew));
|
|
127
|
-
return process$or($orNewOrPromise);
|
|
128
|
-
};
|
|
129
|
-
if ($andNewOrPromise instanceof Promise) return $andNewOrPromise.then(($andNew) => process$and($andNew));
|
|
130
|
-
return process$and($andNewOrPromise);
|
|
131
|
-
};
|
|
132
|
-
if (flatInfoOrPromise instanceof Promise) return flatInfoOrPromise.then(processFlatInfo);
|
|
133
|
-
return processFlatInfo(flatInfoOrPromise);
|
|
10
|
+
function intersection(...arrays) {
|
|
11
|
+
if (arrays.length === 0) return [];
|
|
12
|
+
return [...new Set(arrays.reduce((a, b) => a.filter((c) => b.includes(c))))];
|
|
134
13
|
}
|
|
135
14
|
//#endregion
|
|
136
|
-
export {
|
|
15
|
+
export { intersection as default };
|