@signaldb/core 1.3.1 → 1.4.0
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 +3 -3
- package/dist/Collection/index.d.ts +24 -2
- package/dist/index.cjs10.js +3 -0
- package/dist/index.cjs2.js +99 -20
- package/dist/index.cjs22.js +1 -1
- package/dist/index.cjs23.js +1 -1
- package/dist/index.cjs26.js +1 -1
- package/dist/index.cjs27.js +27 -40
- package/dist/index.cjs28.js +7 -27
- package/dist/index.cjs29.js +40 -7
- package/dist/index10.mjs +3 -0
- package/dist/index2.mjs +99 -20
- package/dist/index22.mjs +1 -1
- package/dist/index23.mjs +1 -1
- package/dist/index26.mjs +1 -1
- package/dist/index27.mjs +27 -40
- package/dist/index28.mjs +7 -27
- package/dist/index29.mjs +40 -7
- package/package.json +1 -1
package/dist/.vite/manifest.json
CHANGED
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
"src": "src/utils/isEqual.ts"
|
|
164
164
|
},
|
|
165
165
|
"src/utils/isFieldExpression.ts": {
|
|
166
|
-
"file": "index.
|
|
166
|
+
"file": "index.cjs29.js",
|
|
167
167
|
"name": "utils/isFieldExpression",
|
|
168
168
|
"src": "src/utils/isFieldExpression.ts"
|
|
169
169
|
},
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
"src": "src/utils/serializeValue.ts"
|
|
198
198
|
},
|
|
199
199
|
"src/utils/set.ts": {
|
|
200
|
-
"file": "index.
|
|
200
|
+
"file": "index.cjs27.js",
|
|
201
201
|
"name": "utils/set",
|
|
202
202
|
"src": "src/utils/set.ts"
|
|
203
203
|
},
|
|
@@ -210,7 +210,7 @@
|
|
|
210
210
|
]
|
|
211
211
|
},
|
|
212
212
|
"src/utils/uniqueBy.ts": {
|
|
213
|
-
"file": "index.
|
|
213
|
+
"file": "index.cjs28.js",
|
|
214
214
|
"name": "utils/uniqueBy",
|
|
215
215
|
"src": "src/utils/uniqueBy.ts"
|
|
216
216
|
}
|
|
@@ -41,6 +41,7 @@ interface CollectionEvents<T extends BaseItem, U = T> {
|
|
|
41
41
|
'insert': (item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
|
|
42
42
|
'updateOne': (selector: Selector<T>, modifier: Modifier<T>) => void;
|
|
43
43
|
'updateMany': (selector: Selector<T>, modifier: Modifier<T>) => void;
|
|
44
|
+
'replaceOne': (selector: Selector<T>, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
|
|
44
45
|
'removeOne': (selector: Selector<T>) => void;
|
|
45
46
|
'removeMany': (selector: Selector<T>) => void;
|
|
46
47
|
'_debug.getItems': (callstack: string, selector: Selector<T> | undefined, measuredTime: number) => void;
|
|
@@ -49,6 +50,7 @@ interface CollectionEvents<T extends BaseItem, U = T> {
|
|
|
49
50
|
'_debug.insert': (callstack: string, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
|
|
50
51
|
'_debug.updateOne': (callstack: string, selector: Selector<T>, modifier: Modifier<T>) => void;
|
|
51
52
|
'_debug.updateMany': (callstack: string, selector: Selector<T>, modifier: Modifier<T>) => void;
|
|
53
|
+
'_debug.replaceOne': (callstack: string, selector: Selector<T>, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
|
|
52
54
|
'_debug.removeOne': (callstack: string, selector: Selector<T>) => void;
|
|
53
55
|
'_debug.removeMany': (callstack: string, selector: Selector<T>) => void;
|
|
54
56
|
}
|
|
@@ -229,18 +231,38 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, U = T
|
|
|
229
231
|
* Updates a single item in the collection that matches the given selector.
|
|
230
232
|
* @param selector - The criteria to select the item to update.
|
|
231
233
|
* @param modifier - The modifications to apply to the item.
|
|
234
|
+
* @param [options] - Optional settings for the update operation.
|
|
235
|
+
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
|
|
232
236
|
* @returns The number of items updated (0 or 1).
|
|
233
237
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
234
238
|
*/
|
|
235
|
-
updateOne(selector: Selector<T>, modifier: Modifier<T
|
|
239
|
+
updateOne(selector: Selector<T>, modifier: Modifier<T>, options?: {
|
|
240
|
+
upsert?: boolean;
|
|
241
|
+
}): 0 | 1;
|
|
236
242
|
/**
|
|
237
243
|
* Updates multiple items in the collection that match the given selector.
|
|
238
244
|
* @param selector - The criteria to select the items to update.
|
|
239
245
|
* @param modifier - The modifications to apply to the items.
|
|
246
|
+
* @param [options] - Optional settings for the update operation.
|
|
247
|
+
* @param [options.upsert] - If `true`, creates new items if no items match the selector.
|
|
240
248
|
* @returns The number of items updated.
|
|
241
249
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
242
250
|
*/
|
|
243
|
-
updateMany(selector: Selector<T>, modifier: Modifier<T
|
|
251
|
+
updateMany(selector: Selector<T>, modifier: Modifier<T>, options?: {
|
|
252
|
+
upsert?: boolean;
|
|
253
|
+
}): number;
|
|
254
|
+
/**
|
|
255
|
+
* Replaces a single item in the collection that matches the given selector.
|
|
256
|
+
* @param selector - The criteria to select the item to replace.
|
|
257
|
+
* @param replacement - The item to replace the selected item with.
|
|
258
|
+
* @param [options] - Optional settings for the replace operation.
|
|
259
|
+
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
|
|
260
|
+
* @returns The number of items replaced (0 or 1).
|
|
261
|
+
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
262
|
+
*/
|
|
263
|
+
replaceOne(selector: Selector<T>, replacement: Omit<T, 'id'> & Partial<Pick<T, 'id'>>, options?: {
|
|
264
|
+
upsert?: boolean;
|
|
265
|
+
}): 0 | 1;
|
|
244
266
|
/**
|
|
245
267
|
* Removes a single item from the collection that matches the given selector.
|
|
246
268
|
* @param selector - The criteria to select the item to remove.
|
package/dist/index.cjs10.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const mingo = require("mingo");
|
|
3
3
|
function modify(item, modifier) {
|
|
4
|
+
const hasOperators = Object.keys(modifier).some((key) => key.startsWith("$"));
|
|
5
|
+
if (!hasOperators)
|
|
6
|
+
return modifier;
|
|
4
7
|
const clonedItem = { ...item };
|
|
5
8
|
mingo.update(clonedItem, modifier);
|
|
6
9
|
return clonedItem;
|
package/dist/index.cjs2.js
CHANGED
|
@@ -567,61 +567,140 @@ const _Collection = class _Collection extends EventEmitter {
|
|
|
567
567
|
* Updates a single item in the collection that matches the given selector.
|
|
568
568
|
* @param selector - The criteria to select the item to update.
|
|
569
569
|
* @param modifier - The modifications to apply to the item.
|
|
570
|
+
* @param [options] - Optional settings for the update operation.
|
|
571
|
+
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
|
|
570
572
|
* @returns The number of items updated (0 or 1).
|
|
571
573
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
572
574
|
*/
|
|
573
|
-
updateOne(selector, modifier) {
|
|
575
|
+
updateOne(selector, modifier, options) {
|
|
574
576
|
if (this.isDisposed)
|
|
575
577
|
throw new Error("Collection is disposed");
|
|
576
578
|
if (!selector)
|
|
577
579
|
throw new Error("Invalid selector");
|
|
578
580
|
if (!modifier)
|
|
579
581
|
throw new Error("Invalid modifier");
|
|
582
|
+
const { $setOnInsert, ...restModifier } = modifier;
|
|
580
583
|
const { item, index } = this.getItemAndIndex(selector);
|
|
581
|
-
if (item == null)
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
584
|
+
if (item == null) {
|
|
585
|
+
if (options == null ? void 0 : options.upsert) {
|
|
586
|
+
const newItem = modify({}, {
|
|
587
|
+
...restModifier,
|
|
588
|
+
$set: {
|
|
589
|
+
...$setOnInsert,
|
|
590
|
+
...restModifier.$set
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
if (newItem.id != null && this.getItemAndIndex({ id: newItem.id }).item != null) {
|
|
594
|
+
throw new Error("Item with same id already exists");
|
|
595
|
+
}
|
|
596
|
+
this.insert(newItem);
|
|
597
|
+
}
|
|
598
|
+
} else {
|
|
599
|
+
const modifiedItem = modify(deepClone.default(item), restModifier);
|
|
600
|
+
if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
|
|
601
|
+
throw new Error("Item with same id already exists");
|
|
602
|
+
}
|
|
603
|
+
this.memory().splice(index, 1, modifiedItem);
|
|
604
|
+
this.rebuildIndices();
|
|
605
|
+
this.emit("changed", modifiedItem, restModifier);
|
|
606
|
+
}
|
|
590
607
|
this.emit("updateOne", selector, modifier);
|
|
591
608
|
this.executeInDebugMode((callstack) => this.emit("_debug.updateOne", callstack, selector, modifier));
|
|
609
|
+
if (item == null && !(options == null ? void 0 : options.upsert))
|
|
610
|
+
return 0;
|
|
592
611
|
return 1;
|
|
593
612
|
}
|
|
594
613
|
/**
|
|
595
614
|
* Updates multiple items in the collection that match the given selector.
|
|
596
615
|
* @param selector - The criteria to select the items to update.
|
|
597
616
|
* @param modifier - The modifications to apply to the items.
|
|
617
|
+
* @param [options] - Optional settings for the update operation.
|
|
618
|
+
* @param [options.upsert] - If `true`, creates new items if no items match the selector.
|
|
598
619
|
* @returns The number of items updated.
|
|
599
620
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
600
621
|
*/
|
|
601
|
-
updateMany(selector, modifier) {
|
|
622
|
+
updateMany(selector, modifier, options) {
|
|
602
623
|
if (this.isDisposed)
|
|
603
624
|
throw new Error("Collection is disposed");
|
|
604
625
|
if (!selector)
|
|
605
626
|
throw new Error("Invalid selector");
|
|
606
627
|
if (!modifier)
|
|
607
628
|
throw new Error("Invalid modifier");
|
|
629
|
+
const { $setOnInsert, ...restModifier } = modifier;
|
|
608
630
|
const items = this.getItems(selector);
|
|
609
|
-
|
|
610
|
-
|
|
631
|
+
if (items.length === 0 && (options == null ? void 0 : options.upsert)) {
|
|
632
|
+
const newItem = modify({}, {
|
|
633
|
+
...restModifier,
|
|
634
|
+
$set: {
|
|
635
|
+
...$setOnInsert,
|
|
636
|
+
...restModifier.$set
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
if (newItem.id != null && this.getItemAndIndex({ id: newItem.id }).item != null) {
|
|
640
|
+
throw new Error("Item with same id already exists");
|
|
641
|
+
}
|
|
642
|
+
this.insert(newItem);
|
|
643
|
+
}
|
|
644
|
+
const changes = items.map((item) => {
|
|
611
645
|
const { index } = this.getItemAndIndex({ id: item.id });
|
|
612
646
|
if (index === -1)
|
|
613
|
-
throw new Error(
|
|
614
|
-
const modifiedItem = modify(deepClone.default(item),
|
|
615
|
-
this.
|
|
616
|
-
|
|
647
|
+
throw new Error(`Cannot resolve index for item with id '${item.id}'`);
|
|
648
|
+
const modifiedItem = modify(deepClone.default(item), restModifier);
|
|
649
|
+
if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
|
|
650
|
+
throw new Error(`Item with same id '${modifiedItem.id}' already exists`);
|
|
651
|
+
}
|
|
652
|
+
return {
|
|
653
|
+
item: modifiedItem,
|
|
654
|
+
index
|
|
655
|
+
};
|
|
656
|
+
});
|
|
657
|
+
changes.forEach(({ item, index }) => {
|
|
658
|
+
this.memory().splice(index, 1, item);
|
|
617
659
|
});
|
|
618
660
|
this.rebuildIndices();
|
|
619
|
-
|
|
620
|
-
this.emit("changed",
|
|
661
|
+
changes.forEach(({ item }) => {
|
|
662
|
+
this.emit("changed", item, restModifier);
|
|
621
663
|
});
|
|
622
664
|
this.emit("updateMany", selector, modifier);
|
|
623
665
|
this.executeInDebugMode((callstack) => this.emit("_debug.updateMany", callstack, selector, modifier));
|
|
624
|
-
return
|
|
666
|
+
return changes.length === 0 && (options == null ? void 0 : options.upsert) ? 1 : changes.length;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Replaces a single item in the collection that matches the given selector.
|
|
670
|
+
* @param selector - The criteria to select the item to replace.
|
|
671
|
+
* @param replacement - The item to replace the selected item with.
|
|
672
|
+
* @param [options] - Optional settings for the replace operation.
|
|
673
|
+
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
|
|
674
|
+
* @returns The number of items replaced (0 or 1).
|
|
675
|
+
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
676
|
+
*/
|
|
677
|
+
replaceOne(selector, replacement, options) {
|
|
678
|
+
if (this.isDisposed)
|
|
679
|
+
throw new Error("Collection is disposed");
|
|
680
|
+
if (!selector)
|
|
681
|
+
throw new Error("Invalid selector");
|
|
682
|
+
const { item, index } = this.getItemAndIndex(selector);
|
|
683
|
+
if (item == null) {
|
|
684
|
+
if (options == null ? void 0 : options.upsert) {
|
|
685
|
+
if (replacement.id != null && this.getItemAndIndex({ id: replacement.id }).item != null) {
|
|
686
|
+
throw new Error("Item with same id already exists");
|
|
687
|
+
}
|
|
688
|
+
this.insert(replacement);
|
|
689
|
+
}
|
|
690
|
+
} else {
|
|
691
|
+
if (item.id !== replacement.id && this.getItemAndIndex({ id: replacement.id }).item != null) {
|
|
692
|
+
throw new Error("Item with same id already exists");
|
|
693
|
+
}
|
|
694
|
+
const modifiedItem = { id: item.id, ...replacement };
|
|
695
|
+
this.memory().splice(index, 1, modifiedItem);
|
|
696
|
+
this.rebuildIndices();
|
|
697
|
+
this.emit("changed", modifiedItem, replacement);
|
|
698
|
+
}
|
|
699
|
+
this.emit("replaceOne", selector, replacement);
|
|
700
|
+
this.executeInDebugMode((callstack) => this.emit("_debug.replaceOne", callstack, selector, replacement));
|
|
701
|
+
if (item == null && !(options == null ? void 0 : options.upsert))
|
|
702
|
+
return 0;
|
|
703
|
+
return 1;
|
|
625
704
|
}
|
|
626
705
|
/**
|
|
627
706
|
* Removes a single item from the collection that matches the given selector.
|
package/dist/index.cjs22.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const get = require("./index.cjs25.js");
|
|
3
|
-
const set = require("./index.
|
|
3
|
+
const set = require("./index.cjs27.js");
|
|
4
4
|
function project(item, fields) {
|
|
5
5
|
const allFieldsDeactivated = Object.values(fields).every((value) => value === 0);
|
|
6
6
|
if (allFieldsDeactivated) {
|
package/dist/index.cjs23.js
CHANGED
|
@@ -3,7 +3,7 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
const isEqual = require("./index.cjs9.js");
|
|
6
|
-
const uniqueBy = require("./index.
|
|
6
|
+
const uniqueBy = require("./index.cjs28.js");
|
|
7
7
|
class Observer {
|
|
8
8
|
/**
|
|
9
9
|
* Creates a new instance of the `Observer` class.
|
package/dist/index.cjs26.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const isFieldExpression = require("./index.
|
|
2
|
+
const isFieldExpression = require("./index.cjs29.js");
|
|
3
3
|
const serializeValue = require("./index.cjs16.js");
|
|
4
4
|
function getMatchingKeys(field, selector) {
|
|
5
5
|
const result = { include: null, exclude: null };
|
package/dist/index.cjs27.js
CHANGED
|
@@ -1,42 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function isFieldExpression(expression) {
|
|
29
|
-
if (typeof expression !== "object" || expression == null) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
const keys = Object.keys(expression);
|
|
33
|
-
if (keys.length === 0) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
const hasInvalidKeys = keys.some((key) => !expressionKeys.has(key));
|
|
37
|
-
if (hasInvalidKeys)
|
|
38
|
-
return false;
|
|
39
|
-
const hasValidKeys = keys.every((key) => expressionKeys.has(key));
|
|
40
|
-
return hasValidKeys;
|
|
2
|
+
function set(object, path, value, deleteIfUndefined = false) {
|
|
3
|
+
if (object == null)
|
|
4
|
+
return object;
|
|
5
|
+
const segments = path.split(/[.[\]]/g);
|
|
6
|
+
if (segments[0] === "")
|
|
7
|
+
segments.shift();
|
|
8
|
+
if (segments.at(-1) === "")
|
|
9
|
+
segments.pop();
|
|
10
|
+
const apply = (node) => {
|
|
11
|
+
if (segments.length > 1) {
|
|
12
|
+
const key = segments.shift();
|
|
13
|
+
const nextIsNumber = !Number.isNaN(Number.parseInt(segments[0], 10));
|
|
14
|
+
if (node[key] === void 0) {
|
|
15
|
+
node[key] = nextIsNumber ? [] : {};
|
|
16
|
+
}
|
|
17
|
+
apply(node[key]);
|
|
18
|
+
} else {
|
|
19
|
+
if (deleteIfUndefined && value === void 0) {
|
|
20
|
+
delete node[segments[0]];
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
node[segments[0]] = value;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
apply(object);
|
|
27
|
+
return object;
|
|
41
28
|
}
|
|
42
|
-
module.exports =
|
|
29
|
+
module.exports = set;
|
package/dist/index.cjs28.js
CHANGED
|
@@ -1,29 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (segments.at(-1) === "")
|
|
9
|
-
segments.pop();
|
|
10
|
-
const apply = (node) => {
|
|
11
|
-
if (segments.length > 1) {
|
|
12
|
-
const key = segments.shift();
|
|
13
|
-
const nextIsNumber = !Number.isNaN(Number.parseInt(segments[0], 10));
|
|
14
|
-
if (node[key] === void 0) {
|
|
15
|
-
node[key] = nextIsNumber ? [] : {};
|
|
16
|
-
}
|
|
17
|
-
apply(node[key]);
|
|
18
|
-
} else {
|
|
19
|
-
if (deleteIfUndefined && value === void 0) {
|
|
20
|
-
delete node[segments[0]];
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
node[segments[0]] = value;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
apply(object);
|
|
27
|
-
return object;
|
|
2
|
+
function uniqueBy(array, fn) {
|
|
3
|
+
const set = /* @__PURE__ */ new Set();
|
|
4
|
+
return array.filter((element) => {
|
|
5
|
+
const value = typeof fn === "function" ? fn(element) : element[fn];
|
|
6
|
+
return !set.has(value) && set.add(value);
|
|
7
|
+
});
|
|
28
8
|
}
|
|
29
|
-
module.exports =
|
|
9
|
+
module.exports = uniqueBy;
|
package/dist/index.cjs29.js
CHANGED
|
@@ -1,9 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
const expressionKeys = /* @__PURE__ */ new Set([
|
|
3
|
+
"$eq",
|
|
4
|
+
"$gt",
|
|
5
|
+
"$gte",
|
|
6
|
+
"$lt",
|
|
7
|
+
"$lte",
|
|
8
|
+
"$in",
|
|
9
|
+
"$nin",
|
|
10
|
+
"$ne",
|
|
11
|
+
"$exists",
|
|
12
|
+
"$not",
|
|
13
|
+
"$expr",
|
|
14
|
+
"$jsonSchema",
|
|
15
|
+
"$mod",
|
|
16
|
+
"$regex",
|
|
17
|
+
"$options",
|
|
18
|
+
"$text",
|
|
19
|
+
"$where",
|
|
20
|
+
"$all",
|
|
21
|
+
"$elemMatch",
|
|
22
|
+
"$size",
|
|
23
|
+
"$bitsAllClear",
|
|
24
|
+
"$bitsAllSet",
|
|
25
|
+
"$bitsAnyClear",
|
|
26
|
+
"$bitsAnySet"
|
|
27
|
+
]);
|
|
28
|
+
function isFieldExpression(expression) {
|
|
29
|
+
if (typeof expression !== "object" || expression == null) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const keys = Object.keys(expression);
|
|
33
|
+
if (keys.length === 0) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const hasInvalidKeys = keys.some((key) => !expressionKeys.has(key));
|
|
37
|
+
if (hasInvalidKeys)
|
|
38
|
+
return false;
|
|
39
|
+
const hasValidKeys = keys.every((key) => expressionKeys.has(key));
|
|
40
|
+
return hasValidKeys;
|
|
8
41
|
}
|
|
9
|
-
module.exports =
|
|
42
|
+
module.exports = isFieldExpression;
|
package/dist/index10.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { update } from "mingo";
|
|
2
2
|
function modify(item, modifier) {
|
|
3
|
+
const hasOperators = Object.keys(modifier).some((key) => key.startsWith("$"));
|
|
4
|
+
if (!hasOperators)
|
|
5
|
+
return modifier;
|
|
3
6
|
const clonedItem = { ...item };
|
|
4
7
|
update(clonedItem, modifier);
|
|
5
8
|
return clonedItem;
|
package/dist/index2.mjs
CHANGED
|
@@ -566,61 +566,140 @@ const _Collection = class _Collection extends EventEmitter {
|
|
|
566
566
|
* Updates a single item in the collection that matches the given selector.
|
|
567
567
|
* @param selector - The criteria to select the item to update.
|
|
568
568
|
* @param modifier - The modifications to apply to the item.
|
|
569
|
+
* @param [options] - Optional settings for the update operation.
|
|
570
|
+
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
|
|
569
571
|
* @returns The number of items updated (0 or 1).
|
|
570
572
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
571
573
|
*/
|
|
572
|
-
updateOne(selector, modifier) {
|
|
574
|
+
updateOne(selector, modifier, options) {
|
|
573
575
|
if (this.isDisposed)
|
|
574
576
|
throw new Error("Collection is disposed");
|
|
575
577
|
if (!selector)
|
|
576
578
|
throw new Error("Invalid selector");
|
|
577
579
|
if (!modifier)
|
|
578
580
|
throw new Error("Invalid modifier");
|
|
581
|
+
const { $setOnInsert, ...restModifier } = modifier;
|
|
579
582
|
const { item, index } = this.getItemAndIndex(selector);
|
|
580
|
-
if (item == null)
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
583
|
+
if (item == null) {
|
|
584
|
+
if (options == null ? void 0 : options.upsert) {
|
|
585
|
+
const newItem = modify({}, {
|
|
586
|
+
...restModifier,
|
|
587
|
+
$set: {
|
|
588
|
+
...$setOnInsert,
|
|
589
|
+
...restModifier.$set
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
if (newItem.id != null && this.getItemAndIndex({ id: newItem.id }).item != null) {
|
|
593
|
+
throw new Error("Item with same id already exists");
|
|
594
|
+
}
|
|
595
|
+
this.insert(newItem);
|
|
596
|
+
}
|
|
597
|
+
} else {
|
|
598
|
+
const modifiedItem = modify(deepClone(item), restModifier);
|
|
599
|
+
if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
|
|
600
|
+
throw new Error("Item with same id already exists");
|
|
601
|
+
}
|
|
602
|
+
this.memory().splice(index, 1, modifiedItem);
|
|
603
|
+
this.rebuildIndices();
|
|
604
|
+
this.emit("changed", modifiedItem, restModifier);
|
|
605
|
+
}
|
|
589
606
|
this.emit("updateOne", selector, modifier);
|
|
590
607
|
this.executeInDebugMode((callstack) => this.emit("_debug.updateOne", callstack, selector, modifier));
|
|
608
|
+
if (item == null && !(options == null ? void 0 : options.upsert))
|
|
609
|
+
return 0;
|
|
591
610
|
return 1;
|
|
592
611
|
}
|
|
593
612
|
/**
|
|
594
613
|
* Updates multiple items in the collection that match the given selector.
|
|
595
614
|
* @param selector - The criteria to select the items to update.
|
|
596
615
|
* @param modifier - The modifications to apply to the items.
|
|
616
|
+
* @param [options] - Optional settings for the update operation.
|
|
617
|
+
* @param [options.upsert] - If `true`, creates new items if no items match the selector.
|
|
597
618
|
* @returns The number of items updated.
|
|
598
619
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
599
620
|
*/
|
|
600
|
-
updateMany(selector, modifier) {
|
|
621
|
+
updateMany(selector, modifier, options) {
|
|
601
622
|
if (this.isDisposed)
|
|
602
623
|
throw new Error("Collection is disposed");
|
|
603
624
|
if (!selector)
|
|
604
625
|
throw new Error("Invalid selector");
|
|
605
626
|
if (!modifier)
|
|
606
627
|
throw new Error("Invalid modifier");
|
|
628
|
+
const { $setOnInsert, ...restModifier } = modifier;
|
|
607
629
|
const items = this.getItems(selector);
|
|
608
|
-
|
|
609
|
-
|
|
630
|
+
if (items.length === 0 && (options == null ? void 0 : options.upsert)) {
|
|
631
|
+
const newItem = modify({}, {
|
|
632
|
+
...restModifier,
|
|
633
|
+
$set: {
|
|
634
|
+
...$setOnInsert,
|
|
635
|
+
...restModifier.$set
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
if (newItem.id != null && this.getItemAndIndex({ id: newItem.id }).item != null) {
|
|
639
|
+
throw new Error("Item with same id already exists");
|
|
640
|
+
}
|
|
641
|
+
this.insert(newItem);
|
|
642
|
+
}
|
|
643
|
+
const changes = items.map((item) => {
|
|
610
644
|
const { index } = this.getItemAndIndex({ id: item.id });
|
|
611
645
|
if (index === -1)
|
|
612
|
-
throw new Error(
|
|
613
|
-
const modifiedItem = modify(deepClone(item),
|
|
614
|
-
this.
|
|
615
|
-
|
|
646
|
+
throw new Error(`Cannot resolve index for item with id '${item.id}'`);
|
|
647
|
+
const modifiedItem = modify(deepClone(item), restModifier);
|
|
648
|
+
if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
|
|
649
|
+
throw new Error(`Item with same id '${modifiedItem.id}' already exists`);
|
|
650
|
+
}
|
|
651
|
+
return {
|
|
652
|
+
item: modifiedItem,
|
|
653
|
+
index
|
|
654
|
+
};
|
|
655
|
+
});
|
|
656
|
+
changes.forEach(({ item, index }) => {
|
|
657
|
+
this.memory().splice(index, 1, item);
|
|
616
658
|
});
|
|
617
659
|
this.rebuildIndices();
|
|
618
|
-
|
|
619
|
-
this.emit("changed",
|
|
660
|
+
changes.forEach(({ item }) => {
|
|
661
|
+
this.emit("changed", item, restModifier);
|
|
620
662
|
});
|
|
621
663
|
this.emit("updateMany", selector, modifier);
|
|
622
664
|
this.executeInDebugMode((callstack) => this.emit("_debug.updateMany", callstack, selector, modifier));
|
|
623
|
-
return
|
|
665
|
+
return changes.length === 0 && (options == null ? void 0 : options.upsert) ? 1 : changes.length;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Replaces a single item in the collection that matches the given selector.
|
|
669
|
+
* @param selector - The criteria to select the item to replace.
|
|
670
|
+
* @param replacement - The item to replace the selected item with.
|
|
671
|
+
* @param [options] - Optional settings for the replace operation.
|
|
672
|
+
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
|
|
673
|
+
* @returns The number of items replaced (0 or 1).
|
|
674
|
+
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
675
|
+
*/
|
|
676
|
+
replaceOne(selector, replacement, options) {
|
|
677
|
+
if (this.isDisposed)
|
|
678
|
+
throw new Error("Collection is disposed");
|
|
679
|
+
if (!selector)
|
|
680
|
+
throw new Error("Invalid selector");
|
|
681
|
+
const { item, index } = this.getItemAndIndex(selector);
|
|
682
|
+
if (item == null) {
|
|
683
|
+
if (options == null ? void 0 : options.upsert) {
|
|
684
|
+
if (replacement.id != null && this.getItemAndIndex({ id: replacement.id }).item != null) {
|
|
685
|
+
throw new Error("Item with same id already exists");
|
|
686
|
+
}
|
|
687
|
+
this.insert(replacement);
|
|
688
|
+
}
|
|
689
|
+
} else {
|
|
690
|
+
if (item.id !== replacement.id && this.getItemAndIndex({ id: replacement.id }).item != null) {
|
|
691
|
+
throw new Error("Item with same id already exists");
|
|
692
|
+
}
|
|
693
|
+
const modifiedItem = { id: item.id, ...replacement };
|
|
694
|
+
this.memory().splice(index, 1, modifiedItem);
|
|
695
|
+
this.rebuildIndices();
|
|
696
|
+
this.emit("changed", modifiedItem, replacement);
|
|
697
|
+
}
|
|
698
|
+
this.emit("replaceOne", selector, replacement);
|
|
699
|
+
this.executeInDebugMode((callstack) => this.emit("_debug.replaceOne", callstack, selector, replacement));
|
|
700
|
+
if (item == null && !(options == null ? void 0 : options.upsert))
|
|
701
|
+
return 0;
|
|
702
|
+
return 1;
|
|
624
703
|
}
|
|
625
704
|
/**
|
|
626
705
|
* Removes a single item from the collection that matches the given selector.
|
package/dist/index22.mjs
CHANGED
package/dist/index23.mjs
CHANGED
|
@@ -2,7 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import isEqual from "./index9.mjs";
|
|
5
|
-
import uniqueBy from "./
|
|
5
|
+
import uniqueBy from "./index28.mjs";
|
|
6
6
|
class Observer {
|
|
7
7
|
/**
|
|
8
8
|
* Creates a new instance of the `Observer` class.
|
package/dist/index26.mjs
CHANGED
package/dist/index27.mjs
CHANGED
|
@@ -1,43 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function isFieldExpression(expression) {
|
|
28
|
-
if (typeof expression !== "object" || expression == null) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
const keys = Object.keys(expression);
|
|
32
|
-
if (keys.length === 0) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
const hasInvalidKeys = keys.some((key) => !expressionKeys.has(key));
|
|
36
|
-
if (hasInvalidKeys)
|
|
37
|
-
return false;
|
|
38
|
-
const hasValidKeys = keys.every((key) => expressionKeys.has(key));
|
|
39
|
-
return hasValidKeys;
|
|
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;
|
|
40
27
|
}
|
|
41
28
|
export {
|
|
42
|
-
|
|
29
|
+
set as default
|
|
43
30
|
};
|
package/dist/index28.mjs
CHANGED
|
@@ -1,30 +1,10 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 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
|
+
});
|
|
27
7
|
}
|
|
28
8
|
export {
|
|
29
|
-
|
|
9
|
+
uniqueBy as default
|
|
30
10
|
};
|
package/dist/index29.mjs
CHANGED
|
@@ -1,10 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const expressionKeys = /* @__PURE__ */ new Set([
|
|
2
|
+
"$eq",
|
|
3
|
+
"$gt",
|
|
4
|
+
"$gte",
|
|
5
|
+
"$lt",
|
|
6
|
+
"$lte",
|
|
7
|
+
"$in",
|
|
8
|
+
"$nin",
|
|
9
|
+
"$ne",
|
|
10
|
+
"$exists",
|
|
11
|
+
"$not",
|
|
12
|
+
"$expr",
|
|
13
|
+
"$jsonSchema",
|
|
14
|
+
"$mod",
|
|
15
|
+
"$regex",
|
|
16
|
+
"$options",
|
|
17
|
+
"$text",
|
|
18
|
+
"$where",
|
|
19
|
+
"$all",
|
|
20
|
+
"$elemMatch",
|
|
21
|
+
"$size",
|
|
22
|
+
"$bitsAllClear",
|
|
23
|
+
"$bitsAllSet",
|
|
24
|
+
"$bitsAnyClear",
|
|
25
|
+
"$bitsAnySet"
|
|
26
|
+
]);
|
|
27
|
+
function isFieldExpression(expression) {
|
|
28
|
+
if (typeof expression !== "object" || expression == null) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const keys = Object.keys(expression);
|
|
32
|
+
if (keys.length === 0) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const hasInvalidKeys = keys.some((key) => !expressionKeys.has(key));
|
|
36
|
+
if (hasInvalidKeys)
|
|
37
|
+
return false;
|
|
38
|
+
const hasValidKeys = keys.every((key) => expressionKeys.has(key));
|
|
39
|
+
return hasValidKeys;
|
|
7
40
|
}
|
|
8
41
|
export {
|
|
9
|
-
|
|
42
|
+
isFieldExpression as default
|
|
10
43
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaldb/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
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"
|