@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/index22.mjs
CHANGED
|
@@ -1,8 +1,129 @@
|
|
|
1
|
-
import
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import intersection from "./index29.mjs";
|
|
2
|
+
function getMergedIndexInfo(queryFunctions, selector) {
|
|
3
|
+
return queryFunctions.reduce((memoOrPromise, queryFunction) => {
|
|
4
|
+
const resultOrPromise = queryFunction(selector);
|
|
5
|
+
const processResult = (memo2, result) => {
|
|
6
|
+
if (!result.matched)
|
|
7
|
+
return memo2;
|
|
8
|
+
const optimizedSelector = result.keepSelector ? memo2.optimizedSelector : Object.fromEntries(Object.entries(memo2.optimizedSelector).filter(([key]) => !result.fields.includes(key)));
|
|
9
|
+
return {
|
|
10
|
+
matched: true,
|
|
11
|
+
ids: [...new Set(memo2.matched ? intersection(memo2.ids, result.ids) : result.ids)],
|
|
12
|
+
optimizedSelector
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
if (resultOrPromise instanceof Promise) {
|
|
16
|
+
return resultOrPromise.then(async (result) => {
|
|
17
|
+
const memo2 = memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise;
|
|
18
|
+
return processResult(memo2, result);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const memo = memoOrPromise;
|
|
22
|
+
if (memo instanceof Promise)
|
|
23
|
+
throw new Error("Mixing async and sync index providers is not supported");
|
|
24
|
+
return processResult(memo, resultOrPromise);
|
|
25
|
+
}, {
|
|
26
|
+
matched: false,
|
|
27
|
+
ids: [],
|
|
28
|
+
optimizedSelector: { ...selector }
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function optimizeLogicGate(queryFunctions, logicGate, idsCallback) {
|
|
32
|
+
return logicGate.reduce((memoOrPromise, sel) => {
|
|
33
|
+
const getSelector = (indexInfo) => {
|
|
34
|
+
const { matched: selMatched, ids: selIds, optimizedSelector: optimizedSelector2 } = indexInfo;
|
|
35
|
+
if (selMatched) {
|
|
36
|
+
idsCallback(true, selIds);
|
|
37
|
+
if (Object.keys(optimizedSelector2).length > 0) {
|
|
38
|
+
return optimizedSelector2;
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
idsCallback(false, []);
|
|
42
|
+
return sel;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const indexInfoOrPromise = getIndexInfo(queryFunctions, sel);
|
|
46
|
+
if (indexInfoOrPromise instanceof Promise) {
|
|
47
|
+
return indexInfoOrPromise.then(async (indexInfo) => {
|
|
48
|
+
const memo2 = memoOrPromise instanceof Promise ? await memoOrPromise : memoOrPromise;
|
|
49
|
+
const optimizedSelector2 = getSelector(indexInfo);
|
|
50
|
+
if (optimizedSelector2)
|
|
51
|
+
memo2.push(optimizedSelector2);
|
|
52
|
+
return memo2;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const memo = memoOrPromise;
|
|
56
|
+
if (memo instanceof Promise)
|
|
57
|
+
throw new Error("Mixing async and sync index providers is not supported");
|
|
58
|
+
const optimizedSelector = getSelector(indexInfoOrPromise);
|
|
59
|
+
if (optimizedSelector)
|
|
60
|
+
memo.push(optimizedSelector);
|
|
61
|
+
return memo;
|
|
62
|
+
}, []);
|
|
63
|
+
}
|
|
64
|
+
function getIndexInfo(queryFunctions, selector) {
|
|
65
|
+
if (selector == null || Object.keys(selector).length <= 0) {
|
|
66
|
+
return {
|
|
67
|
+
matched: false,
|
|
68
|
+
ids: [],
|
|
69
|
+
optimizedSelector: selector
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const { $and, $or, ...rest } = selector;
|
|
73
|
+
const flatInfoOrPromise = getMergedIndexInfo(queryFunctions, rest);
|
|
74
|
+
const processFlatInfo = (flatInfo) => {
|
|
75
|
+
let { matched, ids } = flatInfo;
|
|
76
|
+
const newSelector = flatInfo.optimizedSelector;
|
|
77
|
+
const $andNewOrPromise = Array.isArray($and) ? optimizeLogicGate(queryFunctions, $and, (match, selIds) => {
|
|
78
|
+
if (!match)
|
|
79
|
+
return;
|
|
80
|
+
ids = matched ? intersection(ids, selIds) : selIds;
|
|
81
|
+
matched = true;
|
|
82
|
+
}) : void 0;
|
|
83
|
+
const process$and = ($andNew) => {
|
|
84
|
+
if ($andNew && $andNew.length > 0)
|
|
85
|
+
newSelector.$and = $andNew;
|
|
86
|
+
let hasNonIndexField = false;
|
|
87
|
+
const matchedBefore = matched;
|
|
88
|
+
const idsBefore = ids;
|
|
89
|
+
const process$or = ($orNew) => {
|
|
90
|
+
if ($orNew && $orNew.length > 0)
|
|
91
|
+
newSelector.$or = $orNew;
|
|
92
|
+
if (hasNonIndexField) {
|
|
93
|
+
newSelector.$or = $or;
|
|
94
|
+
matched = matchedBefore;
|
|
95
|
+
ids = idsBefore;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
matched,
|
|
99
|
+
ids: ids || [],
|
|
100
|
+
optimizedSelector: newSelector
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
const $orNewOrPromise = Array.isArray($or) ? optimizeLogicGate(queryFunctions, $or, (match, selIds) => {
|
|
104
|
+
if (match) {
|
|
105
|
+
ids = [.../* @__PURE__ */ new Set([...ids, ...selIds])];
|
|
106
|
+
matched = true;
|
|
107
|
+
} else {
|
|
108
|
+
hasNonIndexField = true;
|
|
109
|
+
}
|
|
110
|
+
}) : void 0;
|
|
111
|
+
if ($orNewOrPromise instanceof Promise) {
|
|
112
|
+
return $orNewOrPromise.then(($orNew) => process$or($orNew));
|
|
113
|
+
}
|
|
114
|
+
return process$or($orNewOrPromise);
|
|
115
|
+
};
|
|
116
|
+
if ($andNewOrPromise instanceof Promise) {
|
|
117
|
+
return $andNewOrPromise.then(($andNew) => process$and($andNew));
|
|
118
|
+
}
|
|
119
|
+
return process$and($andNewOrPromise);
|
|
120
|
+
};
|
|
121
|
+
if (flatInfoOrPromise instanceof Promise) {
|
|
122
|
+
return flatInfoOrPromise.then(processFlatInfo);
|
|
123
|
+
}
|
|
124
|
+
return processFlatInfo(flatInfoOrPromise);
|
|
5
125
|
}
|
|
6
126
|
export {
|
|
7
|
-
|
|
127
|
+
getIndexInfo as default,
|
|
128
|
+
getMergedIndexInfo
|
|
8
129
|
};
|
package/dist/index23.mjs
CHANGED
|
@@ -1,28 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (allFieldsDeactivated) {
|
|
6
|
-
const result2 = { ...item };
|
|
7
|
-
Object.keys(fields).forEach((key) => {
|
|
8
|
-
const fieldValue = get(item, key);
|
|
9
|
-
if (fieldValue === void 0)
|
|
10
|
-
return;
|
|
11
|
-
set(result2, key, void 0, true);
|
|
12
|
-
});
|
|
13
|
-
return result2;
|
|
14
|
-
}
|
|
15
|
-
const result = {};
|
|
16
|
-
Object.entries(fields).forEach(([key, value]) => {
|
|
17
|
-
const fieldValue = get(item, key);
|
|
18
|
-
if (fieldValue === void 0)
|
|
19
|
-
return;
|
|
20
|
-
if (fieldValue == null && value !== 1)
|
|
21
|
-
return;
|
|
22
|
-
set(result, key, value === 1 ? fieldValue : void 0);
|
|
23
|
-
});
|
|
24
|
-
return result;
|
|
1
|
+
import { Query } from "mingo";
|
|
2
|
+
function match(item, selector) {
|
|
3
|
+
const query = new Query(selector);
|
|
4
|
+
return query.test(item);
|
|
25
5
|
}
|
|
26
6
|
export {
|
|
27
|
-
|
|
7
|
+
match as default
|
|
28
8
|
};
|
package/dist/index24.mjs
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import get from "./index10.mjs";
|
|
2
|
+
import set from "./index31.mjs";
|
|
3
|
+
function project(item, fields) {
|
|
4
|
+
const allFieldsDeactivated = Object.values(fields).every((value) => value === 0);
|
|
5
|
+
if (allFieldsDeactivated) {
|
|
6
|
+
const result2 = { ...item };
|
|
7
|
+
Object.keys(fields).forEach((key) => {
|
|
8
|
+
const fieldValue = get(item, key);
|
|
9
|
+
if (fieldValue === void 0)
|
|
10
|
+
return;
|
|
11
|
+
set(result2, key, void 0, true);
|
|
12
|
+
});
|
|
13
|
+
return result2;
|
|
14
|
+
}
|
|
15
|
+
const result = {};
|
|
16
|
+
Object.entries(fields).forEach(([key, value]) => {
|
|
17
|
+
const fieldValue = get(item, key);
|
|
18
|
+
if (fieldValue === void 0)
|
|
19
|
+
return;
|
|
20
|
+
if (fieldValue == null && value !== 1)
|
|
21
|
+
return;
|
|
22
|
+
set(result, key, value === 1 ? fieldValue : void 0);
|
|
23
|
+
});
|
|
24
|
+
return result;
|
|
5
25
|
}
|
|
6
26
|
export {
|
|
7
|
-
|
|
27
|
+
project as default
|
|
8
28
|
};
|
package/dist/index27.mjs
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
1
|
+
function batchOnNextTick(onFlush) {
|
|
2
|
+
const queues = /* @__PURE__ */ new Map();
|
|
3
|
+
function enqueue(key, args) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
let q = queues.get(key);
|
|
6
|
+
if (!q) {
|
|
7
|
+
q = {
|
|
8
|
+
timer: null,
|
|
9
|
+
items: [],
|
|
10
|
+
flush: () => flush(key)
|
|
11
|
+
};
|
|
12
|
+
queues.set(key, q);
|
|
13
|
+
}
|
|
14
|
+
q.items.push({ args, resolve, reject });
|
|
15
|
+
if (q.timer == null) {
|
|
16
|
+
q.timer = setTimeout(() => {
|
|
17
|
+
q.timer = null;
|
|
18
|
+
void q.flush();
|
|
19
|
+
}, 0);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async function flush(key) {
|
|
24
|
+
const q = queues.get(key);
|
|
25
|
+
if (!q || q.items.length === 0)
|
|
26
|
+
return;
|
|
27
|
+
if (q.timer != null) {
|
|
28
|
+
clearTimeout(q.timer);
|
|
29
|
+
q.timer = null;
|
|
30
|
+
}
|
|
31
|
+
const items = q.items.splice(0);
|
|
32
|
+
onFlush(key, items.map((i) => i.args)).then((results) => {
|
|
33
|
+
for (const [index, result] of results.entries()) {
|
|
34
|
+
const { resolve } = items[index];
|
|
35
|
+
resolve(result);
|
|
36
|
+
}
|
|
37
|
+
}).catch((error) => {
|
|
38
|
+
for (const { reject } of items) {
|
|
39
|
+
reject(error);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return { enqueue, flush };
|
|
3
44
|
}
|
|
4
45
|
export {
|
|
5
|
-
|
|
46
|
+
batchOnNextTick as default
|
|
6
47
|
};
|
package/dist/index28.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
function truthy(value) {
|
|
2
|
+
return !!value;
|
|
3
|
+
}
|
|
4
|
+
function compact(array) {
|
|
5
|
+
return array.filter(truthy);
|
|
5
6
|
}
|
|
6
7
|
export {
|
|
7
|
-
|
|
8
|
+
compact as default
|
|
8
9
|
};
|
package/dist/index29.mjs
CHANGED
|
@@ -1,30 +1,8 @@
|
|
|
1
|
-
function
|
|
2
|
-
if (
|
|
3
|
-
return
|
|
4
|
-
|
|
5
|
-
if (segments[0] === "")
|
|
6
|
-
segments.shift();
|
|
7
|
-
if (segments.at(-1) === "")
|
|
8
|
-
segments.pop();
|
|
9
|
-
const apply = (node) => {
|
|
10
|
-
if (segments.length > 1) {
|
|
11
|
-
const key = segments.shift();
|
|
12
|
-
const nextIsNumber = !Number.isNaN(Number.parseInt(segments[0], 10));
|
|
13
|
-
if (node[key] === void 0) {
|
|
14
|
-
node[key] = nextIsNumber ? [] : {};
|
|
15
|
-
}
|
|
16
|
-
apply(node[key]);
|
|
17
|
-
} else {
|
|
18
|
-
if (deleteIfUndefined && value === void 0) {
|
|
19
|
-
delete node[segments[0]];
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
node[segments[0]] = value;
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
apply(object);
|
|
26
|
-
return object;
|
|
1
|
+
function intersection(...arrays) {
|
|
2
|
+
if (arrays.length === 0)
|
|
3
|
+
return [];
|
|
4
|
+
return [...new Set(arrays.reduce((a, b) => a.filter((c) => b.includes(c))))];
|
|
27
5
|
}
|
|
28
6
|
export {
|
|
29
|
-
|
|
7
|
+
intersection as default
|
|
30
8
|
};
|
package/dist/index3.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import randomId from "./index8.mjs";
|
|
|
4
4
|
import DefaultDataAdapter from "./index12.mjs";
|
|
5
5
|
import modify from "./index7.mjs";
|
|
6
6
|
import deepClone from "./index19.mjs";
|
|
7
|
+
import queryId from "./index20.mjs";
|
|
7
8
|
import Cursor from "./index2.mjs";
|
|
8
9
|
class Collection extends EventEmitter {
|
|
9
10
|
static collections = [];
|
|
@@ -66,6 +67,7 @@ class Collection extends EventEmitter {
|
|
|
66
67
|
isDisposed = false;
|
|
67
68
|
postBatchCallbacks = /* @__PURE__ */ new Set();
|
|
68
69
|
fieldTracking = false;
|
|
70
|
+
queryListenersMap = /* @__PURE__ */ new Map();
|
|
69
71
|
constructor(nameOrOptions, maybeDataAdapter, maybeOptions) {
|
|
70
72
|
super();
|
|
71
73
|
const name = typeof nameOrOptions === "string" ? nameOrOptions : nameOrOptions?.name || `${this.constructor.name}-${randomId()}`;
|
|
@@ -190,6 +192,11 @@ class Collection extends EventEmitter {
|
|
|
190
192
|
return item;
|
|
191
193
|
return this.options.transform(item);
|
|
192
194
|
}
|
|
195
|
+
transformAll(items, fields) {
|
|
196
|
+
if (!this.options.transformAll)
|
|
197
|
+
return items;
|
|
198
|
+
return this.options.transformAll(deepClone(items), fields);
|
|
199
|
+
}
|
|
193
200
|
getItem(selector, options) {
|
|
194
201
|
const itemsOrPromise = this.getItems(selector, { ...options, limit: 1 });
|
|
195
202
|
if (itemsOrPromise instanceof Promise) {
|
|
@@ -204,21 +211,9 @@ class Collection extends EventEmitter {
|
|
|
204
211
|
return this.profile(() => {
|
|
205
212
|
if (!options?.async)
|
|
206
213
|
return this.backend.getQueryResult(selector, options);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const cleanup = this.backend.onQueryStateChange(selector, options, (state) => {
|
|
210
|
-
if (state === "error") {
|
|
211
|
-
cleanup();
|
|
212
|
-
reject(this.backend.getQueryError(selector, options) || new Error("Unknown error"));
|
|
213
|
-
} else if (state === "complete") {
|
|
214
|
-
cleanup();
|
|
215
|
-
resolve(this.backend.getQueryResult(selector, options) || []);
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
this.backend.registerQuery(selector, options);
|
|
219
|
-
}).finally(() => {
|
|
214
|
+
this.isPullingSignal.set(true);
|
|
215
|
+
return this.backend.executeQuery(selector, options).finally(() => {
|
|
220
216
|
this.isPullingSignal.set(false);
|
|
221
|
-
this.backend.unregisterQuery(selector, options);
|
|
222
217
|
});
|
|
223
218
|
}, (measuredTime) => this.executeInDebugMode((callstack) => this.emit("_debug.getItems", callstack, selector, measuredTime)));
|
|
224
219
|
}
|
|
@@ -230,6 +225,13 @@ class Collection extends EventEmitter {
|
|
|
230
225
|
this.isPushingSignal.set(false);
|
|
231
226
|
}
|
|
232
227
|
}
|
|
228
|
+
queryListeners(query, listeners) {
|
|
229
|
+
const id = queryId(query.selector, query.options);
|
|
230
|
+
if (listeners != null) {
|
|
231
|
+
return this.queryListenersMap.set(id, listeners);
|
|
232
|
+
}
|
|
233
|
+
return this.queryListenersMap.get(id) ?? 0;
|
|
234
|
+
}
|
|
233
235
|
/**
|
|
234
236
|
* Disposes the collection, unregisters persistence adapters, clears memory, and
|
|
235
237
|
* cleans up all resources used by the collection.
|
|
@@ -255,7 +257,17 @@ class Collection extends EventEmitter {
|
|
|
255
257
|
throw new Error("Collection is disposed");
|
|
256
258
|
if (selector !== void 0 && (!selector || typeof selector !== "object"))
|
|
257
259
|
throw new Error("Invalid selector");
|
|
258
|
-
const
|
|
260
|
+
const getTransformedItems = () => {
|
|
261
|
+
const itemsOrPromise = this.getItems(selector, options || {});
|
|
262
|
+
if (itemsOrPromise instanceof Promise) {
|
|
263
|
+
return itemsOrPromise.then((items2) => {
|
|
264
|
+
return this.transformAll(items2, options?.fields);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const items = itemsOrPromise;
|
|
268
|
+
return this.transformAll(items, options?.fields);
|
|
269
|
+
};
|
|
270
|
+
const cursor = new Cursor(getTransformedItems, {
|
|
259
271
|
reactive: this.options.reactivity,
|
|
260
272
|
fieldTracking: this.fieldTracking,
|
|
261
273
|
...options,
|
|
@@ -268,17 +280,25 @@ class Collection extends EventEmitter {
|
|
|
268
280
|
}
|
|
269
281
|
requery();
|
|
270
282
|
};
|
|
271
|
-
this.
|
|
272
|
-
|
|
283
|
+
const listeners = this.queryListeners({ selector, options });
|
|
284
|
+
if (listeners === 0)
|
|
285
|
+
this.backend.registerQuery(selector, options || {});
|
|
286
|
+
this.queryListeners({ selector, options }, listeners + 1);
|
|
287
|
+
const queryStateChangeCleanup = this.backend.onQueryStateChange(selector, options || {}, (state) => {
|
|
273
288
|
if (state !== "complete")
|
|
274
289
|
return;
|
|
275
290
|
handleRequery();
|
|
276
291
|
});
|
|
277
292
|
this.emit("observer.created", selector, options);
|
|
278
293
|
return () => {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
294
|
+
setTimeout(() => {
|
|
295
|
+
const newListeners = Math.max(0, this.queryListeners({ selector, options }) - 1);
|
|
296
|
+
if (newListeners === 0)
|
|
297
|
+
this.backend.unregisterQuery(selector, options || {});
|
|
298
|
+
this.queryListeners({ selector, options }, newListeners);
|
|
299
|
+
queryStateChangeCleanup();
|
|
300
|
+
this.emit("observer.disposed", selector, options);
|
|
301
|
+
}, 0);
|
|
282
302
|
};
|
|
283
303
|
}
|
|
284
304
|
});
|
|
@@ -371,9 +391,8 @@ class Collection extends EventEmitter {
|
|
|
371
391
|
throw new Error("Collection is disposed");
|
|
372
392
|
if (!items)
|
|
373
393
|
throw new Error("Invalid items");
|
|
374
|
-
if (items.length === 0)
|
|
394
|
+
if (items.length === 0)
|
|
375
395
|
return [];
|
|
376
|
-
}
|
|
377
396
|
const ids = [];
|
|
378
397
|
await this.batch(async () => {
|
|
379
398
|
await Promise.all(items.map(async (item) => {
|
package/dist/index31.mjs
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
function set(object, path, value, deleteIfUndefined = false) {
|
|
2
|
+
if (object == null)
|
|
3
|
+
return object;
|
|
4
|
+
const segments = path.split(/[.[\]]/g);
|
|
5
|
+
if (segments[0] === "")
|
|
6
|
+
segments.shift();
|
|
7
|
+
if (segments.at(-1) === "")
|
|
8
|
+
segments.pop();
|
|
9
|
+
const apply = (node) => {
|
|
10
|
+
if (segments.length > 1) {
|
|
11
|
+
const key = segments.shift();
|
|
12
|
+
const nextIsNumber = !Number.isNaN(Number.parseInt(segments[0], 10));
|
|
13
|
+
if (node[key] === void 0) {
|
|
14
|
+
node[key] = nextIsNumber ? [] : {};
|
|
15
|
+
}
|
|
16
|
+
apply(node[key]);
|
|
17
|
+
} else {
|
|
18
|
+
if (deleteIfUndefined && value === void 0) {
|
|
19
|
+
delete node[segments[0]];
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
node[segments[0]] = value;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
apply(object);
|
|
26
|
+
return object;
|
|
7
27
|
}
|
|
8
28
|
export {
|
|
9
|
-
|
|
29
|
+
set as default
|
|
10
30
|
};
|
package/dist/index32.mjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function uniqueBy(array, fn) {
|
|
2
|
+
const set = /* @__PURE__ */ new Set();
|
|
3
|
+
return array.filter((element) => {
|
|
4
|
+
const value = typeof fn === "function" ? fn(element) : element[fn];
|
|
5
|
+
return !set.has(value) && set.add(value);
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
uniqueBy as default
|
|
10
|
+
};
|
package/dist/index33.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Groups multiple calls by key and flushes them on the next tick (macrotask).
|
|
3
|
+
* @param onFlush - Function that will be called with the key and all queued items when flushing.
|
|
4
|
+
* @returns An object with `enqueue` and `flush` methods.
|
|
5
|
+
* @example
|
|
6
|
+
* const batcher = batchOnNextTick<string>(async (key, items) => {
|
|
7
|
+
* // items is an array of { args, resolve, reject }
|
|
8
|
+
* // do something once with all args...
|
|
9
|
+
* })
|
|
10
|
+
*
|
|
11
|
+
* batcher.enqueue("my-key", [arg1, arg2])
|
|
12
|
+
*/
|
|
13
|
+
export default function batchOnNextTick<TKey>(onFlush: (key: TKey, items: any[][]) => Promise<any[]>): {
|
|
14
|
+
enqueue: (key: TKey, args: any[]) => Promise<any>;
|
|
15
|
+
flush: (key: TKey) => Promise<void>;
|
|
16
|
+
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @template T - The type of the value to clone.
|
|
5
5
|
* @param value - The value to deep clone.
|
|
6
6
|
* @returns A deep copy of the provided value.
|
|
7
|
-
* @throws An error if the value is a function, as cloning functions is not supported.
|
|
7
|
+
* @throws {Error} An error if the value is a function, as cloning functions is not supported.
|
|
8
8
|
*/
|
|
9
9
|
export declare function clone<T>(value: T): T;
|
|
10
10
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaldb/core",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "SignalDB is a client-side database that provides a simple MongoDB-like interface to the data with first-class typescript support to achieve an optimistic UI. Data persistence can be achieved by using storage providers that store the data through a JSON interface to places such as localStorage.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rimraf dist && vite build",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
],
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"fast-sort": "^3.4.1",
|
|
58
|
-
"mingo": "^
|
|
58
|
+
"mingo": "^7.1.1"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"zod": "^4.
|
|
61
|
+
"zod": "^4.3.5"
|
|
62
62
|
}
|
|
63
63
|
}
|