@signaldb/core 2.0.0-beta.0 → 2.0.0-beta.1
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 +25 -12
- package/dist/AutoFetchDataAdapter.d.ts +0 -1
- package/dist/Collection/index.d.ts +2 -0
- package/dist/DataAdapter.d.ts +7 -6
- package/dist/DefaultDataAdapter.d.ts +1 -0
- package/dist/WorkerDataAdapter.d.ts +4 -1
- package/dist/WorkerDataAdapterHost.d.ts +9 -6
- package/dist/index.cjs12.js +32 -21
- package/dist/index.cjs13.js +25 -13
- package/dist/index.cjs14.js +31 -37
- package/dist/index.cjs15.js +120 -75
- package/dist/index.cjs16.js +45 -36
- package/dist/index.cjs17.js +1 -1
- package/dist/index.cjs2.js +5 -2
- package/dist/index.cjs20.js +5 -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.cjs26.js +1 -1
- package/dist/index.cjs27.js +44 -3
- package/dist/index.cjs28.js +6 -5
- package/dist/index.cjs29.js +7 -27
- package/dist/index.cjs3.js +25 -21
- package/dist/index.cjs30.js +3 -40
- package/dist/index.cjs31.js +5 -7
- package/dist/index.cjs32.js +29 -0
- package/dist/index.cjs33.js +42 -0
- package/dist/index.d.ts +1 -0
- package/dist/index12.mjs +32 -21
- package/dist/index13.mjs +25 -13
- package/dist/index14.mjs +31 -37
- package/dist/index15.mjs +120 -75
- package/dist/index16.mjs +45 -36
- package/dist/index17.mjs +1 -1
- package/dist/index2.mjs +5 -2
- package/dist/index20.mjs +5 -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/index26.mjs +1 -1
- package/dist/index27.mjs +44 -3
- package/dist/index28.mjs +6 -5
- package/dist/index29.mjs +7 -27
- package/dist/index3.mjs +25 -21
- package/dist/index30.mjs +3 -40
- package/dist/index31.mjs +5 -7
- package/dist/index32.mjs +30 -0
- package/dist/index33.mjs +43 -0
- package/dist/utils/batchOnNextTick.d.ts +16 -0
- package/package.json +1 -1
package/dist/.vite/manifest.json
CHANGED
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"src/DefaultDataAdapter.ts",
|
|
60
60
|
"src/utils/modify.ts",
|
|
61
61
|
"src/utils/deepClone.ts",
|
|
62
|
+
"src/utils/queryId.ts",
|
|
62
63
|
"src/Collection/Cursor.ts"
|
|
63
64
|
]
|
|
64
65
|
},
|
|
@@ -86,7 +87,8 @@
|
|
|
86
87
|
"src": "src/WorkerDataAdapter.ts",
|
|
87
88
|
"imports": [
|
|
88
89
|
"src/utils/queryId.ts",
|
|
89
|
-
"src/utils/randomId.ts"
|
|
90
|
+
"src/utils/randomId.ts",
|
|
91
|
+
"src/utils/batchOnNextTick.ts"
|
|
90
92
|
]
|
|
91
93
|
},
|
|
92
94
|
"src/WorkerDataAdapterHost.ts": {
|
|
@@ -102,11 +104,12 @@
|
|
|
102
104
|
"src/getIndexInfo.ts",
|
|
103
105
|
"src/utils/getMatchingKeys.ts",
|
|
104
106
|
"src/utils/sortItems.ts",
|
|
105
|
-
"src/utils/project.ts"
|
|
107
|
+
"src/utils/project.ts",
|
|
108
|
+
"src/utils/compact.ts"
|
|
106
109
|
]
|
|
107
110
|
},
|
|
108
111
|
"src/createIndex.ts": {
|
|
109
|
-
"file": "index.
|
|
112
|
+
"file": "index.cjs21.js",
|
|
110
113
|
"name": "createIndex",
|
|
111
114
|
"src": "src/createIndex.ts",
|
|
112
115
|
"imports": [
|
|
@@ -117,7 +120,7 @@
|
|
|
117
120
|
]
|
|
118
121
|
},
|
|
119
122
|
"src/createIndexProvider.ts": {
|
|
120
|
-
"file": "index.
|
|
123
|
+
"file": "index.cjs30.js",
|
|
121
124
|
"name": "createIndexProvider",
|
|
122
125
|
"src": "src/createIndexProvider.ts"
|
|
123
126
|
},
|
|
@@ -132,7 +135,7 @@
|
|
|
132
135
|
"src": "src/createStorageAdapter.ts"
|
|
133
136
|
},
|
|
134
137
|
"src/getIndexInfo.ts": {
|
|
135
|
-
"file": "index.
|
|
138
|
+
"file": "index.cjs22.js",
|
|
136
139
|
"name": "getIndexInfo",
|
|
137
140
|
"src": "src/getIndexInfo.ts",
|
|
138
141
|
"imports": [
|
|
@@ -167,6 +170,16 @@
|
|
|
167
170
|
"name": "utils/EventEmitter",
|
|
168
171
|
"src": "src/utils/EventEmitter.ts"
|
|
169
172
|
},
|
|
173
|
+
"src/utils/batchOnNextTick.ts": {
|
|
174
|
+
"file": "index.cjs27.js",
|
|
175
|
+
"name": "utils/batchOnNextTick",
|
|
176
|
+
"src": "src/utils/batchOnNextTick.ts"
|
|
177
|
+
},
|
|
178
|
+
"src/utils/compact.ts": {
|
|
179
|
+
"file": "index.cjs28.js",
|
|
180
|
+
"name": "utils/compact",
|
|
181
|
+
"src": "src/utils/compact.ts"
|
|
182
|
+
},
|
|
170
183
|
"src/utils/createSignal.ts": {
|
|
171
184
|
"file": "index.cjs18.js",
|
|
172
185
|
"name": "utils/createSignal",
|
|
@@ -192,7 +205,7 @@
|
|
|
192
205
|
]
|
|
193
206
|
},
|
|
194
207
|
"src/utils/intersection.ts": {
|
|
195
|
-
"file": "index.
|
|
208
|
+
"file": "index.cjs31.js",
|
|
196
209
|
"name": "utils/intersection",
|
|
197
210
|
"src": "src/utils/intersection.ts"
|
|
198
211
|
},
|
|
@@ -202,12 +215,12 @@
|
|
|
202
215
|
"src": "src/utils/isEqual.ts"
|
|
203
216
|
},
|
|
204
217
|
"src/utils/isFieldExpression.ts": {
|
|
205
|
-
"file": "index.
|
|
218
|
+
"file": "index.cjs33.js",
|
|
206
219
|
"name": "utils/isFieldExpression",
|
|
207
220
|
"src": "src/utils/isFieldExpression.ts"
|
|
208
221
|
},
|
|
209
222
|
"src/utils/match.ts": {
|
|
210
|
-
"file": "index.
|
|
223
|
+
"file": "index.cjs23.js",
|
|
211
224
|
"name": "utils/match",
|
|
212
225
|
"src": "src/utils/match.ts"
|
|
213
226
|
},
|
|
@@ -220,7 +233,7 @@
|
|
|
220
233
|
]
|
|
221
234
|
},
|
|
222
235
|
"src/utils/project.ts": {
|
|
223
|
-
"file": "index.
|
|
236
|
+
"file": "index.cjs24.js",
|
|
224
237
|
"name": "utils/project",
|
|
225
238
|
"src": "src/utils/project.ts",
|
|
226
239
|
"imports": [
|
|
@@ -229,7 +242,7 @@
|
|
|
229
242
|
]
|
|
230
243
|
},
|
|
231
244
|
"src/utils/queryId.ts": {
|
|
232
|
-
"file": "index.
|
|
245
|
+
"file": "index.cjs20.js",
|
|
233
246
|
"name": "utils/queryId",
|
|
234
247
|
"src": "src/utils/queryId.ts"
|
|
235
248
|
},
|
|
@@ -244,7 +257,7 @@
|
|
|
244
257
|
"src": "src/utils/serializeValue.ts"
|
|
245
258
|
},
|
|
246
259
|
"src/utils/set.ts": {
|
|
247
|
-
"file": "index.
|
|
260
|
+
"file": "index.cjs32.js",
|
|
248
261
|
"name": "utils/set",
|
|
249
262
|
"src": "src/utils/set.ts"
|
|
250
263
|
},
|
|
@@ -257,7 +270,7 @@
|
|
|
257
270
|
]
|
|
258
271
|
},
|
|
259
272
|
"src/utils/uniqueBy.ts": {
|
|
260
|
-
"file": "index.
|
|
273
|
+
"file": "index.cjs29.js",
|
|
261
274
|
"name": "utils/uniqueBy",
|
|
262
275
|
"src": "src/utils/uniqueBy.ts"
|
|
263
276
|
}
|
|
@@ -72,7 +72,6 @@ export default class AutoFetchDataAdapter implements DataAdapter {
|
|
|
72
72
|
private autoloadIds;
|
|
73
73
|
constructor(options: AutoFetchDataAdapterOptions);
|
|
74
74
|
createCollectionBackend<T extends BaseItem<I>, I = any, U = T>(collection: Collection<T, I, U>, indices: string[]): CollectionBackend<T, I>;
|
|
75
|
-
private selectorKey;
|
|
76
75
|
private forceRefetchAll;
|
|
77
76
|
private fetchAndIngest;
|
|
78
77
|
private purgeSelector;
|
|
@@ -102,6 +102,7 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, U = T
|
|
|
102
102
|
private isDisposed;
|
|
103
103
|
private postBatchCallbacks;
|
|
104
104
|
private fieldTracking;
|
|
105
|
+
private queryListenersMap;
|
|
105
106
|
/**
|
|
106
107
|
* Initializes a new instance of the `Collection` class with optional configuration.
|
|
107
108
|
* Sets up memory, persistence, reactivity, and indices as specified in the options.
|
|
@@ -186,6 +187,7 @@ export default class Collection<T extends BaseItem<I> = BaseItem, I = any, U = T
|
|
|
186
187
|
private getItem;
|
|
187
188
|
private getItems;
|
|
188
189
|
private withPushState;
|
|
190
|
+
private queryListeners;
|
|
189
191
|
/**
|
|
190
192
|
* Disposes the collection, unregisters persistence adapters, clears memory, and
|
|
191
193
|
* cleans up all resources used by the collection.
|
package/dist/DataAdapter.d.ts
CHANGED
|
@@ -19,12 +19,13 @@ export interface CollectionBackend<T extends BaseItem<I>, I> {
|
|
|
19
19
|
replaceOne(selector: Selector<T>, replacement: Omit<T, 'id'> & Partial<Pick<T, 'id'>>): Promise<T[]>;
|
|
20
20
|
removeOne(selector: Selector<T>): Promise<T[]>;
|
|
21
21
|
removeMany(selector: Selector<T>): Promise<T[]>;
|
|
22
|
-
registerQuery<O extends QueryOptions<T>>(selector: Selector<T>, options
|
|
23
|
-
unregisterQuery<O extends QueryOptions<T>>(selector: Selector<T>, options
|
|
24
|
-
getQueryState<O extends QueryOptions<T>>(selector: Selector<T>, options
|
|
25
|
-
getQueryError<O extends QueryOptions<T>>(selector: Selector<T>, options
|
|
26
|
-
getQueryResult<O extends QueryOptions<T>>(selector: Selector<T>, options
|
|
27
|
-
|
|
22
|
+
registerQuery<O extends QueryOptions<T>>(selector: Selector<T>, options: O): void;
|
|
23
|
+
unregisterQuery<O extends QueryOptions<T>>(selector: Selector<T>, options: O): void;
|
|
24
|
+
getQueryState<O extends QueryOptions<T>>(selector: Selector<T>, options: O): 'active' | 'complete' | 'error';
|
|
25
|
+
getQueryError<O extends QueryOptions<T>>(selector: Selector<T>, options: O): Error | null;
|
|
26
|
+
getQueryResult<O extends QueryOptions<T>>(selector: Selector<T>, options: O): T[];
|
|
27
|
+
executeQuery<O extends QueryOptions<T>>(selector: Selector<T>, options: O): Promise<T[]>;
|
|
28
|
+
onQueryStateChange<O extends QueryOptions<T>>(selector: Selector<T>, options: O, callback: (state: 'active' | 'complete' | 'error') => void): () => void;
|
|
28
29
|
dispose(): Promise<void>;
|
|
29
30
|
isReady(): Promise<void>;
|
|
30
31
|
}
|
|
@@ -26,6 +26,7 @@ export default class DefaultDataAdapter implements DataAdapter {
|
|
|
26
26
|
private queryItems;
|
|
27
27
|
private executeQuery;
|
|
28
28
|
private flushQueuedQueryUpdates;
|
|
29
|
+
private executeAndCacheQuery;
|
|
29
30
|
private updateQueries;
|
|
30
31
|
createCollectionBackend<T extends BaseItem<I>, I = any, U = T>(collection: Collection<T, I, U>, indices: string[]): CollectionBackend<T, I>;
|
|
31
32
|
}
|
|
@@ -4,6 +4,7 @@ import type DataAdapter from './DataAdapter';
|
|
|
4
4
|
import type { CollectionBackend } from './DataAdapter';
|
|
5
5
|
interface WorkerDataAdapterOptions {
|
|
6
6
|
id?: string;
|
|
7
|
+
log?: (message: string, ...args: any[]) => void;
|
|
7
8
|
}
|
|
8
9
|
export default class WorkerDataAdapter implements DataAdapter {
|
|
9
10
|
private worker;
|
|
@@ -11,11 +12,13 @@ export default class WorkerDataAdapter implements DataAdapter {
|
|
|
11
12
|
private id;
|
|
12
13
|
private isDisposed;
|
|
13
14
|
private workerReady;
|
|
15
|
+
private log;
|
|
14
16
|
private collectionReady;
|
|
17
|
+
private batchExecutionHelpers;
|
|
15
18
|
private queries;
|
|
16
19
|
constructor(worker: Worker, options: WorkerDataAdapterOptions);
|
|
17
20
|
private exec;
|
|
18
|
-
private
|
|
21
|
+
private enqueueBatched;
|
|
19
22
|
private updateQuery;
|
|
20
23
|
createCollectionBackend<T extends BaseItem<I>, I = any, U = T>(collection: Collection<T, I, U>, indices?: string[]): CollectionBackend<T, I>;
|
|
21
24
|
}
|
|
@@ -11,24 +11,27 @@ interface WorkerDataAdapterHostOptions {
|
|
|
11
11
|
id?: string;
|
|
12
12
|
storage: (name: string) => StorageAdapter<any, any>;
|
|
13
13
|
onError?: (error: Error) => void;
|
|
14
|
+
log?: (message: string, ...args: any[]) => void;
|
|
14
15
|
}
|
|
15
16
|
type CollectionMethods<T extends BaseItem<I>, I = any> = {
|
|
16
17
|
registerCollection: (collectionName: string, indices: string[]) => Promise<void>;
|
|
17
18
|
unregisterCollection: (collectionName: string) => Promise<void>;
|
|
18
19
|
registerQuery: <O extends QueryOptions<T>>(collectionName: string, selector: Selector<T>, options?: O) => Promise<void>;
|
|
19
20
|
unregisterQuery: <O extends QueryOptions<T>>(collectionName: string, selector: Selector<T>, options?: O) => Promise<void>;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
executeQuery: <O extends QueryOptions<T>>(collectionName: string, selector: Selector<T>, options?: O) => Promise<T[]>;
|
|
22
|
+
insert: (collectionName: string, items: [T][]) => Promise<(T | Error)[]>;
|
|
23
|
+
updateOne: (collectionName: string, args: [Selector<T>, Modifier<T>][]) => Promise<(T[] | Error)[]>;
|
|
24
|
+
updateMany: (collectionName: string, args: [Selector<T>, Modifier<T>][]) => Promise<(T[] | Error)[]>;
|
|
25
|
+
replaceOne: (collectionName: string, args: [Selector<T>, Omit<T, 'id'> & Partial<Pick<T, 'id'>>][]) => Promise<(T[] | Error)[]>;
|
|
26
|
+
removeOne: (collectionName: string, selectors: [Selector<T>][]) => Promise<(T[] | Error)[]>;
|
|
27
|
+
removeMany: (collectionName: string, selectors: [Selector<T>][]) => Promise<(T[] | Error)[]>;
|
|
26
28
|
isReady: (collectionName: string) => Promise<void>;
|
|
27
29
|
};
|
|
28
30
|
export default class WorkerDataAdapterHost<T extends BaseItem<I>, I = any> {
|
|
29
31
|
private workerContext;
|
|
30
32
|
private options;
|
|
31
33
|
private id;
|
|
34
|
+
private log;
|
|
32
35
|
private storageAdapters;
|
|
33
36
|
private storageAdapterReady;
|
|
34
37
|
private collectionIndices;
|
package/dist/index.cjs12.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const createIndex = require("./index.
|
|
3
|
-
const getIndexInfo = require("./index.
|
|
2
|
+
const createIndex = require("./index.cjs21.js");
|
|
3
|
+
const getIndexInfo = require("./index.cjs22.js");
|
|
4
4
|
const deepClone = require("./index.cjs19.js");
|
|
5
5
|
const EventEmitter = require("./index.cjs9.js");
|
|
6
6
|
const isEqual = require("./index.cjs6.js");
|
|
7
|
-
const match = require("./index.
|
|
7
|
+
const match = require("./index.cjs23.js");
|
|
8
8
|
const modify = require("./index.cjs7.js");
|
|
9
|
-
const project = require("./index.
|
|
10
|
-
const queryId = require("./index.
|
|
9
|
+
const project = require("./index.cjs24.js");
|
|
10
|
+
const queryId = require("./index.cjs20.js");
|
|
11
11
|
const serializeValue = require("./index.cjs11.js");
|
|
12
12
|
const sortItems = require("./index.cjs25.js");
|
|
13
13
|
function hasPendingUpdates(pendingUpdates) {
|
|
@@ -143,14 +143,28 @@ class DefaultDataAdapter {
|
|
|
143
143
|
return;
|
|
144
144
|
this.queuedQueryUpdates.set(collection.name, { added: [], modified: [], removed: [] });
|
|
145
145
|
const flatItems = [...changes.added, ...changes.modified, ...changes.removed];
|
|
146
|
-
const
|
|
146
|
+
const itemIds = new Set(flatItems.map((i) => i.id));
|
|
147
|
+
const queries = [
|
|
148
|
+
...this.activeQueries.get(collection.name)?.values() ?? []
|
|
149
|
+
].filter(({ selector, options }) => {
|
|
150
|
+
const idsInQuery = this.cachedQueryResults.get(collection.name)?.get(queryId(selector, options))?.map((i) => i.id) ?? [];
|
|
151
|
+
if (idsInQuery.some((id) => itemIds.has(id)))
|
|
152
|
+
return true;
|
|
153
|
+
return flatItems.some((item) => match(item, selector));
|
|
154
|
+
});
|
|
147
155
|
queries.forEach(({ selector, options }) => {
|
|
148
|
-
|
|
149
|
-
if (!emitter)
|
|
150
|
-
return;
|
|
151
|
-
emitter.emit("change", selector, options, "complete");
|
|
156
|
+
this.executeAndCacheQuery(collection, selector, options);
|
|
152
157
|
});
|
|
153
158
|
}
|
|
159
|
+
executeAndCacheQuery(collection, selector, options) {
|
|
160
|
+
const result = this.executeQuery(collection, selector, options);
|
|
161
|
+
this.cachedQueryResults.set(collection.name, this.cachedQueryResults.get(collection.name) || /* @__PURE__ */ new Map());
|
|
162
|
+
this.cachedQueryResults.get(collection.name)?.set(queryId(selector, options), result);
|
|
163
|
+
const emitter = this.queryEmitters.get(collection.name);
|
|
164
|
+
if (!emitter)
|
|
165
|
+
return;
|
|
166
|
+
emitter.emit("change", selector, options, "complete");
|
|
167
|
+
}
|
|
154
168
|
updateQueries(collection, changes) {
|
|
155
169
|
this.queuedQueryUpdates.set(collection.name, this.queuedQueryUpdates.get(collection.name) || { added: [], modified: [], removed: [] });
|
|
156
170
|
this.queuedQueryUpdates.get(collection.name)?.added.push(...changes.added);
|
|
@@ -162,6 +176,7 @@ class DefaultDataAdapter {
|
|
|
162
176
|
this.ensureStorageAdapter(collection.name);
|
|
163
177
|
this.items.set(collection.name, this.items.get(collection.name) ?? /* @__PURE__ */ new Map());
|
|
164
178
|
this.queryEmitters.set(collection.name, this.queryEmitters.get(collection.name) ?? new EventEmitter());
|
|
179
|
+
this.queryEmitters.get(collection.name)?.setMaxListeners(Infinity);
|
|
165
180
|
this.activeQueries.set(collection.name, this.activeQueries.get(collection.name) || /* @__PURE__ */ new Map());
|
|
166
181
|
this.indices.set(collection.name, indices.map((field) => createIndex(field)));
|
|
167
182
|
this.rebuildIndices(collection);
|
|
@@ -207,7 +222,7 @@ class DefaultDataAdapter {
|
|
|
207
222
|
},
|
|
208
223
|
updateMany: async (selector, modifier) => {
|
|
209
224
|
const { $setOnInsert, ...restModifier } = modifier;
|
|
210
|
-
const items =
|
|
225
|
+
const items = this.executeQuery(collection, selector, {});
|
|
211
226
|
const changedItems = items.map((item) => {
|
|
212
227
|
const modifiedItem = modify(deepClone.default(item), restModifier);
|
|
213
228
|
const hasItemWithSameId = item.id !== modifiedItem.id && this.getItem(collection, { id: modifiedItem.id }) != null;
|
|
@@ -263,7 +278,7 @@ class DefaultDataAdapter {
|
|
|
263
278
|
return [item];
|
|
264
279
|
},
|
|
265
280
|
removeMany: async (selector) => {
|
|
266
|
-
const items = backend.getQueryResult(selector);
|
|
281
|
+
const items = backend.getQueryResult(selector, {});
|
|
267
282
|
items.forEach((item) => {
|
|
268
283
|
this.items.get(collection.name)?.delete(serializeValue(item.id));
|
|
269
284
|
});
|
|
@@ -283,10 +298,7 @@ class DefaultDataAdapter {
|
|
|
283
298
|
selector,
|
|
284
299
|
options
|
|
285
300
|
});
|
|
286
|
-
|
|
287
|
-
if (!emitter)
|
|
288
|
-
throw new Error(`Query emitter not found for collection ${collection.name}`);
|
|
289
|
-
emitter.emit("change", selector, options, "complete");
|
|
301
|
+
this.executeAndCacheQuery(collection, selector, options);
|
|
290
302
|
},
|
|
291
303
|
unregisterQuery: (selector, options) => {
|
|
292
304
|
if (!this.activeQueries.get(collection.name))
|
|
@@ -299,7 +311,7 @@ class DefaultDataAdapter {
|
|
|
299
311
|
if (!emitter)
|
|
300
312
|
throw new Error(`Query emitter not found for collection ${collection.name}`);
|
|
301
313
|
const handler = (querySelector, queryOptions, state) => {
|
|
302
|
-
if (querySelector !== selector
|
|
314
|
+
if (queryId(querySelector, queryOptions) !== queryId(selector, options))
|
|
303
315
|
return;
|
|
304
316
|
callback(state);
|
|
305
317
|
};
|
|
@@ -310,14 +322,13 @@ class DefaultDataAdapter {
|
|
|
310
322
|
},
|
|
311
323
|
getQueryError: () => null,
|
|
312
324
|
getQueryResult: (selector, options) => {
|
|
313
|
-
const result = this.executeQuery(collection, selector, options);
|
|
314
325
|
const isQueryActive = this.activeQueries.get(collection.name)?.has(queryId(selector, options));
|
|
315
326
|
if (isQueryActive) {
|
|
316
|
-
|
|
317
|
-
this.cachedQueryResults.get(collection.name)?.set(queryId(selector, options), result);
|
|
327
|
+
return this.cachedQueryResults.get(collection.name)?.get(queryId(selector, options)) ?? [];
|
|
318
328
|
}
|
|
319
|
-
return
|
|
329
|
+
return this.executeQuery(collection, selector, options);
|
|
320
330
|
},
|
|
331
|
+
executeQuery: (selector, options) => Promise.resolve(this.executeQuery(collection, selector, options)),
|
|
321
332
|
// lifecycle methods
|
|
322
333
|
dispose: async () => {
|
|
323
334
|
const adapter = this.storageAdapters.get(collection.name);
|
package/dist/index.cjs13.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const deepClone = require("./index.cjs19.js");
|
|
3
|
-
const match = require("./index.
|
|
3
|
+
const match = require("./index.cjs23.js");
|
|
4
4
|
const modify = require("./index.cjs7.js");
|
|
5
|
-
const queryId = require("./index.
|
|
5
|
+
const queryId = require("./index.cjs20.js");
|
|
6
6
|
const isEqual = require("./index.cjs6.js");
|
|
7
|
-
const getIndexInfo = require("./index.
|
|
7
|
+
const getIndexInfo = require("./index.cjs22.js");
|
|
8
8
|
const getMatchingKeys = require("./index.cjs26.js");
|
|
9
9
|
const sortItems = require("./index.cjs25.js");
|
|
10
|
-
const project = require("./index.
|
|
10
|
+
const project = require("./index.cjs24.js");
|
|
11
11
|
class AsyncDataAdapter {
|
|
12
12
|
options;
|
|
13
13
|
id;
|
|
@@ -120,6 +120,13 @@ class AsyncDataAdapter {
|
|
|
120
120
|
getQueryError,
|
|
121
121
|
getQueryResult,
|
|
122
122
|
onQueryStateChange,
|
|
123
|
+
executeQuery: async (selector, options) => {
|
|
124
|
+
await ready;
|
|
125
|
+
registerQuery(selector, options);
|
|
126
|
+
const result = getQueryResult(selector, options);
|
|
127
|
+
unregisterQuery(selector, options);
|
|
128
|
+
return result;
|
|
129
|
+
},
|
|
123
130
|
dispose: async () => {
|
|
124
131
|
this.storageAdapters.delete(collection.name);
|
|
125
132
|
this.queries.delete(collection.name);
|
|
@@ -135,10 +142,7 @@ class AsyncDataAdapter {
|
|
|
135
142
|
const storage = this.storageAdapters.get(collectionName);
|
|
136
143
|
if (!storage)
|
|
137
144
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
138
|
-
await Promise.all(
|
|
139
|
-
storage.createIndex("id"),
|
|
140
|
-
...indices.map((index) => storage.createIndex(index))
|
|
141
|
-
]);
|
|
145
|
+
await Promise.all(indices.map((index) => storage.createIndex(index)));
|
|
142
146
|
await storage.setup();
|
|
143
147
|
}
|
|
144
148
|
ensureStorageAdapter(name) {
|
|
@@ -200,20 +204,28 @@ class AsyncDataAdapter {
|
|
|
200
204
|
rec.items = items;
|
|
201
205
|
}
|
|
202
206
|
async getIndexInfo(collectionName, selector) {
|
|
203
|
-
const
|
|
204
|
-
if (!
|
|
207
|
+
const storageAdapter = this.storageAdapters.get(collectionName);
|
|
208
|
+
if (!storageAdapter)
|
|
205
209
|
throw new Error(`No persistence adapter for collection ${collectionName}`);
|
|
206
210
|
if (selector != null && Object.keys(selector).length === 1 && "id" in selector && typeof selector.id !== "object") {
|
|
207
|
-
return {
|
|
211
|
+
return {
|
|
212
|
+
matched: true,
|
|
213
|
+
ids: [selector.id].filter(Boolean),
|
|
214
|
+
optimizedSelector: {}
|
|
215
|
+
};
|
|
208
216
|
}
|
|
209
217
|
if (selector == null) {
|
|
210
|
-
return {
|
|
218
|
+
return {
|
|
219
|
+
matched: false,
|
|
220
|
+
ids: [],
|
|
221
|
+
optimizedSelector: {}
|
|
222
|
+
};
|
|
211
223
|
}
|
|
212
224
|
const indices = this.collectionIndices.get(collectionName) ?? [];
|
|
213
225
|
return getIndexInfo.default(indices.map((field) => async (flatSelector) => {
|
|
214
226
|
if (!Object.hasOwnProperty.call(flatSelector, field))
|
|
215
227
|
return { matched: false };
|
|
216
|
-
const index = await
|
|
228
|
+
const index = await storageAdapter.readIndex(field);
|
|
217
229
|
const fieldSelector = flatSelector[field];
|
|
218
230
|
const filtersForNull = fieldSelector == null || fieldSelector.$exists === false;
|
|
219
231
|
const keys = filtersForNull ? { include: null, exclude: [...index.keys()].filter((key) => key != null) } : getMatchingKeys(field, flatSelector);
|
package/dist/index.cjs14.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const queryId = require("./index.
|
|
2
|
+
const queryId = require("./index.cjs20.js");
|
|
3
3
|
const randomId = require("./index.cjs8.js");
|
|
4
|
+
const batchOnNextTick = require("./index.cjs27.js");
|
|
4
5
|
class WorkerDataAdapter {
|
|
5
6
|
worker;
|
|
6
7
|
options;
|
|
7
8
|
id;
|
|
8
9
|
isDisposed = false;
|
|
9
10
|
workerReady;
|
|
11
|
+
log = () => {
|
|
12
|
+
};
|
|
10
13
|
collectionReady = /* @__PURE__ */ new Map();
|
|
14
|
+
batchExecutionHelpers = /* @__PURE__ */ new Map();
|
|
11
15
|
queries = {};
|
|
12
16
|
constructor(worker, options) {
|
|
13
17
|
this.worker = worker;
|
|
14
18
|
this.options = options;
|
|
15
19
|
this.id = this.options.id || "default-worker-data-adapter";
|
|
20
|
+
if (this.options.log)
|
|
21
|
+
this.log = this.options.log;
|
|
16
22
|
this.workerReady = new Promise((resolve, reject) => {
|
|
17
23
|
const timeoutId = setTimeout(() => {
|
|
18
24
|
reject(new Error("WorkerDataAdapter initialization timed out"));
|
|
@@ -51,6 +57,7 @@ class WorkerDataAdapter {
|
|
|
51
57
|
return;
|
|
52
58
|
if (id !== messageId)
|
|
53
59
|
return;
|
|
60
|
+
this.log(method, "result", data ?? error);
|
|
54
61
|
if (error) {
|
|
55
62
|
reject(error);
|
|
56
63
|
} else {
|
|
@@ -67,74 +74,61 @@ class WorkerDataAdapter {
|
|
|
67
74
|
});
|
|
68
75
|
});
|
|
69
76
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const collectionQueries = this.queries[collectionName];
|
|
76
|
-
if (!collectionQueries)
|
|
77
|
-
return 0;
|
|
78
|
-
const existing = collectionQueries.get(id);
|
|
79
|
-
return existing?.listeners || 0;
|
|
77
|
+
enqueueBatched(collectionName, method, args) {
|
|
78
|
+
const helper = this.batchExecutionHelpers.get(collectionName);
|
|
79
|
+
if (!helper)
|
|
80
|
+
throw new Error(`Collection "${collectionName}" is not registered in WorkerDataAdapter`);
|
|
81
|
+
return helper.enqueue(method, args);
|
|
80
82
|
}
|
|
83
|
+
// ---------- end batching integration ----------
|
|
81
84
|
updateQuery(collectionName, query, update) {
|
|
82
85
|
const id = queryId(query.selector, query.options);
|
|
83
86
|
const collectionQueries = this.queries[collectionName];
|
|
84
87
|
if (!collectionQueries)
|
|
85
88
|
return;
|
|
86
89
|
const existing = collectionQueries.get(id);
|
|
87
|
-
|
|
88
|
-
listeners: 0,
|
|
90
|
+
const newState = {
|
|
89
91
|
state: "active",
|
|
90
92
|
error: null,
|
|
91
93
|
items: [],
|
|
92
94
|
...existing,
|
|
93
95
|
...update
|
|
94
|
-
}
|
|
96
|
+
};
|
|
97
|
+
collectionQueries.set(id, newState);
|
|
95
98
|
this.queries[collectionName] = collectionQueries;
|
|
96
99
|
}
|
|
97
100
|
createCollectionBackend(collection, indices = []) {
|
|
98
101
|
this.queries[collection.name] = /* @__PURE__ */ new Map();
|
|
99
102
|
void this.exec("registerCollection", collection.name, indices);
|
|
100
103
|
this.collectionReady.set(collection.name, this.exec("isReady", collection.name));
|
|
104
|
+
this.batchExecutionHelpers.set(collection.name, batchOnNextTick(async (method, args) => this.exec(method, collection.name, args)));
|
|
101
105
|
return {
|
|
102
106
|
insert: async (item) => {
|
|
103
|
-
return this.
|
|
107
|
+
return this.enqueueBatched(collection.name, "insert", [item]);
|
|
104
108
|
},
|
|
105
109
|
updateOne: async (selector, modifier) => {
|
|
106
|
-
return this.
|
|
110
|
+
return this.enqueueBatched(collection.name, "updateOne", [selector, modifier]);
|
|
107
111
|
},
|
|
108
112
|
updateMany: async (selector, modifier) => {
|
|
109
|
-
return this.
|
|
113
|
+
return this.enqueueBatched(collection.name, "updateMany", [selector, modifier]);
|
|
110
114
|
},
|
|
111
115
|
replaceOne: async (selector, replacement) => {
|
|
112
|
-
return this.
|
|
116
|
+
return this.enqueueBatched(collection.name, "replaceOne", [selector, replacement]);
|
|
113
117
|
},
|
|
114
118
|
removeOne: async (selector) => {
|
|
115
|
-
return this.
|
|
119
|
+
return this.enqueueBatched(collection.name, "removeOne", [selector]);
|
|
116
120
|
},
|
|
117
121
|
removeMany: async (selector) => {
|
|
118
|
-
return this.
|
|
122
|
+
return this.enqueueBatched(collection.name, "removeMany", [selector]);
|
|
119
123
|
},
|
|
120
124
|
// methods for registering and unregistering queries that will be called from the collection during find/findOne
|
|
121
125
|
registerQuery: (selector, options) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this.updateQuery(collection.name, { selector, options }, { state: "active", error: null, items: [] });
|
|
125
|
-
void this.exec("registerQuery", collection.name, selector, options);
|
|
126
|
-
}
|
|
127
|
-
this.queryListeners(collection.name, { selector, options }, listeners + 1);
|
|
126
|
+
this.updateQuery(collection.name, { selector, options }, { state: "active", error: null, items: [] });
|
|
127
|
+
void this.exec("registerQuery", collection.name, selector, options);
|
|
128
128
|
},
|
|
129
129
|
unregisterQuery: (selector, options) => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const newListeners = Math.max(0, listeners - 1);
|
|
133
|
-
if (newListeners === 0) {
|
|
134
|
-
this.queries[collection.name]?.delete(queryId(selector, options));
|
|
135
|
-
void this.exec("unregisterQuery", collection.name, selector, options);
|
|
136
|
-
}
|
|
137
|
-
}, 0);
|
|
130
|
+
this.queries[collection.name]?.delete(queryId(selector, options));
|
|
131
|
+
void this.exec("unregisterQuery", collection.name, selector, options);
|
|
138
132
|
},
|
|
139
133
|
getQueryState: (selector, options) => {
|
|
140
134
|
const query = this.queries[collection.name]?.get(queryId(selector, options));
|
|
@@ -160,10 +154,9 @@ class WorkerDataAdapter {
|
|
|
160
154
|
return;
|
|
161
155
|
if (collectionName !== collection.name)
|
|
162
156
|
return;
|
|
163
|
-
if (
|
|
164
|
-
return;
|
|
165
|
-
if (JSON.stringify(responseOptions) !== JSON.stringify(options))
|
|
157
|
+
if (queryId(responseSelector, responseOptions) !== queryId(selector, options))
|
|
166
158
|
return;
|
|
159
|
+
this.log("queryUpdate", responseSelector, responseOptions, state, data ?? error);
|
|
167
160
|
this.updateQuery(collection.name, {
|
|
168
161
|
selector: responseSelector,
|
|
169
162
|
options: responseOptions
|
|
@@ -175,6 +168,7 @@ class WorkerDataAdapter {
|
|
|
175
168
|
this.worker.removeEventListener("message", handler);
|
|
176
169
|
};
|
|
177
170
|
},
|
|
171
|
+
executeQuery: (selector, options) => this.exec("executeQuery", collection.name, selector, options),
|
|
178
172
|
// lifecycle methods
|
|
179
173
|
dispose: async () => {
|
|
180
174
|
await this.exec("unregisterCollection", collection.name);
|