@signaldb/core 1.7.1 → 2.0.0-beta.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 +125 -82
- package/dist/AsyncDataAdapter.d.ts +64 -0
- package/dist/AutoFetchDataAdapter.d.ts +113 -0
- package/dist/Collection/Cursor.d.ts +9 -9
- package/dist/Collection/Observer.d.ts +3 -2
- package/dist/Collection/index.d.ts +52 -46
- package/dist/Collection/types.d.ts +4 -9
- package/dist/DataAdapter.d.ts +33 -0
- package/dist/DefaultDataAdapter.d.ts +32 -0
- package/dist/WorkerDataAdapter.d.ts +22 -0
- package/dist/WorkerDataAdapterHost.d.ts +59 -0
- package/dist/createIndex.d.ts +7 -0
- package/dist/createStorageAdapter.d.ts +9 -0
- package/dist/{Collection/getIndexInfo.d.ts → getIndexInfo.d.ts} +17 -19
- package/dist/index.cjs.js +21 -17
- package/dist/index.cjs10.js +15 -26
- package/dist/index.cjs11.js +13 -10
- package/dist/index.cjs12.js +337 -3
- package/dist/index.cjs13.js +384 -110
- package/dist/index.cjs14.js +183 -67
- package/dist/index.cjs15.js +339 -8
- package/dist/index.cjs16.js +563 -20
- package/dist/index.cjs17.js +12 -4
- package/dist/index.cjs18.js +24 -5
- package/dist/index.cjs2.js +24 -30
- package/dist/index.cjs20.js +102 -13
- package/dist/index.cjs21.js +124 -21
- package/dist/index.cjs22.js +5 -77
- package/dist/index.cjs23.js +22 -79
- package/dist/index.cjs24.js +5 -16
- package/dist/index.cjs25.js +8 -27
- package/dist/index.cjs26.js +27 -7
- package/dist/index.cjs27.js +3 -5
- package/dist/index.cjs28.js +5 -27
- package/dist/index.cjs29.js +27 -40
- package/dist/index.cjs3.js +191 -441
- package/dist/index.cjs30.js +42 -0
- package/dist/index.cjs31.js +9 -0
- package/dist/index.cjs4.js +3 -165
- package/dist/index.cjs5.js +3 -66
- package/dist/index.cjs6.js +27 -3
- package/dist/index.cjs7.js +10 -3
- package/dist/index.cjs8.js +3 -3
- package/dist/index.cjs9.js +131 -3
- package/dist/index.d.ts +10 -8
- package/dist/index.mjs +15 -11
- package/dist/index10.mjs +15 -26
- package/dist/index11.mjs +13 -10
- package/dist/index12.mjs +337 -3
- package/dist/index13.mjs +384 -110
- package/dist/index14.mjs +183 -66
- package/dist/index15.mjs +339 -8
- package/dist/index16.mjs +563 -20
- package/dist/index17.mjs +12 -4
- package/dist/index18.mjs +24 -5
- package/dist/index2.mjs +24 -30
- package/dist/index20.mjs +102 -13
- package/dist/index21.mjs +123 -21
- package/dist/index22.mjs +5 -76
- package/dist/index23.mjs +22 -78
- package/dist/index24.mjs +5 -16
- package/dist/index25.mjs +8 -27
- package/dist/index26.mjs +27 -7
- package/dist/index27.mjs +3 -5
- package/dist/index28.mjs +5 -27
- package/dist/index29.mjs +27 -40
- package/dist/index3.mjs +191 -442
- package/dist/index30.mjs +43 -0
- package/dist/index31.mjs +10 -0
- package/dist/index4.mjs +3 -165
- package/dist/index5.mjs +3 -65
- package/dist/index6.mjs +27 -3
- package/dist/index7.mjs +10 -3
- package/dist/index8.mjs +3 -3
- package/dist/index9.mjs +131 -3
- package/dist/types/IndexProvider.d.ts +12 -7
- package/dist/types/StorageAdapter.d.ts +20 -0
- package/dist/utils/objectId.d.ts +8 -0
- package/dist/utils/queryId.d.ts +9 -0
- package/package.json +1 -1
- package/dist/AutoFetchCollection.d.ts +0 -60
- package/dist/Collection/createIndex.d.ts +0 -15
- package/dist/ReplicatedCollection.d.ts +0 -60
- package/dist/createMemoryAdapter.d.ts +0 -7
- package/dist/persistence/combinePersistenceAdapters.d.ts +0 -32
- package/dist/persistence/createPersistenceAdapter.d.ts +0 -9
- package/dist/types/MemoryAdapter.d.ts +0 -15
- package/dist/types/PersistenceAdapter.d.ts +0 -20
package/dist/index3.mjs
CHANGED
|
@@ -1,37 +1,10 @@
|
|
|
1
|
-
import EventEmitter from "./
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import EventEmitter from "./index9.mjs";
|
|
2
|
+
import createSignal from "./index18.mjs";
|
|
3
|
+
import randomId from "./index8.mjs";
|
|
4
|
+
import DefaultDataAdapter from "./index12.mjs";
|
|
5
|
+
import modify from "./index7.mjs";
|
|
6
6
|
import deepClone from "./index19.mjs";
|
|
7
|
-
import serializeValue from "./index20.mjs";
|
|
8
|
-
import createSignal from "./index21.mjs";
|
|
9
7
|
import Cursor from "./index2.mjs";
|
|
10
|
-
import getIndexInfo from "./index22.mjs";
|
|
11
|
-
import { createExternalIndex } from "./index14.mjs";
|
|
12
|
-
import { default as default2 } from "./index14.mjs";
|
|
13
|
-
function hasPendingUpdates(pendingUpdates) {
|
|
14
|
-
return pendingUpdates.added.length > 0 || pendingUpdates.modified.length > 0 || pendingUpdates.removed.length > 0;
|
|
15
|
-
}
|
|
16
|
-
function applyUpdates(currentItems, { added, modified, removed }) {
|
|
17
|
-
const items = [...currentItems];
|
|
18
|
-
added.forEach((item) => {
|
|
19
|
-
items.push(item);
|
|
20
|
-
});
|
|
21
|
-
modified.forEach((item) => {
|
|
22
|
-
const index = items.findIndex(({ id }) => id === item.id);
|
|
23
|
-
if (index === -1)
|
|
24
|
-
return;
|
|
25
|
-
items[index] = item;
|
|
26
|
-
});
|
|
27
|
-
removed.forEach((item) => {
|
|
28
|
-
const index = items.findIndex(({ id }) => id === item.id);
|
|
29
|
-
if (index === -1)
|
|
30
|
-
return;
|
|
31
|
-
items.splice(index, 1);
|
|
32
|
-
});
|
|
33
|
-
return items;
|
|
34
|
-
}
|
|
35
8
|
class Collection extends EventEmitter {
|
|
36
9
|
static collections = [];
|
|
37
10
|
static debugMode = false;
|
|
@@ -67,210 +40,58 @@ class Collection extends EventEmitter {
|
|
|
67
40
|
collection.setFieldTracking(enable);
|
|
68
41
|
});
|
|
69
42
|
};
|
|
70
|
-
/**
|
|
71
|
-
* Executes a batch operation, allowing multiple modifications to the collection
|
|
72
|
-
* while deferring index rebuilding until all operations in the batch are completed.
|
|
73
|
-
* This improves performance by avoiding repetitive index recalculations and
|
|
74
|
-
* provides atomicity for the batch of operations.
|
|
75
|
-
* @param callback - The batch operation to execute.
|
|
76
|
-
*/
|
|
77
43
|
static batch(callback) {
|
|
78
44
|
Collection.batchOperationInProgress = true;
|
|
79
|
-
Collection.collections.reduce((memo, collection) => () =>
|
|
80
|
-
|
|
45
|
+
const execute = () => Collection.collections.reduce((memo, collection) => () => {
|
|
46
|
+
return collection.batch(memo);
|
|
47
|
+
}, callback)();
|
|
48
|
+
const maybePromise = execute();
|
|
49
|
+
const afterBatch = () => {
|
|
50
|
+
Collection.batchOperationInProgress = false;
|
|
51
|
+
};
|
|
52
|
+
if (maybePromise && typeof maybePromise.then === "function") {
|
|
53
|
+
return maybePromise.then(() => afterBatch());
|
|
54
|
+
} else {
|
|
55
|
+
afterBatch();
|
|
56
|
+
}
|
|
81
57
|
}
|
|
82
58
|
name;
|
|
59
|
+
backend;
|
|
83
60
|
options;
|
|
84
|
-
persistenceAdapter = null;
|
|
85
61
|
isPullingSignal;
|
|
86
62
|
isPushingSignal;
|
|
87
|
-
|
|
88
|
-
indicesOutdated = false;
|
|
89
|
-
idIndex = /* @__PURE__ */ new Map();
|
|
63
|
+
readySignal;
|
|
90
64
|
debugMode;
|
|
91
65
|
batchOperationInProgress = false;
|
|
92
66
|
isDisposed = false;
|
|
93
67
|
postBatchCallbacks = /* @__PURE__ */ new Set();
|
|
94
68
|
fieldTracking = false;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Initializes a new instance of the `Collection` class with optional configuration.
|
|
98
|
-
* Sets up memory, persistence, reactivity, and indices as specified in the options.
|
|
99
|
-
* @template T - The type of the items stored in the collection.
|
|
100
|
-
* @template I - The type of the unique identifier for the items.
|
|
101
|
-
* @template U - The transformed item type after applying transformations (default is T).
|
|
102
|
-
* @param options - Optional configuration for the collection.
|
|
103
|
-
* @param options.name - An optional name for the collection.
|
|
104
|
-
* @param options.memory - The in-memory adapter for storing items.
|
|
105
|
-
* @param options.reactivity - The reactivity adapter for observing changes in the collection.
|
|
106
|
-
* @param options.transform - A transformation function to apply to items when retrieving them.
|
|
107
|
-
* @param options.persistence - The persistence adapter for saving and loading items.
|
|
108
|
-
* @param options.indices - An array of index providers for optimized querying.
|
|
109
|
-
* @param options.enableDebugMode - A boolean to enable or disable debug mode.
|
|
110
|
-
* @param options.fieldTracking - A boolean to enable or disable field tracking by default.
|
|
111
|
-
*/
|
|
112
|
-
constructor(options) {
|
|
69
|
+
constructor(nameOrOptions, maybeDataAdapter, maybeOptions) {
|
|
113
70
|
super();
|
|
71
|
+
const name = typeof nameOrOptions === "string" ? nameOrOptions : nameOrOptions?.name || `${this.constructor.name}-${randomId()}`;
|
|
72
|
+
const options = typeof nameOrOptions === "string" ? maybeOptions || {} : nameOrOptions || {};
|
|
73
|
+
const persistence = options.persistence;
|
|
74
|
+
const dataAdapter = maybeDataAdapter || new DefaultDataAdapter({
|
|
75
|
+
...persistence ? { storage: () => persistence } : {}
|
|
76
|
+
});
|
|
114
77
|
Collection.collections.push(this);
|
|
115
|
-
this.name =
|
|
116
|
-
this.options = {
|
|
117
|
-
memory: [],
|
|
118
|
-
...options
|
|
119
|
-
};
|
|
78
|
+
this.name = name;
|
|
79
|
+
this.options = { ...options };
|
|
120
80
|
this.fieldTracking = this.options.fieldTracking ?? Collection.fieldTracking;
|
|
121
81
|
this.debugMode = this.options.enableDebugMode ?? Collection.debugMode;
|
|
122
|
-
this.
|
|
123
|
-
createExternalIndex("id", this.idIndex),
|
|
124
|
-
...this.options.indices || []
|
|
125
|
-
];
|
|
126
|
-
this.rebuildIndices();
|
|
127
|
-
this.isPullingSignal = createSignal(this.options.reactivity, !!options?.persistence);
|
|
82
|
+
this.isPullingSignal = createSignal(this.options.reactivity, false);
|
|
128
83
|
this.isPushingSignal = createSignal(this.options.reactivity, false);
|
|
129
|
-
this.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
this.on("persistence.pushStarted", () => {
|
|
136
|
-
this.isPushingSignal.set(true);
|
|
137
|
-
});
|
|
138
|
-
this.on("persistence.pushCompleted", () => {
|
|
139
|
-
this.isPushingSignal.set(false);
|
|
140
|
-
});
|
|
141
|
-
this.persistenceAdapter = this.options.persistence ?? null;
|
|
142
|
-
if (this.persistenceAdapter) {
|
|
143
|
-
let ongoingSaves = 0;
|
|
144
|
-
let isInitialized = false;
|
|
145
|
-
const pendingUpdates = { added: [], modified: [], removed: [] };
|
|
146
|
-
const loadPersistentData = async (data) => {
|
|
147
|
-
if (!this.persistenceAdapter)
|
|
148
|
-
throw new Error("Persistence adapter not found");
|
|
149
|
-
this.emit("persistence.pullStarted");
|
|
150
|
-
const { items, changes } = data ?? await this.persistenceAdapter.load();
|
|
151
|
-
if (items) {
|
|
152
|
-
if (ongoingSaves > 0)
|
|
153
|
-
return;
|
|
154
|
-
this.memory().splice(0, this.memoryArray().length, ...items);
|
|
155
|
-
this.idIndex.clear();
|
|
156
|
-
this.memory().map((item, index) => {
|
|
157
|
-
this.idIndex.set(serializeValue(item.id), /* @__PURE__ */ new Set([index]));
|
|
158
|
-
});
|
|
159
|
-
} else if (changes) {
|
|
160
|
-
changes.added.forEach((item) => {
|
|
161
|
-
const index = this.memory().findIndex((document) => document.id === item.id);
|
|
162
|
-
if (index !== -1) {
|
|
163
|
-
this.memory().splice(index, 1, item);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
this.memory().push(item);
|
|
167
|
-
const itemIndex = this.memory().findIndex((document) => document === item);
|
|
168
|
-
this.idIndex.set(serializeValue(item.id), /* @__PURE__ */ new Set([itemIndex]));
|
|
169
|
-
});
|
|
170
|
-
changes.modified.forEach((item) => {
|
|
171
|
-
const index = this.memory().findIndex((document) => document.id === item.id);
|
|
172
|
-
if (index === -1)
|
|
173
|
-
throw new Error("Cannot resolve index for item");
|
|
174
|
-
this.memory().splice(index, 1, item);
|
|
175
|
-
});
|
|
176
|
-
changes.removed.forEach((item) => {
|
|
177
|
-
const index = this.memory().findIndex((document) => document.id === item.id);
|
|
178
|
-
if (index === -1)
|
|
179
|
-
throw new Error("Cannot resolve index for item");
|
|
180
|
-
this.memory().splice(index, 1);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
this.rebuildIndices();
|
|
184
|
-
this.emit("persistence.received");
|
|
185
|
-
setTimeout(() => this.emit("persistence.pullCompleted"), 0);
|
|
186
|
-
};
|
|
187
|
-
const saveQueue = {
|
|
188
|
-
added: [],
|
|
189
|
-
modified: [],
|
|
190
|
-
removed: []
|
|
191
|
-
};
|
|
192
|
-
let isFlushing = false;
|
|
193
|
-
const flushQueue = () => {
|
|
194
|
-
if (!this.persistenceAdapter)
|
|
195
|
-
throw new Error("Persistence adapter not found");
|
|
196
|
-
if (ongoingSaves <= 0)
|
|
197
|
-
this.emit("persistence.pushStarted");
|
|
198
|
-
if (isFlushing)
|
|
199
|
-
return;
|
|
200
|
-
if (!hasPendingUpdates(saveQueue))
|
|
201
|
-
return;
|
|
202
|
-
isFlushing = true;
|
|
203
|
-
ongoingSaves += 1;
|
|
204
|
-
const currentItems = this.memoryArray();
|
|
205
|
-
const changes = { ...saveQueue };
|
|
206
|
-
saveQueue.added = [];
|
|
207
|
-
saveQueue.modified = [];
|
|
208
|
-
saveQueue.removed = [];
|
|
209
|
-
this.persistenceAdapter.save(currentItems, changes).then(() => {
|
|
210
|
-
this.emit("persistence.transmitted");
|
|
211
|
-
}).catch((error) => {
|
|
212
|
-
this.emit("persistence.error", error instanceof Error ? error : new Error(error));
|
|
213
|
-
}).finally(() => {
|
|
214
|
-
ongoingSaves -= 1;
|
|
215
|
-
isFlushing = false;
|
|
216
|
-
flushQueue();
|
|
217
|
-
if (ongoingSaves <= 0)
|
|
218
|
-
this.emit("persistence.pushCompleted");
|
|
219
|
-
});
|
|
220
|
-
};
|
|
221
|
-
this.on("added", (item) => {
|
|
222
|
-
if (!isInitialized) {
|
|
223
|
-
pendingUpdates.added.push(item);
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
saveQueue.added.push(item);
|
|
227
|
-
flushQueue();
|
|
228
|
-
});
|
|
229
|
-
this.on("changed", (item) => {
|
|
230
|
-
if (!isInitialized) {
|
|
231
|
-
pendingUpdates.modified.push(item);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
saveQueue.modified.push(item);
|
|
235
|
-
flushQueue();
|
|
236
|
-
});
|
|
237
|
-
this.on("removed", (item) => {
|
|
238
|
-
if (!isInitialized) {
|
|
239
|
-
pendingUpdates.removed.push(item);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
saveQueue.removed.push(item);
|
|
243
|
-
flushQueue();
|
|
244
|
-
});
|
|
245
|
-
this.persistenceAdapter.register((data) => loadPersistentData(data)).then(async () => {
|
|
246
|
-
if (!this.persistenceAdapter)
|
|
247
|
-
throw new Error("Persistence adapter not found");
|
|
248
|
-
let currentItems = this.memoryArray();
|
|
249
|
-
await loadPersistentData();
|
|
250
|
-
while (hasPendingUpdates(pendingUpdates)) {
|
|
251
|
-
const added = pendingUpdates.added.splice(0);
|
|
252
|
-
const modified = pendingUpdates.modified.splice(0);
|
|
253
|
-
const removed = pendingUpdates.removed.splice(0);
|
|
254
|
-
currentItems = applyUpdates(this.memoryArray(), { added, modified, removed });
|
|
255
|
-
await this.persistenceAdapter.save(currentItems, { added, modified, removed }).then(() => {
|
|
256
|
-
this.emit("persistence.transmitted");
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
await loadPersistentData();
|
|
260
|
-
isInitialized = true;
|
|
261
|
-
setTimeout(() => this.emit("persistence.init"), 0);
|
|
262
|
-
}).catch((error) => {
|
|
263
|
-
this.emit("persistence.error", error instanceof Error ? error : new Error(error));
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
this.persistenceReadyPromise = new Promise((resolve, reject) => {
|
|
267
|
-
if (!this.persistenceAdapter)
|
|
268
|
-
return resolve();
|
|
269
|
-
this.once("persistence.init", resolve);
|
|
270
|
-
this.once("persistence.error", reject);
|
|
84
|
+
this.readySignal = createSignal(this.options.reactivity, false);
|
|
85
|
+
this.backend = dataAdapter.createCollectionBackend(this, this.options.indices ?? []);
|
|
86
|
+
void this.backend.isReady().then(() => {
|
|
87
|
+
this.readySignal.set(true);
|
|
88
|
+
}).catch(() => {
|
|
271
89
|
});
|
|
272
90
|
Collection.onCreationCallbacks.forEach((callback) => callback(this));
|
|
273
91
|
}
|
|
92
|
+
isBatchOperationInProgress() {
|
|
93
|
+
return Collection.batchOperationInProgress || this.batchOperationInProgress;
|
|
94
|
+
}
|
|
274
95
|
/**
|
|
275
96
|
* Checks whether the collection is currently performing a pull operation
|
|
276
97
|
* ⚡️ this function is reactive!
|
|
@@ -335,17 +156,28 @@ class Collection extends EventEmitter {
|
|
|
335
156
|
*
|
|
336
157
|
* collection.insert({ name: 'Item 1' })
|
|
337
158
|
*/
|
|
338
|
-
async
|
|
339
|
-
return this.
|
|
159
|
+
async ready() {
|
|
160
|
+
return this.backend.isReady();
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Checks if the collection is ready.
|
|
164
|
+
* ⚡️ this function is reactive!
|
|
165
|
+
* @returns A boolean indicating whether the collection is ready.
|
|
166
|
+
*/
|
|
167
|
+
isReady() {
|
|
168
|
+
return this.readySignal.get() ?? false;
|
|
340
169
|
}
|
|
341
170
|
profile(fn, measureFunction) {
|
|
342
171
|
if (!this.debugMode)
|
|
343
172
|
return fn();
|
|
344
173
|
const startTime = performance.now();
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
174
|
+
const handleProfileEnd = (result) => {
|
|
175
|
+
const endTime = performance.now();
|
|
176
|
+
measureFunction(endTime - startTime);
|
|
177
|
+
return result;
|
|
178
|
+
};
|
|
179
|
+
const maybePromise = fn();
|
|
180
|
+
return maybePromise instanceof Promise ? maybePromise.then(handleProfileEnd) : handleProfileEnd(maybePromise);
|
|
349
181
|
}
|
|
350
182
|
executeInDebugMode(fn) {
|
|
351
183
|
if (!this.debugMode)
|
|
@@ -353,114 +185,58 @@ class Collection extends EventEmitter {
|
|
|
353
185
|
const callstack = new Error().stack || "";
|
|
354
186
|
fn(callstack);
|
|
355
187
|
}
|
|
356
|
-
rebuildIndices() {
|
|
357
|
-
this.indicesOutdated = true;
|
|
358
|
-
if (this.batchOperationInProgress)
|
|
359
|
-
return;
|
|
360
|
-
this.rebuildAllIndices();
|
|
361
|
-
}
|
|
362
|
-
rebuildAllIndices() {
|
|
363
|
-
this.idIndex.clear();
|
|
364
|
-
this.memory().map((item, index) => {
|
|
365
|
-
this.idIndex.set(serializeValue(item.id), /* @__PURE__ */ new Set([index]));
|
|
366
|
-
});
|
|
367
|
-
this.indexProviders.forEach((index) => index.rebuild(this.memoryArray()));
|
|
368
|
-
this.indicesOutdated = false;
|
|
369
|
-
}
|
|
370
|
-
getIndexInfo(selector) {
|
|
371
|
-
if (selector != null && Object.keys(selector).length === 1 && "id" in selector && typeof selector.id !== "object") {
|
|
372
|
-
return {
|
|
373
|
-
matched: true,
|
|
374
|
-
positions: [...this.idIndex.get(serializeValue(selector.id)) || []],
|
|
375
|
-
optimizedSelector: {}
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
if (selector == null) {
|
|
379
|
-
return {
|
|
380
|
-
matched: false,
|
|
381
|
-
positions: [],
|
|
382
|
-
optimizedSelector: {}
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
if (this.indicesOutdated) {
|
|
386
|
-
return {
|
|
387
|
-
matched: false,
|
|
388
|
-
positions: [],
|
|
389
|
-
optimizedSelector: selector
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
return getIndexInfo(this.indexProviders, selector);
|
|
393
|
-
}
|
|
394
|
-
getItemAndIndex(selector) {
|
|
395
|
-
const memory = this.memoryArray();
|
|
396
|
-
const indexInfo = this.getIndexInfo(selector);
|
|
397
|
-
const items = indexInfo.matched ? indexInfo.positions.map((index2) => memory[index2]) : memory;
|
|
398
|
-
const item = items.find((document) => match(document, selector));
|
|
399
|
-
const foundInIndex = indexInfo.matched && indexInfo.positions.find((itemIndex) => memory[itemIndex] === item);
|
|
400
|
-
const index = foundInIndex || memory.findIndex((document) => document === item);
|
|
401
|
-
if (item == null)
|
|
402
|
-
return { item: null, index: -1 };
|
|
403
|
-
if (index === -1)
|
|
404
|
-
throw new Error("Cannot resolve index for item");
|
|
405
|
-
return { item, index };
|
|
406
|
-
}
|
|
407
|
-
deleteFromIdIndex(id, index) {
|
|
408
|
-
this.idIndex.delete(serializeValue(id));
|
|
409
|
-
if (!this.batchOperationInProgress)
|
|
410
|
-
return;
|
|
411
|
-
this.idIndex.forEach(([currenIndex], key) => {
|
|
412
|
-
if (currenIndex > index) {
|
|
413
|
-
this.idIndex.set(key, /* @__PURE__ */ new Set([currenIndex - 1]));
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
memory() {
|
|
418
|
-
return this.options.memory;
|
|
419
|
-
}
|
|
420
|
-
memoryArray() {
|
|
421
|
-
return this.memory().map((item) => item);
|
|
422
|
-
}
|
|
423
188
|
transform(item) {
|
|
424
189
|
if (!this.options.transform)
|
|
425
190
|
return item;
|
|
426
191
|
return this.options.transform(item);
|
|
427
192
|
}
|
|
428
|
-
|
|
193
|
+
getItem(selector, options) {
|
|
194
|
+
const itemsOrPromise = this.getItems(selector, { ...options, limit: 1 });
|
|
195
|
+
if (itemsOrPromise instanceof Promise) {
|
|
196
|
+
return itemsOrPromise.then((items) => {
|
|
197
|
+
return items[0] || void 0;
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
return itemsOrPromise[0];
|
|
201
|
+
}
|
|
202
|
+
getItems(selector, options) {
|
|
203
|
+
this.emit("getItems", selector);
|
|
429
204
|
return this.profile(() => {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return items;
|
|
449
|
-
return items.filter(matchItems);
|
|
205
|
+
if (!options?.async)
|
|
206
|
+
return this.backend.getQueryResult(selector, options);
|
|
207
|
+
return new Promise((resolve, reject) => {
|
|
208
|
+
this.isPullingSignal.set(true);
|
|
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(() => {
|
|
220
|
+
this.isPullingSignal.set(false);
|
|
221
|
+
this.backend.unregisterQuery(selector, options);
|
|
222
|
+
});
|
|
450
223
|
}, (measuredTime) => this.executeInDebugMode((callstack) => this.emit("_debug.getItems", callstack, selector, measuredTime)));
|
|
451
224
|
}
|
|
225
|
+
async withPushState(asyncFunction) {
|
|
226
|
+
this.isPushingSignal.set(true);
|
|
227
|
+
try {
|
|
228
|
+
return await asyncFunction();
|
|
229
|
+
} finally {
|
|
230
|
+
this.isPushingSignal.set(false);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
452
233
|
/**
|
|
453
234
|
* Disposes the collection, unregisters persistence adapters, clears memory, and
|
|
454
235
|
* cleans up all resources used by the collection.
|
|
455
236
|
* @returns A promise that resolves when the collection is disposed.
|
|
456
237
|
*/
|
|
457
238
|
async dispose() {
|
|
458
|
-
|
|
459
|
-
await this.persistenceAdapter.unregister();
|
|
460
|
-
this.persistenceAdapter = null;
|
|
461
|
-
this.memory().map(() => this.memory().pop());
|
|
462
|
-
this.idIndex.clear();
|
|
463
|
-
this.indexProviders = [];
|
|
239
|
+
await this.backend.dispose();
|
|
464
240
|
this.isDisposed = true;
|
|
465
241
|
this.removeAllListeners();
|
|
466
242
|
Collection.collections = Collection.collections.filter((collection) => collection !== this);
|
|
@@ -474,12 +250,12 @@ class Collection extends EventEmitter {
|
|
|
474
250
|
* @param [options] - Options for the find operation, such as limit and sort.
|
|
475
251
|
* @returns A cursor to fetch and observe the matching items.
|
|
476
252
|
*/
|
|
477
|
-
find(selector, options) {
|
|
253
|
+
find(selector = {}, options) {
|
|
478
254
|
if (this.isDisposed)
|
|
479
255
|
throw new Error("Collection is disposed");
|
|
480
256
|
if (selector !== void 0 && (!selector || typeof selector !== "object"))
|
|
481
257
|
throw new Error("Invalid selector");
|
|
482
|
-
const cursor = new Cursor(() => this.getItems(selector), {
|
|
258
|
+
const cursor = new Cursor((() => this.getItems(selector, options || {})), {
|
|
483
259
|
reactive: this.options.reactivity,
|
|
484
260
|
fieldTracking: this.fieldTracking,
|
|
485
261
|
...options,
|
|
@@ -492,16 +268,16 @@ class Collection extends EventEmitter {
|
|
|
492
268
|
}
|
|
493
269
|
requery();
|
|
494
270
|
};
|
|
495
|
-
this.
|
|
496
|
-
this.
|
|
497
|
-
|
|
498
|
-
|
|
271
|
+
this.backend.registerQuery(selector, options);
|
|
272
|
+
const queryStateChangeCleanup = this.backend.onQueryStateChange(selector, options, (state) => {
|
|
273
|
+
if (state !== "complete")
|
|
274
|
+
return;
|
|
275
|
+
handleRequery();
|
|
276
|
+
});
|
|
499
277
|
this.emit("observer.created", selector, options);
|
|
500
278
|
return () => {
|
|
501
|
-
this.
|
|
502
|
-
|
|
503
|
-
this.removeListener("changed", handleRequery);
|
|
504
|
-
this.removeListener("removed", handleRequery);
|
|
279
|
+
this.backend.unregisterQuery(selector, options);
|
|
280
|
+
queryStateChangeCleanup();
|
|
505
281
|
this.emit("observer.disposed", selector, options);
|
|
506
282
|
};
|
|
507
283
|
}
|
|
@@ -514,6 +290,7 @@ class Collection extends EventEmitter {
|
|
|
514
290
|
* Finds a single item in the collection based on a selector and optional options.
|
|
515
291
|
* ⚡️ this function is reactive!
|
|
516
292
|
* Returns the found item or undefined if no item matches.
|
|
293
|
+
* @template Async - Whether to perform the operation asynchronously.
|
|
517
294
|
* @template O - The options type for the find operation.
|
|
518
295
|
* @param selector - The criteria to select the item.
|
|
519
296
|
* @param [options] - Options for the find operation, such as projection.
|
|
@@ -526,23 +303,39 @@ class Collection extends EventEmitter {
|
|
|
526
303
|
limit: 1,
|
|
527
304
|
...options
|
|
528
305
|
});
|
|
529
|
-
const
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
306
|
+
const handleItems = (items) => {
|
|
307
|
+
const returnValue = items[0] || void 0;
|
|
308
|
+
this.emit("findOne", selector, options, returnValue);
|
|
309
|
+
this.executeInDebugMode((callstack) => this.emit("_debug.findOne", callstack, selector, options, returnValue));
|
|
310
|
+
return returnValue;
|
|
311
|
+
};
|
|
312
|
+
const maybePromise = cursor.fetch();
|
|
313
|
+
return maybePromise instanceof Promise ? maybePromise.then(handleItems) : handleItems(maybePromise);
|
|
533
314
|
}
|
|
534
|
-
/**
|
|
535
|
-
* Performs a batch operation, deferring index rebuilds and allowing multiple
|
|
536
|
-
* modifications to be made atomically. Executes any post-batch callbacks afterwards.
|
|
537
|
-
* @param callback - The batch operation to execute.
|
|
538
|
-
*/
|
|
539
315
|
batch(callback) {
|
|
316
|
+
if (this.batchOperationInProgress)
|
|
317
|
+
return callback();
|
|
540
318
|
this.batchOperationInProgress = true;
|
|
541
|
-
callback();
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
319
|
+
const maybePromise = callback();
|
|
320
|
+
const afterBatch = () => {
|
|
321
|
+
this.batchOperationInProgress = false;
|
|
322
|
+
this.postBatchCallbacks.forEach((callback_) => callback_());
|
|
323
|
+
this.postBatchCallbacks.clear();
|
|
324
|
+
};
|
|
325
|
+
if (maybePromise && typeof maybePromise.then === "function") {
|
|
326
|
+
return maybePromise.then(() => afterBatch());
|
|
327
|
+
} else {
|
|
328
|
+
afterBatch();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
onPostBatch(callback) {
|
|
332
|
+
if (this.isDisposed)
|
|
333
|
+
throw new Error("Collection is disposed");
|
|
334
|
+
if (this.batchOperationInProgress) {
|
|
335
|
+
this.postBatchCallbacks.add(callback);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
return callback();
|
|
546
339
|
}
|
|
547
340
|
/**
|
|
548
341
|
* Inserts a single item into the collection. Generates a unique ID if not provided.
|
|
@@ -550,20 +343,18 @@ class Collection extends EventEmitter {
|
|
|
550
343
|
* @returns The ID of the inserted item.
|
|
551
344
|
* @throws {Error} If the collection is disposed or the item has an invalid ID.
|
|
552
345
|
*/
|
|
553
|
-
insert(item) {
|
|
346
|
+
async insert(item) {
|
|
554
347
|
if (this.isDisposed)
|
|
555
348
|
throw new Error("Collection is disposed");
|
|
556
349
|
if (!item)
|
|
557
350
|
throw new Error("Invalid item");
|
|
558
351
|
const primaryKeyGenerator = this.options.primaryKeyGenerator ?? randomId;
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this.
|
|
564
|
-
const
|
|
565
|
-
this.idIndex.set(serializeValue(newItem.id), /* @__PURE__ */ new Set([itemIndex]));
|
|
566
|
-
this.rebuildIndices();
|
|
352
|
+
const itemWithId = {
|
|
353
|
+
id: primaryKeyGenerator(item),
|
|
354
|
+
...item
|
|
355
|
+
};
|
|
356
|
+
this.emit("validate", itemWithId);
|
|
357
|
+
const newItem = await this.withPushState(() => this.backend.insert(itemWithId));
|
|
567
358
|
this.emit("added", newItem);
|
|
568
359
|
this.emit("insert", newItem);
|
|
569
360
|
this.executeInDebugMode((callstack) => this.emit("_debug.insert", callstack, newItem));
|
|
@@ -575,7 +366,7 @@ class Collection extends EventEmitter {
|
|
|
575
366
|
* @returns An array of IDs of the inserted items.
|
|
576
367
|
* @throws {Error} If the collection is disposed or the items are invalid.
|
|
577
368
|
*/
|
|
578
|
-
insertMany(items) {
|
|
369
|
+
async insertMany(items) {
|
|
579
370
|
if (this.isDisposed)
|
|
580
371
|
throw new Error("Collection is disposed");
|
|
581
372
|
if (!items)
|
|
@@ -584,10 +375,10 @@ class Collection extends EventEmitter {
|
|
|
584
375
|
return [];
|
|
585
376
|
}
|
|
586
377
|
const ids = [];
|
|
587
|
-
this.batch(() => {
|
|
588
|
-
items.
|
|
589
|
-
ids.push(this.insert(item));
|
|
590
|
-
});
|
|
378
|
+
await this.batch(async () => {
|
|
379
|
+
await Promise.all(items.map(async (item) => {
|
|
380
|
+
ids.push(await this.insert(item));
|
|
381
|
+
}));
|
|
591
382
|
});
|
|
592
383
|
return ids;
|
|
593
384
|
}
|
|
@@ -600,7 +391,7 @@ class Collection extends EventEmitter {
|
|
|
600
391
|
* @returns The number of items updated (0 or 1).
|
|
601
392
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
602
393
|
*/
|
|
603
|
-
updateOne(selector, modifier, options) {
|
|
394
|
+
async updateOne(selector, modifier, options) {
|
|
604
395
|
if (this.isDisposed)
|
|
605
396
|
throw new Error("Collection is disposed");
|
|
606
397
|
if (!selector)
|
|
@@ -608,7 +399,7 @@ class Collection extends EventEmitter {
|
|
|
608
399
|
if (!modifier)
|
|
609
400
|
throw new Error("Invalid modifier");
|
|
610
401
|
const { $setOnInsert, ...restModifier } = modifier;
|
|
611
|
-
const
|
|
402
|
+
const item = await this.getItem(selector, { async: true });
|
|
612
403
|
if (item == null) {
|
|
613
404
|
if (options?.upsert) {
|
|
614
405
|
const newItem = modify({}, {
|
|
@@ -618,26 +409,18 @@ class Collection extends EventEmitter {
|
|
|
618
409
|
...restModifier.$set
|
|
619
410
|
}
|
|
620
411
|
});
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
}
|
|
624
|
-
this.insert(newItem);
|
|
625
|
-
}
|
|
626
|
-
} else {
|
|
627
|
-
const modifiedItem = modify(deepClone(item), restModifier);
|
|
628
|
-
if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
|
|
629
|
-
throw new Error("Item with same id already exists");
|
|
412
|
+
await this.insert(newItem);
|
|
413
|
+
return 1;
|
|
630
414
|
}
|
|
631
|
-
|
|
632
|
-
this.memory().splice(index, 1, modifiedItem);
|
|
633
|
-
this.rebuildIndices();
|
|
634
|
-
this.emit("changed", modifiedItem, restModifier);
|
|
415
|
+
return 0;
|
|
635
416
|
}
|
|
417
|
+
const modifiedItem = modify(deepClone(item), restModifier);
|
|
418
|
+
this.emit("validate", modifiedItem);
|
|
419
|
+
const changes = await this.withPushState(() => this.backend.updateOne(selector, modifier));
|
|
420
|
+
this.emit("changed", modifiedItem, restModifier);
|
|
636
421
|
this.emit("updateOne", selector, modifier);
|
|
637
422
|
this.executeInDebugMode((callstack) => this.emit("_debug.updateOne", callstack, selector, modifier));
|
|
638
|
-
|
|
639
|
-
return 0;
|
|
640
|
-
return 1;
|
|
423
|
+
return changes.length;
|
|
641
424
|
}
|
|
642
425
|
/**
|
|
643
426
|
* Updates multiple items in the collection that match the given selector.
|
|
@@ -648,7 +431,7 @@ class Collection extends EventEmitter {
|
|
|
648
431
|
* @returns The number of items updated.
|
|
649
432
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
650
433
|
*/
|
|
651
|
-
updateMany(selector, modifier, options) {
|
|
434
|
+
async updateMany(selector, modifier, options) {
|
|
652
435
|
if (this.isDisposed)
|
|
653
436
|
throw new Error("Collection is disposed");
|
|
654
437
|
if (!selector)
|
|
@@ -656,44 +439,32 @@ class Collection extends EventEmitter {
|
|
|
656
439
|
if (!modifier)
|
|
657
440
|
throw new Error("Invalid modifier");
|
|
658
441
|
const { $setOnInsert, ...restModifier } = modifier;
|
|
659
|
-
const items = this.getItems(selector);
|
|
660
|
-
if (items.length === 0
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
442
|
+
const items = await this.getItems(selector, { async: true });
|
|
443
|
+
if (items.length === 0) {
|
|
444
|
+
if (options?.upsert) {
|
|
445
|
+
const newItem = modify({}, {
|
|
446
|
+
...restModifier,
|
|
447
|
+
$set: {
|
|
448
|
+
...$setOnInsert,
|
|
449
|
+
...restModifier.$set
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
await this.insert(newItem);
|
|
453
|
+
return 1;
|
|
670
454
|
}
|
|
671
|
-
|
|
455
|
+
return 0;
|
|
672
456
|
}
|
|
673
|
-
|
|
674
|
-
const { index } = this.getItemAndIndex({ id: item.id });
|
|
675
|
-
if (index === -1)
|
|
676
|
-
throw new Error(`Cannot resolve index for item with id '${item.id}'`);
|
|
457
|
+
items.forEach((item) => {
|
|
677
458
|
const modifiedItem = modify(deepClone(item), restModifier);
|
|
678
|
-
if (item.id !== modifiedItem.id && this.getItemAndIndex({ id: modifiedItem.id }).item != null) {
|
|
679
|
-
throw new Error(`Item with same id '${modifiedItem.id}' already exists`);
|
|
680
|
-
}
|
|
681
459
|
this.emit("validate", modifiedItem);
|
|
682
|
-
return {
|
|
683
|
-
item: modifiedItem,
|
|
684
|
-
index
|
|
685
|
-
};
|
|
686
|
-
});
|
|
687
|
-
changes.forEach(({ item, index }) => {
|
|
688
|
-
this.memory().splice(index, 1, item);
|
|
689
460
|
});
|
|
690
|
-
this.
|
|
691
|
-
changes.forEach((
|
|
461
|
+
const changes = await this.withPushState(() => this.backend.updateMany(selector, modifier));
|
|
462
|
+
changes.forEach((item) => {
|
|
692
463
|
this.emit("changed", item, restModifier);
|
|
693
464
|
});
|
|
694
465
|
this.emit("updateMany", selector, modifier);
|
|
695
466
|
this.executeInDebugMode((callstack) => this.emit("_debug.updateMany", callstack, selector, modifier));
|
|
696
|
-
return changes.length
|
|
467
|
+
return changes.length;
|
|
697
468
|
}
|
|
698
469
|
/**
|
|
699
470
|
* Replaces a single item in the collection that matches the given selector.
|
|
@@ -704,34 +475,26 @@ class Collection extends EventEmitter {
|
|
|
704
475
|
* @returns The number of items replaced (0 or 1).
|
|
705
476
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
706
477
|
*/
|
|
707
|
-
replaceOne(selector, replacement, options) {
|
|
478
|
+
async replaceOne(selector, replacement, options) {
|
|
708
479
|
if (this.isDisposed)
|
|
709
480
|
throw new Error("Collection is disposed");
|
|
710
481
|
if (!selector)
|
|
711
482
|
throw new Error("Invalid selector");
|
|
712
|
-
const
|
|
483
|
+
const item = await this.getItem(selector, { async: true });
|
|
713
484
|
if (item == null) {
|
|
714
485
|
if (options?.upsert) {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
}
|
|
718
|
-
this.insert(replacement);
|
|
719
|
-
}
|
|
720
|
-
} else {
|
|
721
|
-
if (item.id !== replacement.id && this.getItemAndIndex({ id: replacement.id }).item != null) {
|
|
722
|
-
throw new Error("Item with same id already exists");
|
|
486
|
+
await this.insert(replacement);
|
|
487
|
+
return 1;
|
|
723
488
|
}
|
|
724
|
-
|
|
725
|
-
this.emit("validate", modifiedItem);
|
|
726
|
-
this.memory().splice(index, 1, modifiedItem);
|
|
727
|
-
this.rebuildIndices();
|
|
728
|
-
this.emit("changed", modifiedItem, replacement);
|
|
489
|
+
return 0;
|
|
729
490
|
}
|
|
491
|
+
const modifiedItem = { id: item.id, ...replacement };
|
|
492
|
+
this.emit("validate", modifiedItem);
|
|
493
|
+
const changes = await this.withPushState(() => this.backend.replaceOne(selector, replacement));
|
|
494
|
+
this.emit("changed", modifiedItem, replacement);
|
|
730
495
|
this.emit("replaceOne", selector, replacement);
|
|
731
496
|
this.executeInDebugMode((callstack) => this.emit("_debug.replaceOne", callstack, selector, replacement));
|
|
732
|
-
|
|
733
|
-
return 0;
|
|
734
|
-
return 1;
|
|
497
|
+
return changes.length;
|
|
735
498
|
}
|
|
736
499
|
/**
|
|
737
500
|
* Removes a single item from the collection that matches the given selector.
|
|
@@ -739,21 +502,16 @@ class Collection extends EventEmitter {
|
|
|
739
502
|
* @returns The number of items removed (0 or 1).
|
|
740
503
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
741
504
|
*/
|
|
742
|
-
removeOne(selector) {
|
|
505
|
+
async removeOne(selector) {
|
|
743
506
|
if (this.isDisposed)
|
|
744
507
|
throw new Error("Collection is disposed");
|
|
745
508
|
if (!selector)
|
|
746
509
|
throw new Error("Invalid selector");
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
this.memory().splice(index, 1);
|
|
750
|
-
this.deleteFromIdIndex(item.id, index);
|
|
751
|
-
this.rebuildIndices();
|
|
752
|
-
this.emit("removed", item);
|
|
753
|
-
}
|
|
510
|
+
const removedItems = await this.withPushState(() => this.backend.removeOne(selector));
|
|
511
|
+
this.emit("removed", removedItems[0]);
|
|
754
512
|
this.emit("removeOne", selector);
|
|
755
513
|
this.executeInDebugMode((callstack) => this.emit("_debug.removeOne", callstack, selector));
|
|
756
|
-
return
|
|
514
|
+
return removedItems.length;
|
|
757
515
|
}
|
|
758
516
|
/**
|
|
759
517
|
* Removes multiple items from the collection that match the given selector.
|
|
@@ -761,29 +519,20 @@ class Collection extends EventEmitter {
|
|
|
761
519
|
* @returns The number of items removed.
|
|
762
520
|
* @throws {Error} If the collection is disposed or invalid arguments are provided.
|
|
763
521
|
*/
|
|
764
|
-
removeMany(selector) {
|
|
522
|
+
async removeMany(selector) {
|
|
765
523
|
if (this.isDisposed)
|
|
766
524
|
throw new Error("Collection is disposed");
|
|
767
525
|
if (!selector)
|
|
768
526
|
throw new Error("Invalid selector");
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
const index = this.memory().findIndex((document) => document === item);
|
|
772
|
-
if (index === -1)
|
|
773
|
-
throw new Error("Cannot resolve index for item");
|
|
774
|
-
this.memory().splice(index, 1);
|
|
775
|
-
this.deleteFromIdIndex(item.id, index);
|
|
776
|
-
this.rebuildIndices();
|
|
777
|
-
});
|
|
778
|
-
items.forEach((item) => {
|
|
527
|
+
const removedItems = await this.withPushState(() => this.backend.removeMany(selector));
|
|
528
|
+
removedItems.forEach((item) => {
|
|
779
529
|
this.emit("removed", item);
|
|
780
530
|
});
|
|
781
531
|
this.emit("removeMany", selector);
|
|
782
532
|
this.executeInDebugMode((callstack) => this.emit("_debug.removeMany", callstack, selector));
|
|
783
|
-
return
|
|
533
|
+
return removedItems.length;
|
|
784
534
|
}
|
|
785
535
|
}
|
|
786
536
|
export {
|
|
787
|
-
default2 as createIndex,
|
|
788
537
|
Collection as default
|
|
789
538
|
};
|