@oimdb/core 1.4.1 → 2.0.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/README.md +594 -76
- package/dist/index.cjs +1987 -1463
- package/dist/index.d.cts +629 -499
- package/dist/index.d.ts +629 -499
- package/dist/index.js +1971 -1458
- package/llms.txt +429 -0
- package/package.json +7 -2
package/dist/index.cjs
CHANGED
|
@@ -29,13 +29,19 @@ __export(index_exports, {
|
|
|
29
29
|
OIMCollection: () => OIMCollection,
|
|
30
30
|
OIMCollectionByPkSelector: () => OIMCollectionByPkSelector,
|
|
31
31
|
OIMCollectionByPksSelector: () => OIMCollectionByPksSelector,
|
|
32
|
-
|
|
32
|
+
OIMCollectionChangedFields: () => OIMCollectionChangedFields,
|
|
33
|
+
OIMCollectionIndexFactory: () => OIMCollectionIndexFactory,
|
|
34
|
+
OIMCollectionIndexManualOrderedArrayBased: () => OIMCollectionIndexManualOrderedArrayBased,
|
|
35
|
+
OIMCollectionOrderedListCommandStream: () => OIMCollectionOrderedListCommandStream,
|
|
36
|
+
OIMCollectionSelectors: () => OIMCollectionSelectors,
|
|
33
37
|
OIMCollectionStore: () => OIMCollectionStore,
|
|
34
38
|
OIMCollectionStoreMapDriven: () => OIMCollectionStoreMapDriven,
|
|
35
39
|
OIMComparatorFactory: () => OIMComparatorFactory,
|
|
36
|
-
|
|
40
|
+
OIMComputeRuntime: () => OIMComputeRuntime,
|
|
37
41
|
OIMComputed: () => OIMComputed,
|
|
38
42
|
OIMDBSettings: () => OIMDBSettings,
|
|
43
|
+
OIMDerivedCollectionIndexArrayBased: () => OIMDerivedCollectionIndexArrayBased,
|
|
44
|
+
OIMDerivedCollectionIndexSetBased: () => OIMDerivedCollectionIndexSetBased,
|
|
39
45
|
OIMEffect: () => OIMEffect,
|
|
40
46
|
OIMEffectDependencyComputed: () => OIMEffectDependencyComputed,
|
|
41
47
|
OIMEffectDependencyKeyed: () => OIMEffectDependencyKeyed,
|
|
@@ -53,6 +59,7 @@ __export(index_exports, {
|
|
|
53
59
|
OIMEventQueueSchedulerImmediate: () => OIMEventQueueSchedulerImmediate,
|
|
54
60
|
OIMEventQueueSchedulerMicrotask: () => OIMEventQueueSchedulerMicrotask,
|
|
55
61
|
OIMEventQueueSchedulerTimeout: () => OIMEventQueueSchedulerTimeout,
|
|
62
|
+
OIMIndex: () => OIMIndex,
|
|
56
63
|
OIMIndexArrayBased: () => OIMIndexArrayBased,
|
|
57
64
|
OIMIndexComparatorFactory: () => OIMIndexComparatorFactory,
|
|
58
65
|
OIMIndexManualArrayBased: () => OIMIndexManualArrayBased,
|
|
@@ -74,16 +81,20 @@ __export(index_exports, {
|
|
|
74
81
|
OIMObjectStoreRecordDriven: () => OIMObjectStoreRecordDriven,
|
|
75
82
|
OIMObjectValueByKeySelector: () => OIMObjectValueByKeySelector,
|
|
76
83
|
OIMObjectValuesByKeysSelector: () => OIMObjectValuesByKeysSelector,
|
|
77
|
-
|
|
84
|
+
OIMOrderedListCommandStream: () => OIMOrderedListCommandStream,
|
|
78
85
|
OIMPkSelectorFactory: () => OIMPkSelectorFactory,
|
|
79
|
-
OIMRICollection: () => OIMRICollection,
|
|
80
86
|
OIMReactiveCollection: () => OIMReactiveCollection,
|
|
87
|
+
OIMReactiveCollectionIndexManualArrayBased: () => OIMReactiveCollectionIndexManualArrayBased,
|
|
88
|
+
OIMReactiveCollectionIndexManualSetBased: () => OIMReactiveCollectionIndexManualSetBased,
|
|
89
|
+
OIMReactiveIndex: () => OIMReactiveIndex,
|
|
81
90
|
OIMReactiveIndexArrayBased: () => OIMReactiveIndexArrayBased,
|
|
82
91
|
OIMReactiveIndexManualArrayBased: () => OIMReactiveIndexManualArrayBased,
|
|
83
92
|
OIMReactiveIndexManualSetBased: () => OIMReactiveIndexManualSetBased,
|
|
84
93
|
OIMReactiveIndexSetBased: () => OIMReactiveIndexSetBased,
|
|
85
94
|
OIMReactiveObject: () => OIMReactiveObject,
|
|
86
|
-
OIMSelector: () => OIMSelector
|
|
95
|
+
OIMSelector: () => OIMSelector,
|
|
96
|
+
createOIMCollectionContext: () => createOIMCollectionContext,
|
|
97
|
+
createOIMCollectionIndexFactory: () => createOIMCollectionIndexFactory
|
|
87
98
|
});
|
|
88
99
|
module.exports = __toCommonJS(index_exports);
|
|
89
100
|
|
|
@@ -91,14 +102,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
91
102
|
var OIMCollectionStore = class {
|
|
92
103
|
};
|
|
93
104
|
|
|
94
|
-
// src/abstract/OIMIndexStoreSetBased.ts
|
|
95
|
-
var OIMIndexStoreSetBased = class {
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// src/abstract/OIMIndexStoreArrayBased.ts
|
|
99
|
-
var OIMIndexStoreArrayBased = class {
|
|
100
|
-
};
|
|
101
|
-
|
|
102
105
|
// src/core/OIMEventEmitter.ts
|
|
103
106
|
var OIMEventEmitter = class {
|
|
104
107
|
constructor() {
|
|
@@ -204,7 +207,94 @@ var OIMEventEmitter = class {
|
|
|
204
207
|
}
|
|
205
208
|
};
|
|
206
209
|
|
|
207
|
-
// src/
|
|
210
|
+
// src/enums/EOIMIndexEventType.ts
|
|
211
|
+
var EOIMIndexEventType = /* @__PURE__ */ ((EOIMIndexEventType2) => {
|
|
212
|
+
EOIMIndexEventType2[EOIMIndexEventType2["UPDATE"] = 0] = "UPDATE";
|
|
213
|
+
return EOIMIndexEventType2;
|
|
214
|
+
})(EOIMIndexEventType || {});
|
|
215
|
+
|
|
216
|
+
// src/abstract/OIMIndex.ts
|
|
217
|
+
var OIMIndex = class {
|
|
218
|
+
constructor(store, comparePks) {
|
|
219
|
+
this.emitter = new OIMEventEmitter();
|
|
220
|
+
this.store = store;
|
|
221
|
+
this.comparePks = comparePks;
|
|
222
|
+
}
|
|
223
|
+
hasKey(key) {
|
|
224
|
+
return this.store.getOneByKey(key) !== void 0;
|
|
225
|
+
}
|
|
226
|
+
getKeys() {
|
|
227
|
+
return this.store.getAllKeys();
|
|
228
|
+
}
|
|
229
|
+
getKeySize(key) {
|
|
230
|
+
const bucket = this.store.getOneByKey(key);
|
|
231
|
+
return bucket ? this.getBucketSize(bucket) : 0;
|
|
232
|
+
}
|
|
233
|
+
get size() {
|
|
234
|
+
return this.store.countAll();
|
|
235
|
+
}
|
|
236
|
+
get isEmpty() {
|
|
237
|
+
return this.store.countAll() === 0;
|
|
238
|
+
}
|
|
239
|
+
getEntitiesByKey(key) {
|
|
240
|
+
const bucket = this.store.getOneByKey(key);
|
|
241
|
+
return bucket ? this.slotsToEntities(bucket) : [];
|
|
242
|
+
}
|
|
243
|
+
getEntitiesByKeys(keys) {
|
|
244
|
+
const result = /* @__PURE__ */ new Map();
|
|
245
|
+
const bucketsByKey = this.store.getManyByKeys(keys);
|
|
246
|
+
for (const [key, bucket] of bucketsByKey) {
|
|
247
|
+
result.set(key, this.slotsToEntities(bucket));
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
getMetrics() {
|
|
252
|
+
let totalPks = 0;
|
|
253
|
+
let maxBucketSize = 0;
|
|
254
|
+
let minBucketSize = Infinity;
|
|
255
|
+
const all = this.store.getAll();
|
|
256
|
+
for (const bucket of all.values()) {
|
|
257
|
+
const size = this.getBucketSize(bucket);
|
|
258
|
+
totalPks += size;
|
|
259
|
+
maxBucketSize = Math.max(maxBucketSize, size);
|
|
260
|
+
minBucketSize = Math.min(minBucketSize, size);
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
totalKeys: all.size,
|
|
264
|
+
totalPks,
|
|
265
|
+
averagePksPerKey: all.size > 0 ? totalPks / all.size : 0,
|
|
266
|
+
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
267
|
+
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
destroy() {
|
|
271
|
+
this.emitter.offAll();
|
|
272
|
+
this.store.clear();
|
|
273
|
+
}
|
|
274
|
+
emitUpdate(keys) {
|
|
275
|
+
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
276
|
+
}
|
|
277
|
+
emitUpdateOne(key) {
|
|
278
|
+
this.emitUpdate([key]);
|
|
279
|
+
}
|
|
280
|
+
slotsToEntities(slots) {
|
|
281
|
+
const entities = [];
|
|
282
|
+
for (const slot of slots) {
|
|
283
|
+
if (slot.item !== void 0) entities.push(slot.item);
|
|
284
|
+
}
|
|
285
|
+
return entities;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/abstract/OIMIndexStoreSetBased.ts
|
|
290
|
+
var OIMIndexStoreSetBased = class {
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// src/abstract/OIMIndexStoreArrayBased.ts
|
|
294
|
+
var OIMIndexStoreArrayBased = class {
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// src/enums/EOIMEventQueueSchedulerEventType.ts
|
|
208
298
|
var EOIMEventQueueSchedulerEventType = /* @__PURE__ */ ((EOIMEventQueueSchedulerEventType2) => {
|
|
209
299
|
EOIMEventQueueSchedulerEventType2[EOIMEventQueueSchedulerEventType2["FLUSH"] = 0] = "FLUSH";
|
|
210
300
|
return EOIMEventQueueSchedulerEventType2;
|
|
@@ -229,332 +319,202 @@ var OIMEventQueueScheduler = class {
|
|
|
229
319
|
}
|
|
230
320
|
};
|
|
231
321
|
|
|
232
|
-
// src/enum/EOIMIndexEventType.ts
|
|
233
|
-
var EOIMIndexEventType = /* @__PURE__ */ ((EOIMIndexEventType2) => {
|
|
234
|
-
EOIMIndexEventType2[EOIMIndexEventType2["UPDATE"] = 0] = "UPDATE";
|
|
235
|
-
return EOIMIndexEventType2;
|
|
236
|
-
})(EOIMIndexEventType || {});
|
|
237
|
-
|
|
238
322
|
// src/core/OIMIndexStoreMapDrivenSetBased.ts
|
|
239
323
|
var OIMIndexStoreMapDrivenSetBased = class extends OIMIndexStoreSetBased {
|
|
240
324
|
constructor() {
|
|
241
325
|
super(...arguments);
|
|
242
|
-
this.
|
|
326
|
+
this.slots = /* @__PURE__ */ new Map();
|
|
243
327
|
}
|
|
244
|
-
setOneByKey(key,
|
|
245
|
-
this.
|
|
328
|
+
setOneByKey(key, slots) {
|
|
329
|
+
this.slots.set(key, slots);
|
|
246
330
|
}
|
|
247
331
|
removeOneByKey(key) {
|
|
248
|
-
this.
|
|
332
|
+
this.slots.delete(key);
|
|
249
333
|
}
|
|
250
334
|
removeManyByKeys(keys) {
|
|
251
335
|
for (const key of keys) {
|
|
252
|
-
this.
|
|
336
|
+
this.slots.delete(key);
|
|
253
337
|
}
|
|
254
338
|
}
|
|
255
339
|
getOneByKey(key) {
|
|
256
|
-
return this.
|
|
340
|
+
return this.slots.get(key);
|
|
257
341
|
}
|
|
258
342
|
getManyByKeys(keys) {
|
|
259
343
|
const result = /* @__PURE__ */ new Map();
|
|
260
344
|
for (const key of keys) {
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
263
|
-
result.set(key,
|
|
345
|
+
const slots = this.getOneByKey(key);
|
|
346
|
+
if (slots !== void 0) {
|
|
347
|
+
result.set(key, slots);
|
|
264
348
|
}
|
|
265
349
|
}
|
|
266
350
|
return result;
|
|
267
351
|
}
|
|
268
352
|
getAllKeys() {
|
|
269
|
-
return Array.from(this.
|
|
353
|
+
return Array.from(this.slots.keys());
|
|
270
354
|
}
|
|
271
355
|
getAll() {
|
|
272
|
-
return new Map(this.
|
|
356
|
+
return new Map(this.slots);
|
|
273
357
|
}
|
|
274
358
|
countAll() {
|
|
275
|
-
return this.
|
|
359
|
+
return this.slots.size;
|
|
276
360
|
}
|
|
277
361
|
clear() {
|
|
278
|
-
this.
|
|
362
|
+
this.slots.clear();
|
|
279
363
|
}
|
|
280
364
|
};
|
|
281
365
|
|
|
282
366
|
// src/abstract/OIMIndexSetBased.ts
|
|
283
|
-
var OIMIndexSetBased = class {
|
|
367
|
+
var OIMIndexSetBased = class extends OIMIndex {
|
|
284
368
|
constructor(options = {}) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Get primary keys for multiple index keys
|
|
291
|
-
*/
|
|
292
|
-
getPksByKeys(keys) {
|
|
293
|
-
return this.store.getManyByKeys(keys);
|
|
369
|
+
super(
|
|
370
|
+
options.store ?? new OIMIndexStoreMapDrivenSetBased(),
|
|
371
|
+
options.comparePks
|
|
372
|
+
);
|
|
294
373
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
* Get primary keys for a specific index key
|
|
298
|
-
*/
|
|
299
|
-
getPks(key) {
|
|
300
|
-
return this.getPksByKey(key);
|
|
374
|
+
getBucketSize(bucket) {
|
|
375
|
+
return bucket.size;
|
|
301
376
|
}
|
|
302
|
-
/**
|
|
303
|
-
* Get primary keys for a specific index key
|
|
304
|
-
*/
|
|
305
377
|
getPksByKey(key) {
|
|
306
|
-
const
|
|
307
|
-
return
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Check if an index key exists
|
|
311
|
-
*/
|
|
312
|
-
hasKey(key) {
|
|
313
|
-
return this.store.getOneByKey(key) !== void 0;
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Get all index keys
|
|
317
|
-
*/
|
|
318
|
-
getKeys() {
|
|
319
|
-
return this.store.getAllKeys();
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Get the number of primary keys for a specific index key
|
|
323
|
-
*/
|
|
324
|
-
getKeySize(key) {
|
|
325
|
-
const pksSet = this.store.getOneByKey(key);
|
|
326
|
-
return pksSet ? pksSet.size : 0;
|
|
378
|
+
const slotsSet = this.store.getOneByKey(key);
|
|
379
|
+
return slotsSet ? this.slotsToPks(slotsSet) : /* @__PURE__ */ new Set();
|
|
327
380
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
381
|
+
getPksByKeys(keys) {
|
|
382
|
+
const result = /* @__PURE__ */ new Map();
|
|
383
|
+
const slotsByKey = this.store.getManyByKeys(keys);
|
|
384
|
+
for (const [key, slots] of slotsByKey) {
|
|
385
|
+
result.set(key, this.slotsToPks(slots));
|
|
386
|
+
}
|
|
387
|
+
return result;
|
|
333
388
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
*/
|
|
337
|
-
get isEmpty() {
|
|
338
|
-
return this.store.countAll() === 0;
|
|
389
|
+
getSlotsByKey(key) {
|
|
390
|
+
return this.store.getOneByKey(key) ?? /* @__PURE__ */ new Set();
|
|
339
391
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
*/
|
|
343
|
-
getMetrics() {
|
|
344
|
-
let totalPks = 0;
|
|
345
|
-
let maxBucketSize = 0;
|
|
346
|
-
let minBucketSize = Infinity;
|
|
347
|
-
const allPks = this.store.getAll();
|
|
348
|
-
for (const pksSet of allPks.values()) {
|
|
349
|
-
totalPks += pksSet.size;
|
|
350
|
-
maxBucketSize = Math.max(maxBucketSize, pksSet.size);
|
|
351
|
-
minBucketSize = Math.min(minBucketSize, pksSet.size);
|
|
352
|
-
}
|
|
353
|
-
return {
|
|
354
|
-
totalKeys: allPks.size,
|
|
355
|
-
totalPks,
|
|
356
|
-
averagePksPerKey: allPks.size > 0 ? totalPks / allPks.size : 0,
|
|
357
|
-
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
358
|
-
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
359
|
-
};
|
|
392
|
+
getSlotsByKeys(keys) {
|
|
393
|
+
return this.store.getManyByKeys(keys);
|
|
360
394
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
this.emitter.offAll();
|
|
366
|
-
this.store.clear();
|
|
395
|
+
slotsToPks(slots) {
|
|
396
|
+
const pks = /* @__PURE__ */ new Set();
|
|
397
|
+
for (const slot of slots) pks.add(slot.pk);
|
|
398
|
+
return pks;
|
|
367
399
|
}
|
|
368
|
-
|
|
369
|
-
* Set primary keys for a specific index key with optional comparison.
|
|
370
|
-
* If comparator is provided and returns true (no changes), skip the update.
|
|
371
|
-
*/
|
|
372
|
-
setPksWithComparison(key, newPks) {
|
|
400
|
+
setSlotsWithComparison(key, newSlots) {
|
|
373
401
|
if (this.comparePks) {
|
|
374
|
-
const
|
|
375
|
-
if (
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
402
|
+
const existingSlotsSet = this.store.getOneByKey(key);
|
|
403
|
+
if (existingSlotsSet && existingSlotsSet.size === newSlots.size) {
|
|
404
|
+
if (this.comparePks(
|
|
405
|
+
Array.from(this.slotsToPks(existingSlotsSet)),
|
|
406
|
+
Array.from(this.slotsToPks(newSlots))
|
|
407
|
+
)) {
|
|
379
408
|
return false;
|
|
380
409
|
}
|
|
381
|
-
} else if (!
|
|
410
|
+
} else if (!existingSlotsSet && newSlots.size === 0) {
|
|
382
411
|
return false;
|
|
383
412
|
}
|
|
384
413
|
}
|
|
385
|
-
this.store.setOneByKey(key,
|
|
414
|
+
this.store.setOneByKey(key, newSlots);
|
|
386
415
|
return true;
|
|
387
416
|
}
|
|
388
|
-
/**
|
|
389
|
-
* Emit update event with changed keys
|
|
390
|
-
*/
|
|
391
|
-
emitUpdate(keys) {
|
|
392
|
-
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Emit update event for a single key (fast-path override point).
|
|
396
|
-
*/
|
|
397
|
-
emitUpdateOne(key) {
|
|
398
|
-
this.emitUpdate([key]);
|
|
399
|
-
}
|
|
400
417
|
};
|
|
401
418
|
|
|
402
419
|
// src/core/OIMIndexStoreMapDrivenArrayBased.ts
|
|
403
420
|
var OIMIndexStoreMapDrivenArrayBased = class extends OIMIndexStoreArrayBased {
|
|
404
421
|
constructor() {
|
|
405
422
|
super(...arguments);
|
|
406
|
-
this.
|
|
423
|
+
this.slots = /* @__PURE__ */ new Map();
|
|
407
424
|
}
|
|
408
|
-
setOneByKey(key,
|
|
409
|
-
this.
|
|
425
|
+
setOneByKey(key, slots) {
|
|
426
|
+
this.slots.set(key, slots);
|
|
410
427
|
}
|
|
411
428
|
removeOneByKey(key) {
|
|
412
|
-
this.
|
|
429
|
+
this.slots.delete(key);
|
|
413
430
|
}
|
|
414
431
|
removeManyByKeys(keys) {
|
|
415
432
|
for (const key of keys) {
|
|
416
|
-
this.
|
|
433
|
+
this.slots.delete(key);
|
|
417
434
|
}
|
|
418
435
|
}
|
|
419
436
|
getOneByKey(key) {
|
|
420
|
-
return this.
|
|
437
|
+
return this.slots.get(key);
|
|
421
438
|
}
|
|
422
439
|
getManyByKeys(keys) {
|
|
423
440
|
const result = /* @__PURE__ */ new Map();
|
|
424
441
|
for (const key of keys) {
|
|
425
|
-
const
|
|
426
|
-
if (
|
|
427
|
-
result.set(key,
|
|
442
|
+
const slots = this.getOneByKey(key);
|
|
443
|
+
if (slots !== void 0) {
|
|
444
|
+
result.set(key, slots);
|
|
428
445
|
}
|
|
429
446
|
}
|
|
430
447
|
return result;
|
|
431
448
|
}
|
|
432
449
|
getAllKeys() {
|
|
433
|
-
return Array.from(this.
|
|
450
|
+
return Array.from(this.slots.keys());
|
|
434
451
|
}
|
|
435
452
|
getAll() {
|
|
436
|
-
return new Map(this.
|
|
453
|
+
return new Map(this.slots);
|
|
437
454
|
}
|
|
438
455
|
countAll() {
|
|
439
|
-
return this.
|
|
456
|
+
return this.slots.size;
|
|
440
457
|
}
|
|
441
458
|
clear() {
|
|
442
|
-
this.
|
|
459
|
+
this.slots.clear();
|
|
443
460
|
}
|
|
444
461
|
};
|
|
445
462
|
|
|
446
463
|
// src/abstract/OIMIndexArrayBased.ts
|
|
447
|
-
var OIMIndexArrayBased = class {
|
|
464
|
+
var OIMIndexArrayBased = class extends OIMIndex {
|
|
448
465
|
constructor(options = {}) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
466
|
+
super(
|
|
467
|
+
options.store ?? new OIMIndexStoreMapDrivenArrayBased(),
|
|
468
|
+
options.comparePks
|
|
469
|
+
);
|
|
452
470
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
*/
|
|
456
|
-
getPksByKeys(keys) {
|
|
457
|
-
return this.store.getManyByKeys(keys);
|
|
471
|
+
getBucketSize(bucket) {
|
|
472
|
+
return bucket.length;
|
|
458
473
|
}
|
|
459
|
-
/**
|
|
460
|
-
* Get primary keys for a specific index key
|
|
461
|
-
*/
|
|
462
474
|
getPksByKey(key) {
|
|
463
|
-
const
|
|
464
|
-
return
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Check if an index key exists
|
|
468
|
-
*/
|
|
469
|
-
hasKey(key) {
|
|
470
|
-
return this.store.getOneByKey(key) !== void 0;
|
|
471
|
-
}
|
|
472
|
-
/**
|
|
473
|
-
* Get all index keys
|
|
474
|
-
*/
|
|
475
|
-
getKeys() {
|
|
476
|
-
return this.store.getAllKeys();
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Get the number of primary keys for a specific index key
|
|
480
|
-
*/
|
|
481
|
-
getKeySize(key) {
|
|
482
|
-
const pksArray = this.store.getOneByKey(key);
|
|
483
|
-
return pksArray ? pksArray.length : 0;
|
|
475
|
+
const slotsArray = this.store.getOneByKey(key);
|
|
476
|
+
return slotsArray ? this.slotsToPks(slotsArray) : [];
|
|
484
477
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
478
|
+
getPksByKeys(keys) {
|
|
479
|
+
const result = /* @__PURE__ */ new Map();
|
|
480
|
+
const slotsByKey = this.store.getManyByKeys(keys);
|
|
481
|
+
for (const [key, slots] of slotsByKey) {
|
|
482
|
+
result.set(key, this.slotsToPks(slots));
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
490
485
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
*/
|
|
494
|
-
get isEmpty() {
|
|
495
|
-
return this.store.countAll() === 0;
|
|
486
|
+
getSlotsByKey(key) {
|
|
487
|
+
return this.store.getOneByKey(key) ?? [];
|
|
496
488
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
*/
|
|
500
|
-
getMetrics() {
|
|
501
|
-
let totalPks = 0;
|
|
502
|
-
let maxBucketSize = 0;
|
|
503
|
-
let minBucketSize = Infinity;
|
|
504
|
-
const allPks = this.store.getAll();
|
|
505
|
-
for (const pksArray of allPks.values()) {
|
|
506
|
-
totalPks += pksArray.length;
|
|
507
|
-
maxBucketSize = Math.max(maxBucketSize, pksArray.length);
|
|
508
|
-
minBucketSize = Math.min(minBucketSize, pksArray.length);
|
|
509
|
-
}
|
|
510
|
-
return {
|
|
511
|
-
totalKeys: allPks.size,
|
|
512
|
-
totalPks,
|
|
513
|
-
averagePksPerKey: allPks.size > 0 ? totalPks / allPks.size : 0,
|
|
514
|
-
maxBucketSize: maxBucketSize === -Infinity ? 0 : maxBucketSize,
|
|
515
|
-
minBucketSize: minBucketSize === Infinity ? 0 : minBucketSize
|
|
516
|
-
};
|
|
489
|
+
getSlotsByKeys(keys) {
|
|
490
|
+
return this.store.getManyByKeys(keys);
|
|
517
491
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
this.store.clear();
|
|
492
|
+
slotsToPks(slots) {
|
|
493
|
+
const pks = [];
|
|
494
|
+
pks.length = slots.length;
|
|
495
|
+
for (let i = 0; i < slots.length; i++) pks[i] = slots[i].pk;
|
|
496
|
+
return pks;
|
|
524
497
|
}
|
|
525
|
-
|
|
526
|
-
* Set primary keys for a specific index key with optional comparison.
|
|
527
|
-
* If comparator is provided and returns true (no changes), skip the update.
|
|
528
|
-
*/
|
|
529
|
-
setPksWithComparison(key, newPks) {
|
|
498
|
+
setSlotsWithComparison(key, newSlots) {
|
|
530
499
|
if (this.comparePks) {
|
|
531
|
-
const
|
|
532
|
-
if (
|
|
533
|
-
if (this.comparePks(
|
|
500
|
+
const existingSlotsArray = this.store.getOneByKey(key);
|
|
501
|
+
if (existingSlotsArray && existingSlotsArray.length === newSlots.length) {
|
|
502
|
+
if (this.comparePks(
|
|
503
|
+
this.slotsToPks(existingSlotsArray),
|
|
504
|
+
this.slotsToPks(newSlots)
|
|
505
|
+
)) {
|
|
534
506
|
return false;
|
|
535
507
|
}
|
|
536
|
-
} else if (!
|
|
508
|
+
} else if (!existingSlotsArray && newSlots.length === 0) {
|
|
537
509
|
return false;
|
|
538
510
|
}
|
|
539
511
|
}
|
|
540
|
-
this.store.setOneByKey(key,
|
|
512
|
+
this.store.setOneByKey(key, newSlots);
|
|
541
513
|
return true;
|
|
542
514
|
}
|
|
543
|
-
/**
|
|
544
|
-
* Emit update event with changed keys
|
|
545
|
-
*/
|
|
546
|
-
emitUpdate(keys) {
|
|
547
|
-
this.emitter.emit(0 /* UPDATE */, { keys });
|
|
548
|
-
}
|
|
549
|
-
/**
|
|
550
|
-
* Emit update event for a single key (fast-path override point).
|
|
551
|
-
*/
|
|
552
|
-
emitUpdateOne(key) {
|
|
553
|
-
this.emitUpdate([key]);
|
|
554
|
-
}
|
|
555
515
|
};
|
|
556
516
|
|
|
557
|
-
// src/
|
|
517
|
+
// src/enums/EOIMEventQueueEventType.ts
|
|
558
518
|
var EOIMEventQueueEventType = /* @__PURE__ */ ((EOIMEventQueueEventType2) => {
|
|
559
519
|
EOIMEventQueueEventType2[EOIMEventQueueEventType2["AFTER_FLUSH"] = 0] = "AFTER_FLUSH";
|
|
560
520
|
EOIMEventQueueEventType2[EOIMEventQueueEventType2["BEFORE_FLUSH"] = 1] = "BEFORE_FLUSH";
|
|
@@ -808,17 +768,17 @@ var OIMUpdateEventEmitter = class {
|
|
|
808
768
|
}
|
|
809
769
|
};
|
|
810
770
|
|
|
811
|
-
// src/abstract/
|
|
812
|
-
var
|
|
771
|
+
// src/abstract/OIMReactiveIndex.ts
|
|
772
|
+
var OIMReactiveIndex = class {
|
|
813
773
|
constructor(queue, createIndex) {
|
|
814
774
|
this.updateEmitter = new OIMUpdateEventEmitter(queue);
|
|
815
775
|
this.index = createIndex(this.updateEmitter);
|
|
816
776
|
}
|
|
817
|
-
|
|
818
|
-
return this.index.
|
|
777
|
+
getEntitiesByKey(key) {
|
|
778
|
+
return this.index.getEntitiesByKey(key);
|
|
819
779
|
}
|
|
820
|
-
|
|
821
|
-
return this.index.
|
|
780
|
+
getEntitiesByKeys(keys) {
|
|
781
|
+
return this.index.getEntitiesByKeys(keys);
|
|
822
782
|
}
|
|
823
783
|
hasKey(key) {
|
|
824
784
|
return this.index.hasKey(key);
|
|
@@ -865,11 +825,10 @@ var OIMReactiveIndexSetBased = class {
|
|
|
865
825
|
}
|
|
866
826
|
};
|
|
867
827
|
|
|
868
|
-
// src/abstract/
|
|
869
|
-
var
|
|
828
|
+
// src/abstract/OIMReactiveIndexSetBased.ts
|
|
829
|
+
var OIMReactiveIndexSetBased = class extends OIMReactiveIndex {
|
|
870
830
|
constructor(queue, createIndex) {
|
|
871
|
-
|
|
872
|
-
this.index = createIndex(this.updateEmitter);
|
|
831
|
+
super(queue, createIndex);
|
|
873
832
|
}
|
|
874
833
|
getPksByKey(key) {
|
|
875
834
|
return this.index.getPksByKey(key);
|
|
@@ -877,59 +836,41 @@ var OIMReactiveIndexArrayBased = class {
|
|
|
877
836
|
getPksByKeys(keys) {
|
|
878
837
|
return this.index.getPksByKeys(keys);
|
|
879
838
|
}
|
|
880
|
-
|
|
881
|
-
return this.index.
|
|
882
|
-
}
|
|
883
|
-
getKeys() {
|
|
884
|
-
return this.index.getKeys();
|
|
885
|
-
}
|
|
886
|
-
getKeySize(key) {
|
|
887
|
-
return this.index.getKeySize(key);
|
|
839
|
+
getSlotsByKey(key) {
|
|
840
|
+
return this.index.getSlotsByKey(key);
|
|
888
841
|
}
|
|
889
|
-
|
|
890
|
-
return this.index.
|
|
842
|
+
getSlotsByKeys(keys) {
|
|
843
|
+
return this.index.getSlotsByKeys(keys);
|
|
891
844
|
}
|
|
892
|
-
|
|
893
|
-
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
// src/abstract/OIMReactiveIndexArrayBased.ts
|
|
848
|
+
var OIMReactiveIndexArrayBased = class extends OIMReactiveIndex {
|
|
849
|
+
constructor(queue, createIndex) {
|
|
850
|
+
super(queue, createIndex);
|
|
894
851
|
}
|
|
895
|
-
|
|
896
|
-
return this.index.
|
|
852
|
+
getPksByKey(key) {
|
|
853
|
+
return this.index.getPksByKey(key);
|
|
897
854
|
}
|
|
898
|
-
|
|
899
|
-
return this.
|
|
855
|
+
getPksByKeys(keys) {
|
|
856
|
+
return this.index.getPksByKeys(keys);
|
|
900
857
|
}
|
|
901
|
-
|
|
902
|
-
return this.
|
|
858
|
+
getSlotsByKey(key) {
|
|
859
|
+
return this.index.getSlotsByKey(key);
|
|
903
860
|
}
|
|
904
|
-
|
|
905
|
-
this.
|
|
861
|
+
getSlotsByKeys(keys) {
|
|
862
|
+
return this.index.getSlotsByKeys(keys);
|
|
906
863
|
}
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
return this.updateEmitter.getMetrics();
|
|
918
|
-
}
|
|
919
|
-
destroy() {
|
|
920
|
-
this.updateEmitter.destroy();
|
|
921
|
-
this.index.destroy();
|
|
922
|
-
}
|
|
923
|
-
};
|
|
924
|
-
|
|
925
|
-
// src/abstract/OIMObjectStore.ts
|
|
926
|
-
var OIMObjectStore = class {
|
|
927
|
-
};
|
|
928
|
-
|
|
929
|
-
// src/core/OIMPkSelectorFactory.ts
|
|
930
|
-
var OIMPkSelectorFactory = class {
|
|
931
|
-
createIdSelector() {
|
|
932
|
-
return (entity) => entity.id;
|
|
864
|
+
};
|
|
865
|
+
|
|
866
|
+
// src/abstract/OIMObjectStore.ts
|
|
867
|
+
var OIMObjectStore = class {
|
|
868
|
+
};
|
|
869
|
+
|
|
870
|
+
// src/core/OIMPkSelectorFactory.ts
|
|
871
|
+
var OIMPkSelectorFactory = class {
|
|
872
|
+
createIdSelector() {
|
|
873
|
+
return (entity) => entity.id;
|
|
933
874
|
}
|
|
934
875
|
};
|
|
935
876
|
|
|
@@ -937,26 +878,58 @@ var OIMPkSelectorFactory = class {
|
|
|
937
878
|
var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
938
879
|
constructor() {
|
|
939
880
|
super(...arguments);
|
|
940
|
-
this.
|
|
881
|
+
this.slots = /* @__PURE__ */ new Map();
|
|
941
882
|
}
|
|
942
883
|
setOneByPk(pk, entity) {
|
|
943
|
-
this.
|
|
884
|
+
const slot = this.slots.get(pk);
|
|
885
|
+
if (slot) {
|
|
886
|
+
slot.item = entity;
|
|
887
|
+
return slot;
|
|
888
|
+
} else {
|
|
889
|
+
const nextSlot = { pk, item: entity };
|
|
890
|
+
this.slots.set(pk, nextSlot);
|
|
891
|
+
return nextSlot;
|
|
892
|
+
}
|
|
944
893
|
}
|
|
945
894
|
setManyByPks(pks, entities) {
|
|
895
|
+
const slots = [];
|
|
896
|
+
slots.length = pks.length;
|
|
897
|
+
for (let i = 0; i < pks.length; i++) {
|
|
898
|
+
slots[i] = this.setOneByPk(pks[i], entities[i]);
|
|
899
|
+
}
|
|
900
|
+
return slots;
|
|
901
|
+
}
|
|
902
|
+
getSlotByPk(pk) {
|
|
903
|
+
return this.slots.get(pk);
|
|
904
|
+
}
|
|
905
|
+
getSlotsByPks(pks) {
|
|
906
|
+
const result = [];
|
|
907
|
+
result.length = pks.length;
|
|
908
|
+
let writeIndex = 0;
|
|
946
909
|
for (let i = 0; i < pks.length; i++) {
|
|
947
|
-
this.
|
|
910
|
+
const slot = this.slots.get(pks[i]);
|
|
911
|
+
if (slot !== void 0) {
|
|
912
|
+
result[writeIndex++] = slot;
|
|
913
|
+
}
|
|
948
914
|
}
|
|
915
|
+
result.length = writeIndex;
|
|
916
|
+
return result;
|
|
917
|
+
}
|
|
918
|
+
getAllSlots() {
|
|
919
|
+
return Array.from(this.slots.values());
|
|
949
920
|
}
|
|
950
921
|
removeOneByPk(pk) {
|
|
951
|
-
this.
|
|
922
|
+
const slot = this.slots.get(pk);
|
|
923
|
+
if (slot) slot.item = void 0;
|
|
924
|
+
this.slots.delete(pk);
|
|
952
925
|
}
|
|
953
926
|
removeManyByPks(pks) {
|
|
954
927
|
for (const pk of pks) {
|
|
955
|
-
this.
|
|
928
|
+
this.removeOneByPk(pk);
|
|
956
929
|
}
|
|
957
930
|
}
|
|
958
931
|
getOneByPk(pk) {
|
|
959
|
-
return this.
|
|
932
|
+
return this.slots.get(pk)?.item;
|
|
960
933
|
}
|
|
961
934
|
getManyByPks(pks) {
|
|
962
935
|
const result = [];
|
|
@@ -972,16 +945,23 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
972
945
|
return result;
|
|
973
946
|
}
|
|
974
947
|
getAll() {
|
|
975
|
-
|
|
948
|
+
const result = [];
|
|
949
|
+
for (const slot of this.slots.values()) {
|
|
950
|
+
if (slot.item !== void 0) result.push(slot.item);
|
|
951
|
+
}
|
|
952
|
+
return result;
|
|
976
953
|
}
|
|
977
954
|
countAll() {
|
|
978
|
-
return this.
|
|
955
|
+
return this.slots.size;
|
|
979
956
|
}
|
|
980
957
|
clear() {
|
|
981
|
-
this.
|
|
958
|
+
for (const slot of this.slots.values()) {
|
|
959
|
+
slot.item = void 0;
|
|
960
|
+
}
|
|
961
|
+
this.slots.clear();
|
|
982
962
|
}
|
|
983
963
|
getAllPks() {
|
|
984
|
-
return Array.from(this.
|
|
964
|
+
return Array.from(this.slots.keys());
|
|
985
965
|
}
|
|
986
966
|
destroy() {
|
|
987
967
|
this.clear();
|
|
@@ -997,7 +977,7 @@ var OIMEntityUpdaterFactory = class {
|
|
|
997
977
|
}
|
|
998
978
|
};
|
|
999
979
|
|
|
1000
|
-
// src/
|
|
980
|
+
// src/enums/EOIMCollectionEventType.ts
|
|
1001
981
|
var EOIMCollectionEventType = /* @__PURE__ */ ((EOIMCollectionEventType2) => {
|
|
1002
982
|
EOIMCollectionEventType2[EOIMCollectionEventType2["UPDATE"] = 0] = "UPDATE";
|
|
1003
983
|
return EOIMCollectionEventType2;
|
|
@@ -1017,19 +997,33 @@ var OIMCollection = class {
|
|
|
1017
997
|
getManyByPks(pks) {
|
|
1018
998
|
return this.store.getManyByPks(pks);
|
|
1019
999
|
}
|
|
1000
|
+
getSlotByPk(pk) {
|
|
1001
|
+
return this.store.getSlotByPk(pk);
|
|
1002
|
+
}
|
|
1003
|
+
getSlotsByPks(pks) {
|
|
1004
|
+
return this.store.getSlotsByPks(pks);
|
|
1005
|
+
}
|
|
1006
|
+
getAllSlots() {
|
|
1007
|
+
return this.store.getAllSlots();
|
|
1008
|
+
}
|
|
1020
1009
|
upsertOneByPk(pk, entity) {
|
|
1021
|
-
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1010
|
+
const slot = this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1022
1011
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1012
|
+
return slot;
|
|
1023
1013
|
}
|
|
1024
1014
|
upsertOne(entity) {
|
|
1025
|
-
const
|
|
1026
|
-
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1015
|
+
const slot = this.upsertOneWithoutNotifications(entity);
|
|
1016
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [slot.pk] });
|
|
1017
|
+
return slot;
|
|
1027
1018
|
}
|
|
1028
1019
|
upsertMany(entities) {
|
|
1029
|
-
|
|
1020
|
+
if (entities.length === 0) return [];
|
|
1021
|
+
const slots = entities.map(
|
|
1030
1022
|
(entity) => this.upsertOneWithoutNotifications(entity)
|
|
1031
1023
|
);
|
|
1024
|
+
const pks = slots.map((slot) => slot.pk);
|
|
1032
1025
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1026
|
+
return slots;
|
|
1033
1027
|
}
|
|
1034
1028
|
removeOne(entity) {
|
|
1035
1029
|
const pk = this.selectPk(entity);
|
|
@@ -1037,6 +1031,7 @@ var OIMCollection = class {
|
|
|
1037
1031
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1038
1032
|
}
|
|
1039
1033
|
removeMany(entities) {
|
|
1034
|
+
if (entities.length === 0) return;
|
|
1040
1035
|
const pks = entities.map(this.selectPk);
|
|
1041
1036
|
this.store.removeManyByPks(pks);
|
|
1042
1037
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
@@ -1046,6 +1041,7 @@ var OIMCollection = class {
|
|
|
1046
1041
|
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1047
1042
|
}
|
|
1048
1043
|
removeManyByPks(pks) {
|
|
1044
|
+
if (pks.length === 0) return;
|
|
1049
1045
|
this.store.removeManyByPks(pks);
|
|
1050
1046
|
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1051
1047
|
}
|
|
@@ -1064,8 +1060,7 @@ var OIMCollection = class {
|
|
|
1064
1060
|
}
|
|
1065
1061
|
upsertOneWithoutNotifications(entity) {
|
|
1066
1062
|
const pk = this.selectPk(entity);
|
|
1067
|
-
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1068
|
-
return pk;
|
|
1063
|
+
return this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1069
1064
|
}
|
|
1070
1065
|
upsertOneWithoutNotificationsByPk(pk, entity) {
|
|
1071
1066
|
if (!pk) {
|
|
@@ -1075,12 +1070,12 @@ var OIMCollection = class {
|
|
|
1075
1070
|
}
|
|
1076
1071
|
const existingEntity = this.store.getOneByPk(pk);
|
|
1077
1072
|
if (existingEntity) {
|
|
1078
|
-
this.store.setOneByPk(
|
|
1073
|
+
return this.store.setOneByPk(
|
|
1079
1074
|
pk,
|
|
1080
1075
|
this.updateEntity(entity, existingEntity)
|
|
1081
1076
|
);
|
|
1082
1077
|
} else {
|
|
1083
|
-
this.store.setOneByPk(pk, entity);
|
|
1078
|
+
return this.store.setOneByPk(pk, entity);
|
|
1084
1079
|
}
|
|
1085
1080
|
}
|
|
1086
1081
|
destroy() {
|
|
@@ -1141,46 +1136,61 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1141
1136
|
};
|
|
1142
1137
|
}
|
|
1143
1138
|
upsertOneByPk(pk, entity) {
|
|
1144
|
-
this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1139
|
+
const slot = this.upsertOneWithoutNotificationsByPk(pk, entity);
|
|
1140
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1145
1141
|
this.updateEmitter.markUpdatedKey(pk);
|
|
1146
1142
|
this.trackAnyUpdatePk(pk);
|
|
1143
|
+
return slot;
|
|
1147
1144
|
}
|
|
1148
1145
|
upsertOne(entity) {
|
|
1149
|
-
const
|
|
1150
|
-
this.
|
|
1151
|
-
this.
|
|
1146
|
+
const slot = this.upsertOneWithoutNotifications(entity);
|
|
1147
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [slot.pk] });
|
|
1148
|
+
this.updateEmitter.markUpdatedKey(slot.pk);
|
|
1149
|
+
this.trackAnyUpdatePk(slot.pk);
|
|
1150
|
+
return slot;
|
|
1152
1151
|
}
|
|
1153
1152
|
upsertMany(entities) {
|
|
1154
|
-
|
|
1153
|
+
if (entities.length === 0) return [];
|
|
1154
|
+
const slots = entities.map(
|
|
1155
1155
|
(entity) => this.upsertOneWithoutNotifications(entity)
|
|
1156
1156
|
);
|
|
1157
|
+
const pks = slots.map((slot) => slot.pk);
|
|
1158
|
+
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1157
1159
|
this.updateEmitter.markUpdatedKeys(pks);
|
|
1158
1160
|
this.trackAnyUpdatePks(pks);
|
|
1161
|
+
return slots;
|
|
1159
1162
|
}
|
|
1160
1163
|
removeOne(entity) {
|
|
1161
1164
|
const pk = this.selectPk(entity);
|
|
1162
1165
|
this.store.removeOneByPk(pk);
|
|
1166
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1163
1167
|
this.updateEmitter.markUpdatedKey(pk);
|
|
1164
1168
|
this.trackAnyUpdatePk(pk);
|
|
1165
1169
|
}
|
|
1166
1170
|
removeMany(entities) {
|
|
1171
|
+
if (entities.length === 0) return;
|
|
1167
1172
|
const pks = entities.map(this.selectPk);
|
|
1168
1173
|
this.store.removeManyByPks(pks);
|
|
1174
|
+
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1169
1175
|
this.updateEmitter.markUpdatedKeys(pks);
|
|
1170
1176
|
this.trackAnyUpdatePks(pks);
|
|
1171
1177
|
}
|
|
1172
1178
|
removeOneByPk(pk) {
|
|
1173
1179
|
this.store.removeOneByPk(pk);
|
|
1180
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [pk] });
|
|
1174
1181
|
this.updateEmitter.markUpdatedKey(pk);
|
|
1175
1182
|
this.trackAnyUpdatePk(pk);
|
|
1176
1183
|
}
|
|
1177
1184
|
removeManyByPks(pks) {
|
|
1185
|
+
if (pks.length === 0) return;
|
|
1178
1186
|
this.store.removeManyByPks(pks);
|
|
1187
|
+
this.emitter.emit(0 /* UPDATE */, { pks });
|
|
1179
1188
|
this.updateEmitter.markUpdatedKeys(pks);
|
|
1180
1189
|
this.trackAnyUpdatePks(pks);
|
|
1181
1190
|
}
|
|
1182
1191
|
clear() {
|
|
1183
1192
|
this.store.clear();
|
|
1193
|
+
this.emitter.emit(0 /* UPDATE */, { pks: [] });
|
|
1184
1194
|
this.updateEmitter.markAllUpdated();
|
|
1185
1195
|
this.trackAnyUpdateClear();
|
|
1186
1196
|
}
|
|
@@ -1218,193 +1228,347 @@ var OIMReactiveCollection = class extends OIMCollection {
|
|
|
1218
1228
|
}
|
|
1219
1229
|
};
|
|
1220
1230
|
|
|
1221
|
-
// src/
|
|
1222
|
-
var
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
get(key) {
|
|
1237
|
-
return this.properties[key];
|
|
1238
|
-
}
|
|
1239
|
-
getAll() {
|
|
1240
|
-
return { ...this.properties };
|
|
1231
|
+
// src/modules/wrapper/index/OIMIndexManualOrderedArrayBased.ts
|
|
1232
|
+
var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
1233
|
+
clear(key) {
|
|
1234
|
+
if (key === void 0) {
|
|
1235
|
+
const keys = this.getKeys();
|
|
1236
|
+
if (keys.length > 0) {
|
|
1237
|
+
this.store.clear();
|
|
1238
|
+
this.emitUpdate(Array.from(keys));
|
|
1239
|
+
}
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
if (this.store.getOneByKey(key) !== void 0) {
|
|
1243
|
+
this.store.removeOneByKey(key);
|
|
1244
|
+
this.emitUpdate([key]);
|
|
1245
|
+
}
|
|
1241
1246
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1247
|
+
pushSlot(key, slot) {
|
|
1248
|
+
const list = this.getOrCreateList(key);
|
|
1249
|
+
const index = list.length;
|
|
1250
|
+
list.push(slot);
|
|
1251
|
+
this.emitUpdate([key]);
|
|
1252
|
+
return index;
|
|
1244
1253
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1254
|
+
insertSlotAt(key, index, slot) {
|
|
1255
|
+
const list = this.getOrCreateList(key);
|
|
1256
|
+
const safeIndex = Math.max(0, Math.min(index, list.length));
|
|
1257
|
+
list.splice(safeIndex, 0, slot);
|
|
1258
|
+
this.emitUpdate([key]);
|
|
1259
|
+
return safeIndex;
|
|
1247
1260
|
}
|
|
1248
|
-
|
|
1249
|
-
|
|
1261
|
+
removeAt(key, index) {
|
|
1262
|
+
const list = this.store.getOneByKey(key);
|
|
1263
|
+
if (!list) return void 0;
|
|
1264
|
+
if (index < 0 || index >= list.length) return void 0;
|
|
1265
|
+
const [removed] = list.splice(index, 1);
|
|
1266
|
+
if (list.length === 0) {
|
|
1267
|
+
this.store.removeOneByKey(key);
|
|
1268
|
+
}
|
|
1269
|
+
this.emitUpdate([key]);
|
|
1270
|
+
return removed;
|
|
1250
1271
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1272
|
+
move(key, fromIndex, toIndex) {
|
|
1273
|
+
const list = this.store.getOneByKey(key);
|
|
1274
|
+
if (!list) return void 0;
|
|
1275
|
+
if (fromIndex < 0 || fromIndex >= list.length) return void 0;
|
|
1276
|
+
if (toIndex < 0 || toIndex >= list.length) return void 0;
|
|
1277
|
+
if (fromIndex === toIndex) return list[fromIndex];
|
|
1278
|
+
const [slot] = list.splice(fromIndex, 1);
|
|
1279
|
+
if (slot === void 0) return void 0;
|
|
1280
|
+
list.splice(toIndex, 0, slot);
|
|
1281
|
+
this.emitUpdate([key]);
|
|
1282
|
+
return slot;
|
|
1253
1283
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1284
|
+
resetSlots(key, slots) {
|
|
1285
|
+
if (slots.length === 0) {
|
|
1286
|
+
if (this.store.getOneByKey(key) !== void 0) {
|
|
1287
|
+
this.store.removeOneByKey(key);
|
|
1288
|
+
this.emitUpdate([key]);
|
|
1289
|
+
}
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
this.store.setOneByKey(key, slots.slice());
|
|
1293
|
+
this.emitUpdate([key]);
|
|
1256
1294
|
}
|
|
1257
|
-
|
|
1258
|
-
this.
|
|
1295
|
+
getOrCreateList(key) {
|
|
1296
|
+
let list = this.store.getOneByKey(key);
|
|
1297
|
+
if (!list) {
|
|
1298
|
+
list = [];
|
|
1299
|
+
this.store.setOneByKey(key, list);
|
|
1300
|
+
}
|
|
1301
|
+
return list;
|
|
1259
1302
|
}
|
|
1260
1303
|
};
|
|
1261
1304
|
|
|
1262
|
-
// src/
|
|
1263
|
-
var
|
|
1264
|
-
EOIMObjectEventType2[EOIMObjectEventType2["UPDATE"] = 0] = "UPDATE";
|
|
1265
|
-
return EOIMObjectEventType2;
|
|
1266
|
-
})(EOIMObjectEventType || {});
|
|
1267
|
-
|
|
1268
|
-
// src/core/OIMObject.ts
|
|
1269
|
-
var OIMObject = class {
|
|
1305
|
+
// src/modules/wrapper/index/OIMCollectionIndexManualOrderedArrayBased.ts
|
|
1306
|
+
var OIMCollectionIndexManualOrderedArrayBased = class extends OIMIndexManualOrderedArrayBased {
|
|
1270
1307
|
constructor(opts) {
|
|
1271
|
-
|
|
1272
|
-
this.
|
|
1273
|
-
}
|
|
1274
|
-
setProperty(key, value) {
|
|
1275
|
-
this.store.setProperty(key, value);
|
|
1276
|
-
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
1277
|
-
}
|
|
1278
|
-
merge(draft) {
|
|
1279
|
-
this.store.merge(draft);
|
|
1280
|
-
this.emitter.emit(0 /* UPDATE */, {
|
|
1281
|
-
keys: Object.keys(draft)
|
|
1282
|
-
});
|
|
1283
|
-
}
|
|
1284
|
-
delete(key) {
|
|
1285
|
-
this.store.delete(key);
|
|
1286
|
-
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
1308
|
+
super();
|
|
1309
|
+
this.resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getSlotByPk(pk) : opts.resolveSlot;
|
|
1287
1310
|
}
|
|
1288
|
-
|
|
1289
|
-
return this.
|
|
1311
|
+
push(key, pk) {
|
|
1312
|
+
return this.pushSlot(key, this.resolveRequiredSlot(pk));
|
|
1290
1313
|
}
|
|
1291
|
-
|
|
1292
|
-
return this.
|
|
1314
|
+
insertAt(key, index, pk) {
|
|
1315
|
+
return this.insertSlotAt(key, index, this.resolveRequiredSlot(pk));
|
|
1293
1316
|
}
|
|
1294
|
-
|
|
1295
|
-
this.
|
|
1296
|
-
this.emitter.emit(0 /* UPDATE */, { keys: [] });
|
|
1317
|
+
reset(key, pks) {
|
|
1318
|
+
this.resetSlots(key, this.resolveSlots(pks));
|
|
1297
1319
|
}
|
|
1298
|
-
|
|
1299
|
-
return
|
|
1320
|
+
getEntitiesByKey(key) {
|
|
1321
|
+
return super.getEntitiesByKey(key);
|
|
1300
1322
|
}
|
|
1301
|
-
keys
|
|
1302
|
-
return
|
|
1323
|
+
getEntitiesByKeys(keys) {
|
|
1324
|
+
return super.getEntitiesByKeys(keys);
|
|
1303
1325
|
}
|
|
1304
|
-
|
|
1305
|
-
return this.
|
|
1326
|
+
resolvePk(pk) {
|
|
1327
|
+
return this.resolveRequiredSlot(pk);
|
|
1306
1328
|
}
|
|
1307
|
-
|
|
1308
|
-
|
|
1329
|
+
resolveSlots(pks) {
|
|
1330
|
+
const slots = [];
|
|
1331
|
+
slots.length = pks.length;
|
|
1332
|
+
for (let i = 0; i < pks.length; i++) {
|
|
1333
|
+
slots[i] = this.resolveRequiredSlot(pks[i]);
|
|
1334
|
+
}
|
|
1335
|
+
return slots;
|
|
1309
1336
|
}
|
|
1310
|
-
|
|
1311
|
-
this.
|
|
1312
|
-
|
|
1337
|
+
resolveRequiredSlot(pk) {
|
|
1338
|
+
const slot = this.resolveSlot(pk);
|
|
1339
|
+
if (!slot) {
|
|
1340
|
+
throw new Error(
|
|
1341
|
+
`[OIMCollectionIndexManualOrderedArrayBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
return slot;
|
|
1313
1345
|
}
|
|
1314
1346
|
};
|
|
1315
1347
|
|
|
1316
|
-
// src/
|
|
1317
|
-
var
|
|
1318
|
-
constructor(queue,
|
|
1319
|
-
|
|
1320
|
-
this.
|
|
1321
|
-
this.
|
|
1322
|
-
this.
|
|
1323
|
-
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1348
|
+
// src/modules/wrapper/index/OIMOrderedListCommandStream.ts
|
|
1349
|
+
var OIMOrderedListCommandStream = class {
|
|
1350
|
+
constructor(queue, index) {
|
|
1351
|
+
this.isInWrite = false;
|
|
1352
|
+
this.commandsByKey = /* @__PURE__ */ new Map();
|
|
1353
|
+
this.onAfterFlush = () => {
|
|
1354
|
+
this.commandsByKey.clear();
|
|
1355
|
+
};
|
|
1356
|
+
this.onIndexUpdate = (payload) => {
|
|
1357
|
+
if (this.isInWrite) return;
|
|
1358
|
+
if (payload.keys.length === 0) return;
|
|
1359
|
+
for (let i = 0; i < payload.keys.length; i++) {
|
|
1360
|
+
const key = payload.keys[i];
|
|
1361
|
+
this.appendSetCommand(key, this.getSlotsByKey(key));
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
1365
|
+
queue,
|
|
1366
|
+
"after_flush"
|
|
1367
|
+
);
|
|
1368
|
+
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
1369
|
+
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
1370
|
+
0 /* AFTER_FLUSH */,
|
|
1371
|
+
this.onAfterFlush
|
|
1372
|
+
);
|
|
1373
|
+
this.unsubscribeFromIndexEmitter = this.index.emitter.on(
|
|
1374
|
+
0 /* UPDATE */,
|
|
1375
|
+
this.onIndexUpdate
|
|
1376
|
+
);
|
|
1327
1377
|
}
|
|
1328
|
-
|
|
1329
|
-
return this.
|
|
1378
|
+
getPksByKey(key) {
|
|
1379
|
+
return this.index.getPksByKey(key);
|
|
1330
1380
|
}
|
|
1331
|
-
|
|
1332
|
-
this.
|
|
1381
|
+
getSlotsByKey(key) {
|
|
1382
|
+
return this.index.getSlotsByKey(
|
|
1383
|
+
key
|
|
1384
|
+
);
|
|
1333
1385
|
}
|
|
1334
|
-
|
|
1335
|
-
this.
|
|
1386
|
+
getEntitiesByKey(key) {
|
|
1387
|
+
return this.index.getEntitiesByKey(key);
|
|
1336
1388
|
}
|
|
1337
|
-
|
|
1338
|
-
return this.
|
|
1389
|
+
hasKey(key) {
|
|
1390
|
+
return this.index.hasKey(key);
|
|
1339
1391
|
}
|
|
1340
|
-
|
|
1341
|
-
return this.
|
|
1392
|
+
getKeys() {
|
|
1393
|
+
return this.index.getKeys();
|
|
1342
1394
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1395
|
+
pushSlot(key, slot) {
|
|
1396
|
+
this.withWrite(() => {
|
|
1397
|
+
const index = this.index.pushSlot(key, slot);
|
|
1398
|
+
this.appendCommand(key, {
|
|
1399
|
+
type: "insert",
|
|
1400
|
+
pk: slot.pk,
|
|
1401
|
+
slot,
|
|
1402
|
+
index
|
|
1403
|
+
});
|
|
1404
|
+
});
|
|
1345
1405
|
}
|
|
1346
|
-
|
|
1347
|
-
this.
|
|
1348
|
-
|
|
1406
|
+
insertSlotAt(key, index, slot) {
|
|
1407
|
+
this.withWrite(() => {
|
|
1408
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1409
|
+
this.appendCommand(key, {
|
|
1410
|
+
type: "insert",
|
|
1411
|
+
pk: slot.pk,
|
|
1412
|
+
slot,
|
|
1413
|
+
index: safeIndex
|
|
1414
|
+
});
|
|
1415
|
+
});
|
|
1349
1416
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1417
|
+
removeAt(key, index) {
|
|
1418
|
+
this.withWrite(() => {
|
|
1419
|
+
const slot = this.index.removeAt(key, index);
|
|
1420
|
+
if (slot === void 0) return;
|
|
1421
|
+
this.appendCommand(key, {
|
|
1422
|
+
type: "remove",
|
|
1423
|
+
pk: slot.pk,
|
|
1424
|
+
slot,
|
|
1425
|
+
index
|
|
1426
|
+
});
|
|
1427
|
+
});
|
|
1356
1428
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1429
|
+
move(key, fromIndex, toIndex) {
|
|
1430
|
+
this.withWrite(() => {
|
|
1431
|
+
const slot = this.index.move(key, fromIndex, toIndex);
|
|
1432
|
+
if (slot === void 0) return;
|
|
1433
|
+
this.appendCommand(key, {
|
|
1434
|
+
type: "move",
|
|
1435
|
+
pk: slot.pk,
|
|
1436
|
+
slot,
|
|
1437
|
+
fromIndex,
|
|
1438
|
+
toIndex
|
|
1439
|
+
});
|
|
1440
|
+
});
|
|
1366
1441
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1442
|
+
setSlots(key, slots) {
|
|
1443
|
+
this.withWrite(() => {
|
|
1444
|
+
this.index.resetSlots(key, slots);
|
|
1445
|
+
this.appendSetCommand(key, slots);
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
getBufferedCommands(key) {
|
|
1449
|
+
return this.commandsByKey.get(key) ?? [];
|
|
1450
|
+
}
|
|
1451
|
+
consumeCommands(key) {
|
|
1452
|
+
const cmds = this.commandsByKey.get(key);
|
|
1453
|
+
if (!cmds || cmds.length === 0) return [];
|
|
1454
|
+
return cmds.slice();
|
|
1455
|
+
}
|
|
1456
|
+
clear(key) {
|
|
1457
|
+
if (key === void 0) {
|
|
1458
|
+
this.index.destroy();
|
|
1459
|
+
this.commandsByKey.clear();
|
|
1460
|
+
return;
|
|
1376
1461
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1462
|
+
this.index.clear(key);
|
|
1463
|
+
this.commandsByKey.delete(key);
|
|
1464
|
+
}
|
|
1465
|
+
destroy() {
|
|
1466
|
+
this.commandsEventEmitter.destroy();
|
|
1467
|
+
this.unsubscribeAfterFlush();
|
|
1468
|
+
this.unsubscribeFromIndexEmitter();
|
|
1469
|
+
this.clear();
|
|
1470
|
+
}
|
|
1471
|
+
withWrite(fn) {
|
|
1472
|
+
if (this.isInWrite) {
|
|
1473
|
+
fn();
|
|
1474
|
+
return;
|
|
1383
1475
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1476
|
+
this.isInWrite = true;
|
|
1477
|
+
try {
|
|
1478
|
+
fn();
|
|
1479
|
+
} finally {
|
|
1480
|
+
this.isInWrite = false;
|
|
1387
1481
|
}
|
|
1388
1482
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
const pksSet = this.store.getOneByKey(key);
|
|
1395
|
-
if (!pksSet) return;
|
|
1396
|
-
let hasChanges = false;
|
|
1397
|
-
for (const pk of pks) {
|
|
1398
|
-
if (pksSet.delete(pk)) {
|
|
1399
|
-
hasChanges = true;
|
|
1400
|
-
}
|
|
1483
|
+
appendCommand(key, cmd) {
|
|
1484
|
+
let cmds = this.commandsByKey.get(key);
|
|
1485
|
+
if (!cmds) {
|
|
1486
|
+
cmds = [];
|
|
1487
|
+
this.commandsByKey.set(key, cmds);
|
|
1401
1488
|
}
|
|
1402
|
-
if (
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
} else if (
|
|
1406
|
-
this.
|
|
1489
|
+
if (cmd.type === "set") {
|
|
1490
|
+
cmds.length = 0;
|
|
1491
|
+
cmds.push(cmd);
|
|
1492
|
+
} else if (cmds.length > 0 && cmds[0].type === "set") {
|
|
1493
|
+
const slots = this.getSlotsByKey(key);
|
|
1494
|
+
cmds[0] = this.createSetCommand(slots);
|
|
1495
|
+
} else {
|
|
1496
|
+
cmds.push(cmd);
|
|
1407
1497
|
}
|
|
1498
|
+
this.commandsEventEmitter.markUpdatedKeys([key]);
|
|
1499
|
+
}
|
|
1500
|
+
appendSetCommand(key, slots) {
|
|
1501
|
+
this.appendCommand(key, this.createSetCommand(slots));
|
|
1502
|
+
}
|
|
1503
|
+
createSetCommand(slots) {
|
|
1504
|
+
return {
|
|
1505
|
+
type: "set",
|
|
1506
|
+
pks: slots.map((slot) => slot.pk),
|
|
1507
|
+
slots
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
|
|
1512
|
+
// src/modules/wrapper/index/OIMCollectionOrderedListCommandStream.ts
|
|
1513
|
+
var OIMCollectionOrderedListCommandStream = class extends OIMOrderedListCommandStream {
|
|
1514
|
+
constructor(queue, opts) {
|
|
1515
|
+
const index = opts.index ?? new OIMCollectionIndexManualOrderedArrayBased(
|
|
1516
|
+
opts.collection !== void 0 ? { collection: opts.collection } : { resolveSlot: opts.resolveSlot }
|
|
1517
|
+
);
|
|
1518
|
+
super(queue, index);
|
|
1519
|
+
this.index = index;
|
|
1520
|
+
}
|
|
1521
|
+
push(key, pk) {
|
|
1522
|
+
this.withWrite(() => {
|
|
1523
|
+
const slot = this.resolvePk(pk);
|
|
1524
|
+
const index = this.index.pushSlot(key, slot);
|
|
1525
|
+
this.appendCommand(key, {
|
|
1526
|
+
type: "insert",
|
|
1527
|
+
pk,
|
|
1528
|
+
slot,
|
|
1529
|
+
index
|
|
1530
|
+
});
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
insertAt(key, index, pk) {
|
|
1534
|
+
this.withWrite(() => {
|
|
1535
|
+
const slot = this.resolvePk(pk);
|
|
1536
|
+
const safeIndex = this.index.insertSlotAt(key, index, slot);
|
|
1537
|
+
this.appendCommand(key, {
|
|
1538
|
+
type: "insert",
|
|
1539
|
+
pk,
|
|
1540
|
+
slot,
|
|
1541
|
+
index: safeIndex
|
|
1542
|
+
});
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
set(key, pks) {
|
|
1546
|
+
this.withWrite(() => {
|
|
1547
|
+
const slots = pks.map((pk) => this.resolvePk(pk));
|
|
1548
|
+
this.index.resetSlots(key, slots);
|
|
1549
|
+
this.appendSetCommand(key, slots);
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
getSlotsByKey(key) {
|
|
1553
|
+
return this.index.getSlotsByKey(
|
|
1554
|
+
key
|
|
1555
|
+
);
|
|
1556
|
+
}
|
|
1557
|
+
getEntitiesByKey(key) {
|
|
1558
|
+
return this.index.getEntitiesByKey(key);
|
|
1559
|
+
}
|
|
1560
|
+
resolvePk(pk) {
|
|
1561
|
+
return this.index.resolvePk(pk);
|
|
1562
|
+
}
|
|
1563
|
+
};
|
|
1564
|
+
|
|
1565
|
+
// src/core/OIMIndexManualArrayBased.ts
|
|
1566
|
+
var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
1567
|
+
constructor(options = {}) {
|
|
1568
|
+
super(options);
|
|
1569
|
+
}
|
|
1570
|
+
setSlots(key, slots) {
|
|
1571
|
+
const hasChanges = this.setSlotsWithComparison(key, slots);
|
|
1408
1572
|
if (hasChanges) {
|
|
1409
1573
|
this.emitUpdateOne(key);
|
|
1410
1574
|
}
|
|
@@ -1428,8 +1592,8 @@ var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
|
1428
1592
|
}
|
|
1429
1593
|
};
|
|
1430
1594
|
|
|
1431
|
-
// src/core/
|
|
1432
|
-
var
|
|
1595
|
+
// src/core/OIMReactiveIndexManualArrayBased.ts
|
|
1596
|
+
var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
1433
1597
|
constructor(updateEmitter, opts) {
|
|
1434
1598
|
super(opts);
|
|
1435
1599
|
this.updateEmitter = updateEmitter;
|
|
@@ -1441,83 +1605,93 @@ var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
|
1441
1605
|
this.updateEmitter.markUpdatedKey(key);
|
|
1442
1606
|
}
|
|
1443
1607
|
};
|
|
1444
|
-
var
|
|
1608
|
+
var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased {
|
|
1445
1609
|
constructor(queue, opts) {
|
|
1446
1610
|
super(queue, (updateEmitter) => {
|
|
1447
|
-
return new
|
|
1611
|
+
return new OIMIndexManualArrayBasedReactive(
|
|
1448
1612
|
updateEmitter,
|
|
1449
1613
|
opts?.indexOptions
|
|
1450
1614
|
);
|
|
1451
1615
|
});
|
|
1452
1616
|
}
|
|
1453
|
-
|
|
1454
|
-
this.index.
|
|
1455
|
-
}
|
|
1456
|
-
addPks(key, pks) {
|
|
1457
|
-
this.index.addPks(key, pks);
|
|
1458
|
-
}
|
|
1459
|
-
removePks(key, pks) {
|
|
1460
|
-
this.index.removePks(key, pks);
|
|
1617
|
+
setSlots(key, slots) {
|
|
1618
|
+
this.index.setSlots(key, slots);
|
|
1461
1619
|
}
|
|
1462
1620
|
clear(key) {
|
|
1463
1621
|
this.index.clear(key);
|
|
1464
1622
|
}
|
|
1465
1623
|
};
|
|
1466
1624
|
|
|
1467
|
-
// src/core/
|
|
1468
|
-
var
|
|
1469
|
-
constructor(
|
|
1470
|
-
|
|
1625
|
+
// src/core/OIMReactiveCollectionIndexManualArrayBased.ts
|
|
1626
|
+
var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexManualArrayBased {
|
|
1627
|
+
constructor(queue, opts) {
|
|
1628
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getSlotByPk(pk) : opts.resolveSlot;
|
|
1629
|
+
super(queue, {
|
|
1630
|
+
indexOptions: opts.indexOptions
|
|
1631
|
+
});
|
|
1632
|
+
this.resolveSlot = resolveSlot;
|
|
1471
1633
|
}
|
|
1472
|
-
/**
|
|
1473
|
-
* Set primary keys for a specific index key, replacing any existing values.
|
|
1474
|
-
* Uses optional comparator to skip updates if PKs haven't actually changed.
|
|
1475
|
-
*/
|
|
1476
1634
|
setPks(key, pks) {
|
|
1477
|
-
|
|
1478
|
-
if (hasChanges) {
|
|
1479
|
-
this.emitUpdateOne(key);
|
|
1480
|
-
}
|
|
1635
|
+
this.setSlots(key, this.resolveSlots(pks));
|
|
1481
1636
|
}
|
|
1482
|
-
/**
|
|
1483
|
-
* Add primary keys to a specific index key
|
|
1484
|
-
*/
|
|
1485
1637
|
addPks(key, pks) {
|
|
1486
1638
|
if (pks.length === 0) return;
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
this.store.setOneByKey(key, pksArray);
|
|
1491
|
-
}
|
|
1492
|
-
const pksSet = new Set(pksArray);
|
|
1639
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1640
|
+
const existingPks = new Set(existingSlots.map((slot) => slot.pk));
|
|
1641
|
+
const nextSlots = existingSlots.slice();
|
|
1493
1642
|
let hasChanges = false;
|
|
1494
1643
|
for (const pk of pks) {
|
|
1495
|
-
if (
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
}
|
|
1500
|
-
if (hasChanges) {
|
|
1501
|
-
this.store.setOneByKey(key, Array.from(pksSet));
|
|
1502
|
-
this.emitUpdateOne(key);
|
|
1644
|
+
if (existingPks.has(pk)) continue;
|
|
1645
|
+
nextSlots.push(this.resolveRequiredSlot(pk));
|
|
1646
|
+
existingPks.add(pk);
|
|
1647
|
+
hasChanges = true;
|
|
1503
1648
|
}
|
|
1649
|
+
if (hasChanges) this.setSlots(key, nextSlots);
|
|
1504
1650
|
}
|
|
1505
|
-
/**
|
|
1506
|
-
* Remove primary keys from a specific index key
|
|
1507
|
-
*/
|
|
1508
1651
|
removePks(key, pks) {
|
|
1509
1652
|
if (pks.length === 0) return;
|
|
1510
|
-
const
|
|
1511
|
-
|
|
1512
|
-
const
|
|
1513
|
-
|
|
1514
|
-
|
|
1653
|
+
const pksToRemove = new Set(pks);
|
|
1654
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1655
|
+
const nextSlots = existingSlots.filter(
|
|
1656
|
+
(slot) => !pksToRemove.has(slot.pk)
|
|
1657
|
+
);
|
|
1658
|
+
if (nextSlots.length === existingSlots.length) return;
|
|
1659
|
+
if (nextSlots.length === 0) this.clear(key);
|
|
1660
|
+
else this.setSlots(key, nextSlots);
|
|
1661
|
+
}
|
|
1662
|
+
getEntitiesByKey(key) {
|
|
1663
|
+
return super.getEntitiesByKey(key);
|
|
1664
|
+
}
|
|
1665
|
+
getEntitiesByKeys(keys) {
|
|
1666
|
+
return super.getEntitiesByKeys(keys);
|
|
1667
|
+
}
|
|
1668
|
+
resolveSlots(pks) {
|
|
1669
|
+
const slots = [];
|
|
1670
|
+
slots.length = pks.length;
|
|
1671
|
+
for (let i = 0; i < pks.length; i++) {
|
|
1672
|
+
slots[i] = this.resolveRequiredSlot(pks[i]);
|
|
1673
|
+
}
|
|
1674
|
+
return slots;
|
|
1675
|
+
}
|
|
1676
|
+
resolveRequiredSlot(pk) {
|
|
1677
|
+
const slot = this.resolveSlot(pk);
|
|
1678
|
+
if (!slot) {
|
|
1679
|
+
throw new Error(
|
|
1680
|
+
`[OIMReactiveCollectionIndexManualArrayBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1681
|
+
);
|
|
1682
|
+
}
|
|
1683
|
+
return slot;
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
// src/core/OIMIndexManualSetBased.ts
|
|
1688
|
+
var OIMIndexManualSetBased = class extends OIMIndexSetBased {
|
|
1689
|
+
constructor(options = {}) {
|
|
1690
|
+
super(options);
|
|
1691
|
+
}
|
|
1692
|
+
setSlots(key, slots) {
|
|
1693
|
+
const hasChanges = this.setSlotsWithComparison(key, new Set(slots));
|
|
1515
1694
|
if (hasChanges) {
|
|
1516
|
-
if (filtered.length === 0) {
|
|
1517
|
-
this.store.removeOneByKey(key);
|
|
1518
|
-
} else {
|
|
1519
|
-
this.store.setOneByKey(key, filtered);
|
|
1520
|
-
}
|
|
1521
1695
|
this.emitUpdateOne(key);
|
|
1522
1696
|
}
|
|
1523
1697
|
}
|
|
@@ -1540,8 +1714,8 @@ var OIMIndexManualArrayBased = class extends OIMIndexArrayBased {
|
|
|
1540
1714
|
}
|
|
1541
1715
|
};
|
|
1542
1716
|
|
|
1543
|
-
// src/core/
|
|
1544
|
-
var
|
|
1717
|
+
// src/core/OIMReactiveIndexManualSetBased.ts
|
|
1718
|
+
var OIMIndexManualSetBasedReactive = class extends OIMIndexManualSetBased {
|
|
1545
1719
|
constructor(updateEmitter, opts) {
|
|
1546
1720
|
super(opts);
|
|
1547
1721
|
this.updateEmitter = updateEmitter;
|
|
@@ -1553,303 +1727,1256 @@ var OIMIndexManualArrayBasedReactive = class extends OIMIndexManualArrayBased {
|
|
|
1553
1727
|
this.updateEmitter.markUpdatedKey(key);
|
|
1554
1728
|
}
|
|
1555
1729
|
};
|
|
1556
|
-
var
|
|
1730
|
+
var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
1557
1731
|
constructor(queue, opts) {
|
|
1558
1732
|
super(queue, (updateEmitter) => {
|
|
1559
|
-
return new
|
|
1733
|
+
return new OIMIndexManualSetBasedReactive(
|
|
1560
1734
|
updateEmitter,
|
|
1561
1735
|
opts?.indexOptions
|
|
1562
1736
|
);
|
|
1563
1737
|
});
|
|
1564
1738
|
}
|
|
1565
|
-
|
|
1566
|
-
this.index.
|
|
1567
|
-
}
|
|
1568
|
-
addPks(key, pks) {
|
|
1569
|
-
this.index.addPks(key, pks);
|
|
1570
|
-
}
|
|
1571
|
-
removePks(key, pks) {
|
|
1572
|
-
this.index.removePks(key, pks);
|
|
1739
|
+
setSlots(key, slots) {
|
|
1740
|
+
this.index.setSlots(key, slots);
|
|
1573
1741
|
}
|
|
1574
1742
|
clear(key) {
|
|
1575
1743
|
this.index.clear(key);
|
|
1576
1744
|
}
|
|
1577
1745
|
};
|
|
1578
1746
|
|
|
1579
|
-
// src/core/
|
|
1580
|
-
var
|
|
1747
|
+
// src/core/OIMReactiveCollectionIndexManualSetBased.ts
|
|
1748
|
+
var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexManualSetBased {
|
|
1581
1749
|
constructor(queue, opts) {
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
};
|
|
1586
|
-
|
|
1587
|
-
// src/core/OIMObjectStoreMapDriven.ts
|
|
1588
|
-
var OIMObjectStoreMapDriven = class extends OIMObjectStore {
|
|
1589
|
-
constructor() {
|
|
1590
|
-
super(...arguments);
|
|
1591
|
-
this.properties = /* @__PURE__ */ new Map();
|
|
1750
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getSlotByPk(pk) : opts.resolveSlot;
|
|
1751
|
+
super(queue, {
|
|
1752
|
+
indexOptions: opts.indexOptions
|
|
1753
|
+
});
|
|
1754
|
+
this.resolveSlot = resolveSlot;
|
|
1592
1755
|
}
|
|
1593
|
-
|
|
1594
|
-
this.
|
|
1756
|
+
setPks(key, pks) {
|
|
1757
|
+
this.setSlots(key, this.resolveSlots(pks));
|
|
1595
1758
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1759
|
+
addPks(key, pks) {
|
|
1760
|
+
if (pks.length === 0) return;
|
|
1761
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1762
|
+
const existingPks = this.index.getPksByKey(key);
|
|
1763
|
+
const nextSlots = new Set(existingSlots);
|
|
1764
|
+
let hasChanges = false;
|
|
1765
|
+
for (const pk of pks) {
|
|
1766
|
+
if (existingPks.has(pk)) continue;
|
|
1767
|
+
const slot = this.resolveRequiredSlot(pk);
|
|
1768
|
+
nextSlots.add(slot);
|
|
1769
|
+
existingPks.add(pk);
|
|
1770
|
+
hasChanges = true;
|
|
1603
1771
|
}
|
|
1772
|
+
if (hasChanges) this.setSlots(key, nextSlots);
|
|
1604
1773
|
}
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
return
|
|
1774
|
+
removePks(key, pks) {
|
|
1775
|
+
if (pks.length === 0) return;
|
|
1776
|
+
const pksToRemove = new Set(pks);
|
|
1777
|
+
const existingSlots = this.index.getSlotsByKey(key);
|
|
1778
|
+
const nextSlots = /* @__PURE__ */ new Set();
|
|
1779
|
+
let hasChanges = false;
|
|
1780
|
+
for (const slot of existingSlots) {
|
|
1781
|
+
if (pksToRemove.has(slot.pk)) {
|
|
1782
|
+
hasChanges = true;
|
|
1783
|
+
} else {
|
|
1784
|
+
nextSlots.add(slot);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
if (!hasChanges) return;
|
|
1788
|
+
if (nextSlots.size === 0) this.clear(key);
|
|
1789
|
+
else this.setSlots(key, nextSlots);
|
|
1619
1790
|
}
|
|
1620
|
-
|
|
1621
|
-
return
|
|
1791
|
+
getEntitiesByKey(key) {
|
|
1792
|
+
return super.getEntitiesByKey(key);
|
|
1622
1793
|
}
|
|
1623
|
-
|
|
1624
|
-
return
|
|
1794
|
+
getEntitiesByKeys(keys) {
|
|
1795
|
+
return super.getEntitiesByKeys(keys);
|
|
1625
1796
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1797
|
+
resolveSlots(pks) {
|
|
1798
|
+
const slots = /* @__PURE__ */ new Set();
|
|
1799
|
+
for (const pk of pks) slots.add(this.resolveRequiredSlot(pk));
|
|
1800
|
+
return slots;
|
|
1628
1801
|
}
|
|
1629
|
-
|
|
1630
|
-
this.
|
|
1802
|
+
resolveRequiredSlot(pk) {
|
|
1803
|
+
const slot = this.resolveSlot(pk);
|
|
1804
|
+
if (!slot) {
|
|
1805
|
+
throw new Error(
|
|
1806
|
+
`[OIMReactiveCollectionIndexManualSetBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1807
|
+
);
|
|
1808
|
+
}
|
|
1809
|
+
return slot;
|
|
1631
1810
|
}
|
|
1632
1811
|
};
|
|
1633
1812
|
|
|
1634
|
-
// src/core/
|
|
1635
|
-
var
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1813
|
+
// src/core/OIMDerivedCollectionIndexSetBased.ts
|
|
1814
|
+
var OIMDerivedCollectionIndexSetBased = class extends OIMReactiveCollectionIndexManualSetBased {
|
|
1815
|
+
constructor(queue, collection, opts) {
|
|
1816
|
+
super(queue, {
|
|
1817
|
+
collection,
|
|
1818
|
+
indexOptions: opts.indexOptions
|
|
1819
|
+
});
|
|
1820
|
+
this.keysByPk = /* @__PURE__ */ new Map();
|
|
1821
|
+
this.onCollectionUpdate = (pks) => {
|
|
1822
|
+
if (pks.length === 0) {
|
|
1823
|
+
this.rebuildFromCollection();
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
for (const pk of pks) {
|
|
1827
|
+
this.syncPk(pk);
|
|
1646
1828
|
}
|
|
1647
|
-
return false;
|
|
1648
1829
|
};
|
|
1830
|
+
this.collection = collection;
|
|
1831
|
+
this.selectIndexKeys = opts.selectIndexKeys;
|
|
1832
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
1833
|
+
0 /* UPDATE */,
|
|
1834
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
1835
|
+
);
|
|
1836
|
+
if (opts.buildInitial !== false) {
|
|
1837
|
+
this.rebuildFromCollection();
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
rebuildFromCollection() {
|
|
1841
|
+
this.keysByPk.clear();
|
|
1842
|
+
super.clear();
|
|
1843
|
+
const slotsByKey = /* @__PURE__ */ new Map();
|
|
1844
|
+
const slots = this.collection.getAllSlots();
|
|
1845
|
+
for (const slot of slots) {
|
|
1846
|
+
if (slot.item === void 0) continue;
|
|
1847
|
+
const keys = this.normalizeKeys(this.selectIndexKeys(slot.item));
|
|
1848
|
+
if (keys.length === 0) continue;
|
|
1849
|
+
this.keysByPk.set(slot.pk, new Set(keys));
|
|
1850
|
+
for (const key of keys) {
|
|
1851
|
+
let slotsForKey = slotsByKey.get(key);
|
|
1852
|
+
if (!slotsForKey) {
|
|
1853
|
+
slotsForKey = /* @__PURE__ */ new Set();
|
|
1854
|
+
slotsByKey.set(key, slotsForKey);
|
|
1855
|
+
}
|
|
1856
|
+
slotsForKey.add(slot);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
for (const [key, keySlots] of slotsByKey) {
|
|
1860
|
+
this.setSlots(key, keySlots);
|
|
1861
|
+
}
|
|
1649
1862
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
this.isFlushing = false;
|
|
1658
|
-
this.scheduler = options.scheduler;
|
|
1659
|
-
if (this.scheduler) {
|
|
1660
|
-
this.flushBound = () => this.flush();
|
|
1661
|
-
this.scheduler.on(
|
|
1662
|
-
0 /* FLUSH */,
|
|
1663
|
-
this.flushBound
|
|
1664
|
-
);
|
|
1863
|
+
clear(key) {
|
|
1864
|
+
if (key === void 0) {
|
|
1865
|
+
this.keysByPk.clear();
|
|
1866
|
+
} else {
|
|
1867
|
+
for (const keys of this.keysByPk.values()) {
|
|
1868
|
+
keys.delete(key);
|
|
1869
|
+
}
|
|
1665
1870
|
}
|
|
1871
|
+
super.clear(key);
|
|
1666
1872
|
}
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
enqueue(fn) {
|
|
1672
|
-
let isActive = true;
|
|
1673
|
-
const task = () => {
|
|
1674
|
-
if (!isActive) return;
|
|
1675
|
-
fn();
|
|
1676
|
-
};
|
|
1677
|
-
this.tasks.add(task);
|
|
1678
|
-
this.ensureScheduled();
|
|
1679
|
-
return () => {
|
|
1680
|
-
if (!isActive) return;
|
|
1681
|
-
isActive = false;
|
|
1682
|
-
this.tasks.delete(task);
|
|
1683
|
-
};
|
|
1873
|
+
destroy() {
|
|
1874
|
+
this.unsubscribeFromCollection();
|
|
1875
|
+
this.keysByPk.clear();
|
|
1876
|
+
super.destroy();
|
|
1684
1877
|
}
|
|
1685
|
-
|
|
1686
|
-
|
|
1878
|
+
syncPk(pk) {
|
|
1879
|
+
const prevKeys = this.keysByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
1880
|
+
const slot = this.collection.getSlotByPk(pk);
|
|
1881
|
+
const entity = slot?.item;
|
|
1882
|
+
const nextKeys = entity === void 0 ? /* @__PURE__ */ new Set() : new Set(this.normalizeKeys(this.selectIndexKeys(entity)));
|
|
1883
|
+
for (const key of prevKeys) {
|
|
1884
|
+
if (!nextKeys.has(key)) {
|
|
1885
|
+
this.removePks(key, [pk]);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
if (entity !== void 0) {
|
|
1889
|
+
for (const key of nextKeys) {
|
|
1890
|
+
if (!prevKeys.has(key)) {
|
|
1891
|
+
this.addPks(key, [pk]);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
if (nextKeys.size === 0) {
|
|
1896
|
+
this.keysByPk.delete(pk);
|
|
1897
|
+
} else {
|
|
1898
|
+
this.keysByPk.set(pk, nextKeys);
|
|
1899
|
+
}
|
|
1687
1900
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1901
|
+
normalizeKeys(keys) {
|
|
1902
|
+
if (keys === void 0 || keys === null) return [];
|
|
1903
|
+
const rawKeys = Array.isArray(keys) ? keys : [keys];
|
|
1904
|
+
const result = [];
|
|
1905
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1906
|
+
for (const key of rawKeys) {
|
|
1907
|
+
if (seen.has(key)) continue;
|
|
1908
|
+
seen.add(key);
|
|
1909
|
+
result.push(key);
|
|
1910
|
+
}
|
|
1911
|
+
return result;
|
|
1693
1912
|
}
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
this.
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1913
|
+
};
|
|
1914
|
+
|
|
1915
|
+
// src/core/OIMDerivedCollectionIndexArrayBased.ts
|
|
1916
|
+
var OIMDerivedCollectionIndexArrayBased = class extends OIMReactiveCollectionIndexManualArrayBased {
|
|
1917
|
+
constructor(queue, collection, opts) {
|
|
1918
|
+
super(queue, {
|
|
1919
|
+
collection,
|
|
1920
|
+
indexOptions: opts.indexOptions
|
|
1921
|
+
});
|
|
1922
|
+
this.keysByPk = /* @__PURE__ */ new Map();
|
|
1923
|
+
this.onCollectionUpdate = (pks) => {
|
|
1924
|
+
if (pks.length === 0) {
|
|
1925
|
+
this.rebuildFromCollection();
|
|
1926
|
+
return;
|
|
1927
|
+
}
|
|
1928
|
+
const affectedKeys = /* @__PURE__ */ new Set();
|
|
1929
|
+
for (const pk of pks) {
|
|
1930
|
+
this.trackPkKeys(pk, affectedKeys);
|
|
1931
|
+
}
|
|
1932
|
+
for (const key of affectedKeys) {
|
|
1933
|
+
this.rebuildKey(key);
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
this.collection = collection;
|
|
1937
|
+
this.selectIndexKeys = opts.selectIndexKeys;
|
|
1938
|
+
this.compareEntities = opts.compareEntities;
|
|
1939
|
+
this.orderBy = opts.orderBy;
|
|
1940
|
+
this.unsubscribeFromCollection = collection.emitter.on(
|
|
1941
|
+
0 /* UPDATE */,
|
|
1942
|
+
(payload) => this.onCollectionUpdate(payload.pks)
|
|
1943
|
+
);
|
|
1944
|
+
if (opts.buildInitial !== false) {
|
|
1945
|
+
this.rebuildFromCollection();
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
rebuildFromCollection() {
|
|
1949
|
+
this.keysByPk.clear();
|
|
1950
|
+
super.clear();
|
|
1951
|
+
const slotsByKey = /* @__PURE__ */ new Map();
|
|
1952
|
+
const slots = this.collection.getAllSlots();
|
|
1953
|
+
for (const slot of slots) {
|
|
1954
|
+
if (slot.item === void 0) continue;
|
|
1955
|
+
const keys = this.normalizeKeys(this.selectIndexKeys(slot.item));
|
|
1956
|
+
if (keys.length === 0) continue;
|
|
1957
|
+
this.keysByPk.set(slot.pk, new Set(keys));
|
|
1958
|
+
for (const key of keys) {
|
|
1959
|
+
let slotsForKey = slotsByKey.get(key);
|
|
1960
|
+
if (!slotsForKey) {
|
|
1961
|
+
slotsForKey = [];
|
|
1962
|
+
slotsByKey.set(key, slotsForKey);
|
|
1963
|
+
}
|
|
1964
|
+
slotsForKey.push(slot);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
for (const [key, keySlots] of slotsByKey) {
|
|
1968
|
+
this.setSlots(key, this.sortSlots(keySlots));
|
|
1708
1969
|
}
|
|
1709
|
-
this.isFlushing = false;
|
|
1710
|
-
this.emitter.emit(0 /* AFTER_FLUSH */, void 0);
|
|
1711
1970
|
}
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1971
|
+
clear(key) {
|
|
1972
|
+
if (key === void 0) {
|
|
1973
|
+
this.keysByPk.clear();
|
|
1974
|
+
} else {
|
|
1975
|
+
for (const keys of this.keysByPk.values()) {
|
|
1976
|
+
keys.delete(key);
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
super.clear(key);
|
|
1717
1980
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
return this.tasks.size === 0;
|
|
1981
|
+
destroy() {
|
|
1982
|
+
this.unsubscribeFromCollection();
|
|
1983
|
+
this.keysByPk.clear();
|
|
1984
|
+
super.destroy();
|
|
1723
1985
|
}
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
this.
|
|
1986
|
+
trackPkKeys(pk, affectedKeys) {
|
|
1987
|
+
const prevKeys = this.keysByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
1988
|
+
for (const key of prevKeys) affectedKeys.add(key);
|
|
1989
|
+
const slot = this.collection.getSlotByPk(pk);
|
|
1990
|
+
const entity = slot?.item;
|
|
1991
|
+
const nextKeys = entity === void 0 ? /* @__PURE__ */ new Set() : new Set(this.normalizeKeys(this.selectIndexKeys(entity)));
|
|
1992
|
+
for (const key of nextKeys) affectedKeys.add(key);
|
|
1993
|
+
if (nextKeys.size === 0) {
|
|
1994
|
+
this.keysByPk.delete(pk);
|
|
1995
|
+
} else {
|
|
1996
|
+
this.keysByPk.set(pk, nextKeys);
|
|
1997
|
+
}
|
|
1730
1998
|
}
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1999
|
+
rebuildKey(key) {
|
|
2000
|
+
const keySlots = [];
|
|
2001
|
+
const slots = this.collection.getAllSlots();
|
|
2002
|
+
for (const slot of slots) {
|
|
2003
|
+
if (slot.item === void 0) continue;
|
|
2004
|
+
const keys = this.keysByPk.get(slot.pk);
|
|
2005
|
+
if (keys?.has(key)) keySlots.push(slot);
|
|
2006
|
+
}
|
|
2007
|
+
if (keySlots.length === 0) {
|
|
2008
|
+
super.clear(key);
|
|
2009
|
+
} else {
|
|
2010
|
+
this.setSlots(key, this.sortSlots(keySlots));
|
|
1736
2011
|
}
|
|
1737
2012
|
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
this.
|
|
1746
|
-
|
|
2013
|
+
sortSlots(slots) {
|
|
2014
|
+
if (!this.compareEntities && !this.orderBy) return slots;
|
|
2015
|
+
return slots.slice().sort((a, b) => {
|
|
2016
|
+
const aItem = a.item;
|
|
2017
|
+
const bItem = b.item;
|
|
2018
|
+
if (aItem === void 0 || bItem === void 0) return 0;
|
|
2019
|
+
if (this.compareEntities) {
|
|
2020
|
+
return this.compareEntities(aItem, bItem);
|
|
2021
|
+
}
|
|
2022
|
+
const aValue = this.orderBy(aItem);
|
|
2023
|
+
const bValue = this.orderBy(bItem);
|
|
2024
|
+
if (aValue < bValue) return -1;
|
|
2025
|
+
if (aValue > bValue) return 1;
|
|
2026
|
+
return 0;
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
normalizeKeys(keys) {
|
|
2030
|
+
if (keys === void 0 || keys === null) return [];
|
|
2031
|
+
const rawKeys = Array.isArray(keys) ? keys : [keys];
|
|
2032
|
+
const result = [];
|
|
2033
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2034
|
+
for (const key of rawKeys) {
|
|
2035
|
+
if (seen.has(key)) continue;
|
|
2036
|
+
seen.add(key);
|
|
2037
|
+
result.push(key);
|
|
1747
2038
|
}
|
|
1748
|
-
|
|
2039
|
+
return result;
|
|
1749
2040
|
}
|
|
1750
2041
|
};
|
|
1751
2042
|
|
|
1752
|
-
// src/core/
|
|
1753
|
-
var
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
*/
|
|
1758
|
-
static createElementWiseComparator() {
|
|
1759
|
-
return (existingPks, newPks) => {
|
|
1760
|
-
if (existingPks.length !== newPks.length) {
|
|
1761
|
-
return false;
|
|
1762
|
-
}
|
|
1763
|
-
for (let i = 0; i < existingPks.length; i++) {
|
|
1764
|
-
if (existingPks[i] !== newPks[i]) {
|
|
1765
|
-
return false;
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
return true;
|
|
1769
|
-
};
|
|
2043
|
+
// src/core/OIMCollectionIndexFactory.ts
|
|
2044
|
+
var OIMCollectionIndexFactory = class {
|
|
2045
|
+
constructor(queue, collection) {
|
|
2046
|
+
this.queue = queue;
|
|
2047
|
+
this.collection = collection;
|
|
1770
2048
|
}
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
2049
|
+
setBasedIndex(opts = {}) {
|
|
2050
|
+
return new OIMReactiveCollectionIndexManualSetBased(this.queue, {
|
|
2051
|
+
collection: this.collection,
|
|
2052
|
+
indexOptions: opts.indexOptions
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
derivedSetIndex(selectIndexKeys, opts = {}) {
|
|
2056
|
+
return new OIMDerivedCollectionIndexSetBased(
|
|
2057
|
+
this.queue,
|
|
2058
|
+
this.collection,
|
|
2059
|
+
{
|
|
2060
|
+
selectIndexKeys,
|
|
2061
|
+
buildInitial: opts.buildInitial,
|
|
2062
|
+
indexOptions: opts.indexOptions
|
|
1784
2063
|
}
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
2064
|
+
);
|
|
2065
|
+
}
|
|
2066
|
+
arrayBasedIndex(opts = {}) {
|
|
2067
|
+
return new OIMReactiveCollectionIndexManualArrayBased(this.queue, {
|
|
2068
|
+
collection: this.collection,
|
|
2069
|
+
indexOptions: opts.indexOptions
|
|
2070
|
+
});
|
|
2071
|
+
}
|
|
2072
|
+
derivedArrayIndex(selectIndexKeys, opts = {}) {
|
|
2073
|
+
return new OIMDerivedCollectionIndexArrayBased(
|
|
2074
|
+
this.queue,
|
|
2075
|
+
this.collection,
|
|
2076
|
+
{
|
|
2077
|
+
selectIndexKeys,
|
|
2078
|
+
buildInitial: opts.buildInitial,
|
|
2079
|
+
compareEntities: opts.compareEntities,
|
|
2080
|
+
orderBy: opts.orderBy,
|
|
2081
|
+
indexOptions: opts.indexOptions
|
|
1789
2082
|
}
|
|
1790
|
-
|
|
1791
|
-
};
|
|
2083
|
+
);
|
|
1792
2084
|
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
2085
|
+
orderedIndex() {
|
|
2086
|
+
return new OIMCollectionIndexManualOrderedArrayBased({
|
|
2087
|
+
collection: this.collection
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
orderedList(opts = {}) {
|
|
2091
|
+
return new OIMCollectionOrderedListCommandStream(
|
|
2092
|
+
this.queue,
|
|
2093
|
+
opts.index ? { collection: this.collection, index: opts.index } : { collection: this.collection }
|
|
2094
|
+
);
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
function createOIMCollectionIndexFactory(queue, collection) {
|
|
2098
|
+
return new OIMCollectionIndexFactory(queue, collection);
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
// src/core/OIMObjectStoreRecordDriven.ts
|
|
2102
|
+
var OIMObjectStoreRecordDriven = class extends OIMObjectStore {
|
|
2103
|
+
constructor(initial) {
|
|
2104
|
+
super();
|
|
2105
|
+
this.properties = Object.assign(/* @__PURE__ */ Object.create(null), initial ?? {});
|
|
2106
|
+
}
|
|
2107
|
+
setProperty(key, value) {
|
|
2108
|
+
this.properties[key] = value;
|
|
2109
|
+
}
|
|
2110
|
+
merge(draft) {
|
|
2111
|
+
Object.assign(this.properties, draft);
|
|
2112
|
+
}
|
|
2113
|
+
delete(key) {
|
|
2114
|
+
delete this.properties[key];
|
|
2115
|
+
}
|
|
2116
|
+
get(key) {
|
|
2117
|
+
return this.properties[key];
|
|
2118
|
+
}
|
|
2119
|
+
getAll() {
|
|
2120
|
+
return { ...this.properties };
|
|
2121
|
+
}
|
|
2122
|
+
clear() {
|
|
2123
|
+
this.properties = /* @__PURE__ */ Object.create(null);
|
|
2124
|
+
}
|
|
2125
|
+
count() {
|
|
2126
|
+
return Object.keys(this.properties).length;
|
|
2127
|
+
}
|
|
2128
|
+
keys() {
|
|
2129
|
+
return Object.keys(this.properties);
|
|
2130
|
+
}
|
|
2131
|
+
values() {
|
|
2132
|
+
return Object.values(this.properties);
|
|
2133
|
+
}
|
|
2134
|
+
entries() {
|
|
2135
|
+
return Object.entries(this.properties);
|
|
2136
|
+
}
|
|
2137
|
+
destroy() {
|
|
2138
|
+
this.clear();
|
|
2139
|
+
}
|
|
2140
|
+
};
|
|
2141
|
+
|
|
2142
|
+
// src/enums/EOIMObjectEventType.ts
|
|
2143
|
+
var EOIMObjectEventType = /* @__PURE__ */ ((EOIMObjectEventType2) => {
|
|
2144
|
+
EOIMObjectEventType2[EOIMObjectEventType2["UPDATE"] = 0] = "UPDATE";
|
|
2145
|
+
return EOIMObjectEventType2;
|
|
2146
|
+
})(EOIMObjectEventType || {});
|
|
2147
|
+
|
|
2148
|
+
// src/core/OIMObject.ts
|
|
2149
|
+
var OIMObject = class {
|
|
2150
|
+
constructor(opts) {
|
|
2151
|
+
this.emitter = new OIMEventEmitter();
|
|
2152
|
+
this.store = opts?.store ?? new OIMObjectStoreRecordDriven();
|
|
2153
|
+
}
|
|
2154
|
+
setProperty(key, value) {
|
|
2155
|
+
this.store.setProperty(key, value);
|
|
2156
|
+
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
2157
|
+
}
|
|
2158
|
+
merge(draft) {
|
|
2159
|
+
this.store.merge(draft);
|
|
2160
|
+
this.emitter.emit(0 /* UPDATE */, {
|
|
2161
|
+
keys: Object.keys(draft)
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2164
|
+
delete(key) {
|
|
2165
|
+
this.store.delete(key);
|
|
2166
|
+
this.emitter.emit(0 /* UPDATE */, { keys: [key] });
|
|
2167
|
+
}
|
|
2168
|
+
get(key) {
|
|
2169
|
+
return this.store.get(key);
|
|
2170
|
+
}
|
|
2171
|
+
getAll() {
|
|
2172
|
+
return this.store.getAll();
|
|
2173
|
+
}
|
|
2174
|
+
clear() {
|
|
2175
|
+
this.store.clear();
|
|
2176
|
+
this.emitter.emit(0 /* UPDATE */, { keys: [] });
|
|
2177
|
+
}
|
|
2178
|
+
count() {
|
|
2179
|
+
return this.store.count();
|
|
2180
|
+
}
|
|
2181
|
+
keys() {
|
|
2182
|
+
return this.store.keys();
|
|
2183
|
+
}
|
|
2184
|
+
values() {
|
|
2185
|
+
return this.store.values();
|
|
2186
|
+
}
|
|
2187
|
+
entries() {
|
|
2188
|
+
return this.store.entries();
|
|
2189
|
+
}
|
|
2190
|
+
destroy() {
|
|
2191
|
+
this.store.destroy();
|
|
2192
|
+
this.emitter.offAll();
|
|
2193
|
+
}
|
|
2194
|
+
};
|
|
2195
|
+
|
|
2196
|
+
// src/core/OIMReactiveObject.ts
|
|
2197
|
+
var OIMReactiveObject = class extends OIMObject {
|
|
2198
|
+
constructor(queue, opts) {
|
|
2199
|
+
super(opts);
|
|
2200
|
+
this.updateEmitter = new OIMUpdateEventEmitter(queue, "queue");
|
|
2201
|
+
this.emitter.on(0 /* UPDATE */, (payload) => {
|
|
2202
|
+
this.updateEmitter.markUpdatedKeys(payload.keys);
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
subscribeOnKey(key, handler) {
|
|
2206
|
+
return this.updateEmitter.subscribeOnKey(key, handler);
|
|
2207
|
+
}
|
|
2208
|
+
subscribeOnKeys(keys, handler) {
|
|
2209
|
+
return this.updateEmitter.subscribeOnKeys(keys, handler);
|
|
2210
|
+
}
|
|
2211
|
+
unsubscribeFromKey(key, handler) {
|
|
2212
|
+
this.updateEmitter.unsubscribeFromKey(key, handler);
|
|
2213
|
+
}
|
|
2214
|
+
unsubscribeFromKeys(keys, handler) {
|
|
2215
|
+
this.updateEmitter.unsubscribeFromKeys(keys, handler);
|
|
2216
|
+
}
|
|
2217
|
+
hasSubscriptions() {
|
|
2218
|
+
return this.updateEmitter.hasSubscriptions();
|
|
2219
|
+
}
|
|
2220
|
+
getHandlerCount(key) {
|
|
2221
|
+
return this.updateEmitter.getHandlerCount(key);
|
|
2222
|
+
}
|
|
2223
|
+
getMetrics() {
|
|
2224
|
+
return this.updateEmitter.getMetrics();
|
|
2225
|
+
}
|
|
2226
|
+
destroy() {
|
|
2227
|
+
this.updateEmitter.destroy();
|
|
2228
|
+
super.destroy();
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
|
|
2232
|
+
// src/core/OIMObjectStoreMapDriven.ts
|
|
2233
|
+
var OIMObjectStoreMapDriven = class extends OIMObjectStore {
|
|
2234
|
+
constructor() {
|
|
2235
|
+
super(...arguments);
|
|
2236
|
+
this.properties = /* @__PURE__ */ new Map();
|
|
2237
|
+
}
|
|
2238
|
+
setProperty(key, value) {
|
|
2239
|
+
this.properties.set(key, value);
|
|
2240
|
+
}
|
|
2241
|
+
merge(draft) {
|
|
2242
|
+
for (const key in draft) {
|
|
2243
|
+
if (!Object.prototype.hasOwnProperty.call(draft, key)) continue;
|
|
2244
|
+
this.properties.set(
|
|
2245
|
+
key,
|
|
2246
|
+
draft[key]
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
delete(key) {
|
|
2251
|
+
this.properties.delete(key);
|
|
2252
|
+
}
|
|
2253
|
+
get(key) {
|
|
2254
|
+
return this.properties.get(key);
|
|
2255
|
+
}
|
|
2256
|
+
getAll() {
|
|
2257
|
+
return Object.fromEntries(this.properties.entries());
|
|
2258
|
+
}
|
|
2259
|
+
clear() {
|
|
2260
|
+
this.properties.clear();
|
|
2261
|
+
}
|
|
2262
|
+
count() {
|
|
2263
|
+
return this.properties.size;
|
|
2264
|
+
}
|
|
2265
|
+
keys() {
|
|
2266
|
+
return Array.from(this.properties.keys());
|
|
2267
|
+
}
|
|
2268
|
+
values() {
|
|
2269
|
+
return Array.from(this.properties.values());
|
|
2270
|
+
}
|
|
2271
|
+
entries() {
|
|
2272
|
+
return Array.from(this.properties.entries());
|
|
2273
|
+
}
|
|
2274
|
+
destroy() {
|
|
2275
|
+
this.properties.clear();
|
|
2276
|
+
}
|
|
2277
|
+
};
|
|
2278
|
+
|
|
2279
|
+
// src/core/OIMComparatorFactory.ts
|
|
2280
|
+
var OIMComparatorFactory = class {
|
|
2281
|
+
createShallowComparator() {
|
|
2282
|
+
return (a, b) => {
|
|
2283
|
+
if (a === b) return false;
|
|
2284
|
+
const ka = Object.keys(a);
|
|
2285
|
+
const kb = Object.keys(b);
|
|
2286
|
+
if (ka.length !== kb.length) return true;
|
|
2287
|
+
for (let i = 0; i < ka.length; i++) {
|
|
2288
|
+
const k = ka[i];
|
|
2289
|
+
if (b[k] !== a[k])
|
|
2290
|
+
return true;
|
|
2291
|
+
}
|
|
2292
|
+
return false;
|
|
2293
|
+
};
|
|
2294
|
+
}
|
|
2295
|
+
};
|
|
2296
|
+
|
|
2297
|
+
// src/core/OIMEventQueue.ts
|
|
2298
|
+
var OIMEventQueue = class {
|
|
2299
|
+
constructor(options = {}) {
|
|
2300
|
+
this.emitter = new OIMEventEmitter();
|
|
2301
|
+
this.tasks = /* @__PURE__ */ new Set();
|
|
2302
|
+
this.isFlushing = false;
|
|
2303
|
+
this.scheduler = options.scheduler;
|
|
2304
|
+
if (this.scheduler) {
|
|
2305
|
+
this.flushBound = () => this.flush();
|
|
2306
|
+
this.scheduler.on(
|
|
2307
|
+
0 /* FLUSH */,
|
|
2308
|
+
this.flushBound
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
/**
|
|
2313
|
+
* Enqueue a one-shot task to be executed on the next flush.
|
|
2314
|
+
* Returns a dequeue function that can be called to cancel the task before it runs.
|
|
2315
|
+
*/
|
|
2316
|
+
enqueue(fn) {
|
|
2317
|
+
let isActive = true;
|
|
2318
|
+
const task = () => {
|
|
2319
|
+
if (!isActive) return;
|
|
2320
|
+
fn();
|
|
2321
|
+
};
|
|
2322
|
+
this.tasks.add(task);
|
|
2323
|
+
this.ensureScheduled();
|
|
2324
|
+
return () => {
|
|
2325
|
+
if (!isActive) return;
|
|
2326
|
+
isActive = false;
|
|
2327
|
+
this.tasks.delete(task);
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
get isInFlush() {
|
|
2331
|
+
return this.isFlushing;
|
|
2332
|
+
}
|
|
2333
|
+
/**
|
|
2334
|
+
* Dequeue (cancel) a previously enqueued task by its dequeue function.
|
|
2335
|
+
*/
|
|
2336
|
+
dequeue(dequeueFn) {
|
|
2337
|
+
dequeueFn();
|
|
2338
|
+
}
|
|
2339
|
+
/**
|
|
2340
|
+
* Execute all pending tasks.
|
|
2341
|
+
*
|
|
2342
|
+
* This flush drains until the queue is empty. If tasks enqueue more tasks, they will be
|
|
2343
|
+
* executed within the same flush.
|
|
2344
|
+
*/
|
|
2345
|
+
flush() {
|
|
2346
|
+
this.scheduler?.cancel();
|
|
2347
|
+
this.isFlushing = true;
|
|
2348
|
+
this.emitter.emit(1 /* BEFORE_FLUSH */, void 0);
|
|
2349
|
+
const snapshot = Array.from(this.tasks);
|
|
2350
|
+
this.tasks.clear();
|
|
2351
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2352
|
+
snapshot[i]();
|
|
2353
|
+
}
|
|
2354
|
+
this.isFlushing = false;
|
|
2355
|
+
this.emitter.emit(0 /* AFTER_FLUSH */, void 0);
|
|
2356
|
+
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Get the current number of queued functions.
|
|
2359
|
+
*/
|
|
2360
|
+
get length() {
|
|
2361
|
+
return this.tasks.size;
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* Check if the queue is empty.
|
|
2365
|
+
*/
|
|
2366
|
+
get isEmpty() {
|
|
2367
|
+
return this.tasks.size === 0;
|
|
2368
|
+
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Clear the queue without executing functions and cancel any scheduled flush.
|
|
2371
|
+
*/
|
|
2372
|
+
clear() {
|
|
2373
|
+
this.tasks.clear();
|
|
2374
|
+
this.scheduler?.cancel();
|
|
2375
|
+
}
|
|
2376
|
+
ensureScheduled() {
|
|
2377
|
+
if (!this.scheduler) return;
|
|
2378
|
+
if (this.isFlushing) return;
|
|
2379
|
+
if (this.tasks.size === 1) {
|
|
2380
|
+
this.scheduler.schedule();
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Clean up scheduler subscription when queue is no longer needed.
|
|
2385
|
+
*/
|
|
2386
|
+
destroy() {
|
|
2387
|
+
if (this.scheduler && this.flushBound) {
|
|
2388
|
+
this.scheduler.off(
|
|
2389
|
+
0 /* FLUSH */,
|
|
2390
|
+
this.flushBound
|
|
2391
|
+
);
|
|
2392
|
+
}
|
|
2393
|
+
this.clear();
|
|
2394
|
+
}
|
|
2395
|
+
};
|
|
2396
|
+
|
|
2397
|
+
// src/core/OIMIndexComparatorFactory.ts
|
|
2398
|
+
var OIMIndexComparatorFactory = class {
|
|
2399
|
+
/**
|
|
2400
|
+
* Create an element-wise comparator that checks arrays for strict equality.
|
|
2401
|
+
* Compares array lengths and each element using strict equality (===).
|
|
2402
|
+
*/
|
|
2403
|
+
static createElementWiseComparator() {
|
|
2404
|
+
return (existingPks, newPks) => {
|
|
2405
|
+
if (existingPks.length !== newPks.length) {
|
|
2406
|
+
return false;
|
|
2407
|
+
}
|
|
2408
|
+
for (let i = 0; i < existingPks.length; i++) {
|
|
2409
|
+
if (existingPks[i] !== newPks[i]) {
|
|
2410
|
+
return false;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
return true;
|
|
2414
|
+
};
|
|
2415
|
+
}
|
|
2416
|
+
/**
|
|
2417
|
+
* Create a set-based comparator that checks if arrays contain the same elements.
|
|
2418
|
+
* Order doesn't matter, only the presence of elements.
|
|
2419
|
+
*/
|
|
2420
|
+
static createSetBasedComparator() {
|
|
2421
|
+
return (existingPks, newPks) => {
|
|
2422
|
+
if (existingPks.length !== newPks.length) {
|
|
2423
|
+
return false;
|
|
2424
|
+
}
|
|
2425
|
+
const existingSet = new Set(existingPks);
|
|
2426
|
+
const newSet = new Set(newPks);
|
|
2427
|
+
if (existingSet.size !== newSet.size || existingSet.size !== existingPks.length) {
|
|
2428
|
+
return false;
|
|
2429
|
+
}
|
|
2430
|
+
for (const pk of Array.from(existingSet)) {
|
|
2431
|
+
if (!newSet.has(pk)) {
|
|
2432
|
+
return false;
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
return true;
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Create a shallow comparator that only checks array references.
|
|
2440
|
+
* Fastest but only works if you're reusing the same array instances.
|
|
2441
|
+
*/
|
|
2442
|
+
static createShallowComparator() {
|
|
2443
|
+
return (existingPks, newPks) => {
|
|
2444
|
+
return existingPks === newPks;
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2448
|
+
* Create a no-comparison comparator that always returns false (always updates).
|
|
2449
|
+
* Useful for disabling comparison while keeping the same interface.
|
|
2450
|
+
*/
|
|
2451
|
+
static createAlwaysUpdateComparator() {
|
|
2452
|
+
return () => false;
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2456
|
+
// src/core/OIMMap2Keys.ts
|
|
2457
|
+
var OIMMap2Keys = class {
|
|
2458
|
+
constructor() {
|
|
2459
|
+
this.map = /* @__PURE__ */ new Map();
|
|
2460
|
+
this._size = 0;
|
|
2461
|
+
}
|
|
2462
|
+
get size() {
|
|
2463
|
+
return this._size;
|
|
2464
|
+
}
|
|
2465
|
+
set(k1, k2, v) {
|
|
2466
|
+
let m = this.map.get(k1);
|
|
2467
|
+
if (!m) {
|
|
2468
|
+
m = /* @__PURE__ */ new Map();
|
|
2469
|
+
this.map.set(k1, m);
|
|
2470
|
+
}
|
|
2471
|
+
if (!m.has(k2)) this._size++;
|
|
2472
|
+
m.set(k2, v);
|
|
2473
|
+
}
|
|
2474
|
+
get(k1, k2) {
|
|
2475
|
+
return this.map.get(k1)?.get(k2);
|
|
2476
|
+
}
|
|
2477
|
+
has(k1, k2) {
|
|
2478
|
+
return this.map.get(k1)?.has(k2);
|
|
2479
|
+
}
|
|
2480
|
+
delete(k1, k2) {
|
|
2481
|
+
const m = this.map.get(k1);
|
|
2482
|
+
if (!m) return false;
|
|
2483
|
+
const had = m.delete(k2);
|
|
2484
|
+
if (had) {
|
|
2485
|
+
this._size--;
|
|
2486
|
+
if (m.size === 0) this.map.delete(k1);
|
|
2487
|
+
}
|
|
2488
|
+
return had;
|
|
2489
|
+
}
|
|
2490
|
+
clear() {
|
|
2491
|
+
this.map.clear();
|
|
2492
|
+
this._size = 0;
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2495
|
+
|
|
2496
|
+
// src/modules/compute/core/OIMComputeRuntime.ts
|
|
2497
|
+
var OIMComputeRuntime = class {
|
|
2498
|
+
constructor(queue) {
|
|
2499
|
+
this.queue = queue;
|
|
2500
|
+
this.isFlushScheduled = false;
|
|
2501
|
+
this.isFlushing = false;
|
|
2502
|
+
this.minLevel = Infinity;
|
|
2503
|
+
this.maxLevel = -Infinity;
|
|
2504
|
+
this.dirtyByLevel = /* @__PURE__ */ new Map();
|
|
2505
|
+
this.afterFlushTasks = /* @__PURE__ */ new Set();
|
|
2506
|
+
this.queue.emitter.on(0 /* AFTER_FLUSH */, () => {
|
|
2507
|
+
if (!this.isFlushScheduled) return;
|
|
2508
|
+
this.flush();
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
/**
|
|
2512
|
+
* Schedule a one-shot task to run on the next `queue.flush()` (AFTER_FLUSH),
|
|
2513
|
+
* ordered by `level` ascending.
|
|
2514
|
+
*/
|
|
2515
|
+
schedule(task, level = 0) {
|
|
2516
|
+
let isActive = true;
|
|
2517
|
+
const wrapped = () => {
|
|
2518
|
+
if (!isActive) return;
|
|
2519
|
+
task();
|
|
2520
|
+
};
|
|
2521
|
+
let bucket = this.dirtyByLevel.get(level);
|
|
2522
|
+
if (!bucket) {
|
|
2523
|
+
bucket = /* @__PURE__ */ new Set();
|
|
2524
|
+
this.dirtyByLevel.set(level, bucket);
|
|
2525
|
+
}
|
|
2526
|
+
bucket.add(wrapped);
|
|
2527
|
+
if (level < this.minLevel) this.minLevel = level;
|
|
2528
|
+
if (level > this.maxLevel) this.maxLevel = level;
|
|
2529
|
+
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
2530
|
+
return () => {
|
|
2531
|
+
if (!isActive) return;
|
|
2532
|
+
isActive = false;
|
|
2533
|
+
bucket.delete(wrapped);
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Run once at the start of the next runtime flush (i.e. after queue.flush()).
|
|
2538
|
+
* Useful for resubscribing dependencies exactly once per source flush.
|
|
2539
|
+
*/
|
|
2540
|
+
scheduleAfterFlush(task) {
|
|
2541
|
+
let isActive = true;
|
|
2542
|
+
const wrapped = () => {
|
|
2543
|
+
if (!isActive) return;
|
|
2544
|
+
task();
|
|
2545
|
+
};
|
|
2546
|
+
this.afterFlushTasks.add(wrapped);
|
|
2547
|
+
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
2548
|
+
return () => {
|
|
2549
|
+
if (!isActive) return;
|
|
2550
|
+
isActive = false;
|
|
2551
|
+
this.afterFlushTasks.delete(wrapped);
|
|
2552
|
+
};
|
|
2553
|
+
}
|
|
2554
|
+
flush() {
|
|
2555
|
+
this.isFlushScheduled = false;
|
|
2556
|
+
if (this.dirtyByLevel.size === 0 && this.afterFlushTasks.size === 0)
|
|
2557
|
+
return;
|
|
2558
|
+
this.isFlushing = true;
|
|
2559
|
+
try {
|
|
2560
|
+
if (this.afterFlushTasks.size > 0) {
|
|
2561
|
+
const snapshot = Array.from(this.afterFlushTasks);
|
|
2562
|
+
this.afterFlushTasks.clear();
|
|
2563
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
2564
|
+
}
|
|
2565
|
+
if (this.dirtyByLevel.size === 0) return;
|
|
2566
|
+
let level = this.minLevel;
|
|
2567
|
+
let max = this.maxLevel;
|
|
2568
|
+
while (level <= max) {
|
|
2569
|
+
for (; ; ) {
|
|
2570
|
+
const bucket = this.dirtyByLevel.get(level);
|
|
2571
|
+
if (!bucket || bucket.size === 0) break;
|
|
2572
|
+
this.dirtyByLevel.delete(level);
|
|
2573
|
+
const snapshot = Array.from(bucket);
|
|
2574
|
+
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
2575
|
+
}
|
|
2576
|
+
if (this.maxLevel > max) max = this.maxLevel;
|
|
2577
|
+
level++;
|
|
2578
|
+
}
|
|
2579
|
+
} finally {
|
|
2580
|
+
this.isFlushing = false;
|
|
2581
|
+
if (this.dirtyByLevel.size === 0) {
|
|
2582
|
+
this.minLevel = Infinity;
|
|
2583
|
+
this.maxLevel = -Infinity;
|
|
2584
|
+
} else {
|
|
2585
|
+
let nextMin = Infinity;
|
|
2586
|
+
let nextMax = -Infinity;
|
|
2587
|
+
this.dirtyByLevel.forEach((_bucket, lvl) => {
|
|
2588
|
+
if (lvl < nextMin) nextMin = lvl;
|
|
2589
|
+
if (lvl > nextMax) nextMax = lvl;
|
|
2590
|
+
});
|
|
2591
|
+
this.minLevel = nextMin;
|
|
2592
|
+
this.maxLevel = nextMax;
|
|
2593
|
+
this.isFlushScheduled = true;
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
};
|
|
2598
|
+
|
|
2599
|
+
// src/modules/selector/core/OIMSelector.ts
|
|
2600
|
+
var OIMSelector = class {
|
|
2601
|
+
constructor(runtime, sourceDeps, computedDeps = []) {
|
|
2602
|
+
this.runtime = runtime;
|
|
2603
|
+
this.sourceDeps = sourceDeps;
|
|
2604
|
+
this.computedDeps = computedDeps;
|
|
2605
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
2606
|
+
this.sourceUnsubscribers = [];
|
|
2607
|
+
this.computedUnsubscribers = [];
|
|
2608
|
+
this.isResubscribeEnqueued = false;
|
|
2609
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2610
|
+
this.isDeliveryEnqueued = false;
|
|
2611
|
+
this.hasLastValue = false;
|
|
2612
|
+
this.onSourceInvalidate = () => {
|
|
2613
|
+
if (this.listeners.size === 0) return;
|
|
2614
|
+
if (!this.isTemporarilyUnsubscribedForFlush) {
|
|
2615
|
+
this.isTemporarilyUnsubscribedForFlush = true;
|
|
2616
|
+
this.unsubscribeFromSourceDeps();
|
|
2617
|
+
this.ensureResubscribeAfterFlush();
|
|
2618
|
+
}
|
|
2619
|
+
if (this.isDeliveryEnqueued) return;
|
|
2620
|
+
this.isDeliveryEnqueued = true;
|
|
2621
|
+
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2622
|
+
};
|
|
2623
|
+
this.onComputedInvalidate = () => {
|
|
2624
|
+
if (this.listeners.size === 0) return;
|
|
2625
|
+
if (this.isDeliveryEnqueued) return;
|
|
2626
|
+
this.isDeliveryEnqueued = true;
|
|
2627
|
+
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2628
|
+
};
|
|
2629
|
+
this.deliver = () => {
|
|
2630
|
+
this.isDeliveryEnqueued = false;
|
|
2631
|
+
this.dequeueDelivery = void 0;
|
|
2632
|
+
if (this.listeners.size === 0) return;
|
|
2633
|
+
const next = this.getValue();
|
|
2634
|
+
if (this.hasLastValue && this.areEqual(this.lastValue, next)) return;
|
|
2635
|
+
this.setLastValue(next);
|
|
2636
|
+
const snapshot = Array.from(this.listeners);
|
|
2637
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2638
|
+
const listener = snapshot[i];
|
|
2639
|
+
if (this.listeners.has(listener)) listener(next);
|
|
2640
|
+
}
|
|
2641
|
+
};
|
|
2642
|
+
this.onAfterFlush = () => {
|
|
2643
|
+
if (!this.isResubscribeEnqueued) return;
|
|
2644
|
+
this.isResubscribeEnqueued = false;
|
|
2645
|
+
this.dequeueResubscribe = void 0;
|
|
2646
|
+
if (this.listeners.size === 0) return;
|
|
2647
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2648
|
+
if (this.sourceUnsubscribers.length === 0) {
|
|
2649
|
+
for (const dep of this.sourceDeps) {
|
|
2650
|
+
this.sourceUnsubscribers.push(
|
|
2651
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2652
|
+
);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
};
|
|
2656
|
+
}
|
|
2657
|
+
get queue() {
|
|
2658
|
+
return this.runtime.queue;
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* Start watching this selector. The callback is called immediately with the current value,
|
|
2662
|
+
* then coalesced and delivered on `queue.flush()` when the selector invalidates.
|
|
2663
|
+
*/
|
|
2664
|
+
watch(onValue) {
|
|
2665
|
+
this.listeners.add(onValue);
|
|
2666
|
+
if (this.listeners.size === 1) {
|
|
2667
|
+
this.subscribeToDeps();
|
|
2668
|
+
}
|
|
2669
|
+
const current = this.getValue();
|
|
2670
|
+
this.setLastValue(current);
|
|
2671
|
+
onValue(current);
|
|
2672
|
+
return () => {
|
|
2673
|
+
this.listeners.delete(onValue);
|
|
2674
|
+
if (this.listeners.size > 0) return;
|
|
2675
|
+
this.unsubscribeFromAllDeps();
|
|
2676
|
+
if (this.dequeueResubscribe) {
|
|
2677
|
+
this.dequeueResubscribe();
|
|
2678
|
+
this.dequeueResubscribe = void 0;
|
|
2679
|
+
}
|
|
2680
|
+
this.isResubscribeEnqueued = false;
|
|
2681
|
+
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2682
|
+
if (this.dequeueDelivery) {
|
|
2683
|
+
this.dequeueDelivery();
|
|
2684
|
+
this.dequeueDelivery = void 0;
|
|
2685
|
+
}
|
|
2686
|
+
this.isDeliveryEnqueued = false;
|
|
2687
|
+
this.hasLastValue = false;
|
|
2688
|
+
};
|
|
2689
|
+
}
|
|
2690
|
+
areEqual(prev, next) {
|
|
2691
|
+
return Object.is(prev, next);
|
|
2692
|
+
}
|
|
2693
|
+
setLastValue(value) {
|
|
2694
|
+
this.lastValue = value;
|
|
2695
|
+
this.hasLastValue = true;
|
|
2696
|
+
}
|
|
2697
|
+
subscribeToDeps() {
|
|
2698
|
+
if (this.sourceUnsubscribers.length > 0 || this.computedUnsubscribers.length > 0)
|
|
2699
|
+
return;
|
|
2700
|
+
for (const dep of this.sourceDeps) {
|
|
2701
|
+
this.sourceUnsubscribers.push(
|
|
2702
|
+
dep.subscribe(this.onSourceInvalidate)
|
|
2703
|
+
);
|
|
2704
|
+
}
|
|
2705
|
+
for (const dep of this.computedDeps) {
|
|
2706
|
+
this.computedUnsubscribers.push(
|
|
2707
|
+
dep.subscribe(this.onComputedInvalidate)
|
|
2708
|
+
);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
unsubscribeFromSourceDeps() {
|
|
2712
|
+
if (this.sourceUnsubscribers.length === 0) return;
|
|
2713
|
+
for (const unsub of this.sourceUnsubscribers) unsub();
|
|
2714
|
+
this.sourceUnsubscribers = [];
|
|
2715
|
+
}
|
|
2716
|
+
unsubscribeFromAllDeps() {
|
|
2717
|
+
this.unsubscribeFromSourceDeps();
|
|
2718
|
+
if (this.computedUnsubscribers.length === 0) return;
|
|
2719
|
+
for (const unsub of this.computedUnsubscribers) unsub();
|
|
2720
|
+
this.computedUnsubscribers = [];
|
|
2721
|
+
}
|
|
2722
|
+
ensureResubscribeAfterFlush() {
|
|
2723
|
+
if (this.isResubscribeEnqueued) return;
|
|
2724
|
+
this.isResubscribeEnqueued = true;
|
|
2725
|
+
this.dequeueResubscribe = this.runtime.scheduleAfterFlush(
|
|
2726
|
+
this.onAfterFlush
|
|
2727
|
+
);
|
|
2728
|
+
}
|
|
2729
|
+
};
|
|
2730
|
+
|
|
2731
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKey.ts
|
|
2732
|
+
var OIMSelectorSourceDependencyUpdateEventEmitterKey = class {
|
|
2733
|
+
constructor(subscription, key) {
|
|
2734
|
+
this.subscription = subscription;
|
|
2735
|
+
this.key = key;
|
|
2736
|
+
}
|
|
2737
|
+
subscribe(onUpdate) {
|
|
2738
|
+
return this.subscription.subscribeOnKey(this.key, onUpdate);
|
|
2739
|
+
}
|
|
2740
|
+
};
|
|
2741
|
+
|
|
2742
|
+
// src/modules/selector/core/OIMCollectionByPkSelector.ts
|
|
2743
|
+
var OIMCollectionByPkSelector = class extends OIMSelector {
|
|
2744
|
+
constructor(runtime, collection, pk) {
|
|
2745
|
+
super(runtime, [
|
|
2746
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2747
|
+
collection,
|
|
2748
|
+
pk
|
|
2749
|
+
)
|
|
2750
|
+
]);
|
|
2751
|
+
this.collection = collection;
|
|
2752
|
+
this.pk = pk;
|
|
2753
|
+
}
|
|
2754
|
+
getValue() {
|
|
2755
|
+
return this.collection.getOneByPk(this.pk);
|
|
2756
|
+
}
|
|
2757
|
+
};
|
|
2758
|
+
|
|
2759
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKeys.ts
|
|
2760
|
+
var OIMSelectorSourceDependencyUpdateEventEmitterKeys = class {
|
|
2761
|
+
constructor(subscription, keys) {
|
|
2762
|
+
this.subscription = subscription;
|
|
2763
|
+
this.keys = keys;
|
|
2764
|
+
}
|
|
2765
|
+
subscribe(onUpdate) {
|
|
2766
|
+
return this.subscription.subscribeOnKeys(this.keys, onUpdate);
|
|
2767
|
+
}
|
|
2768
|
+
};
|
|
2769
|
+
|
|
2770
|
+
// src/modules/selector/core/OIMCollectionByPksSelector.ts
|
|
2771
|
+
var OIMCollectionByPksSelector = class extends OIMSelector {
|
|
2772
|
+
constructor(runtime, collection, pks) {
|
|
2773
|
+
super(runtime, [
|
|
2774
|
+
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2775
|
+
collection,
|
|
2776
|
+
pks
|
|
2777
|
+
)
|
|
2778
|
+
]);
|
|
2779
|
+
this.collection = collection;
|
|
2780
|
+
this.pks = pks;
|
|
2781
|
+
}
|
|
2782
|
+
getValue() {
|
|
2783
|
+
return this.pks.map((pk) => this.collection.getOneByPk(pk));
|
|
2784
|
+
}
|
|
2785
|
+
areEqual(prev, next) {
|
|
2786
|
+
if (prev === next) return true;
|
|
2787
|
+
if (prev.length !== next.length) return false;
|
|
2788
|
+
for (let i = 0; i < prev.length; i++) {
|
|
2789
|
+
if (prev[i] !== next[i]) return false;
|
|
2790
|
+
}
|
|
2791
|
+
return true;
|
|
2792
|
+
}
|
|
2793
|
+
};
|
|
2794
|
+
|
|
2795
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased.ts
|
|
2796
|
+
var OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased = class {
|
|
2797
|
+
constructor(collection, reactiveIndex, key) {
|
|
2798
|
+
this.collection = collection;
|
|
2799
|
+
this.reactiveIndex = reactiveIndex;
|
|
2800
|
+
this.key = key;
|
|
2801
|
+
this.currentPks = [];
|
|
2802
|
+
}
|
|
2803
|
+
subscribe(onUpdate) {
|
|
2804
|
+
const resubscribeCollection = () => {
|
|
2805
|
+
const nextPks = this.reactiveIndex.getPksByKey(this.key);
|
|
2806
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
2807
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2808
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2809
|
+
this.currentPks = nextPks;
|
|
2810
|
+
if (this.currentPks.length === 0) return;
|
|
2811
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
2812
|
+
};
|
|
2813
|
+
const onIndexUpdate = () => {
|
|
2814
|
+
resubscribeCollection();
|
|
2815
|
+
onUpdate();
|
|
2816
|
+
};
|
|
2817
|
+
resubscribeCollection();
|
|
2818
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
2819
|
+
this.key,
|
|
2820
|
+
onIndexUpdate
|
|
2821
|
+
);
|
|
2822
|
+
return () => {
|
|
2823
|
+
unsubscribeFromIndex();
|
|
2824
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2825
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2826
|
+
this.currentPks = [];
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
sameArray(a, b) {
|
|
2830
|
+
if (a === b) return true;
|
|
2831
|
+
if (a.length !== b.length) return false;
|
|
2832
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
2833
|
+
return true;
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
|
|
2837
|
+
// src/modules/selector/core/OIMEntitiesByIndexKeyArrayBasedSelector.ts
|
|
2838
|
+
var OIMEntitiesByIndexKeyArrayBasedSelector = class extends OIMSelector {
|
|
2839
|
+
constructor(runtime, collection, reactiveIndex, key) {
|
|
2840
|
+
super(runtime, [
|
|
2841
|
+
new OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased(collection, reactiveIndex, key)
|
|
2842
|
+
]);
|
|
2843
|
+
this.collection = collection;
|
|
2844
|
+
this.reactiveIndex = reactiveIndex;
|
|
2845
|
+
this.key = key;
|
|
2846
|
+
}
|
|
2847
|
+
getValue() {
|
|
2848
|
+
const pks = this.reactiveIndex.getPksByKey(this.key);
|
|
2849
|
+
const entities = [];
|
|
2850
|
+
entities.length = pks.length;
|
|
2851
|
+
for (let i = 0; i < pks.length; i++) {
|
|
2852
|
+
entities[i] = this.collection.getOneByPk(pks[i]);
|
|
2853
|
+
}
|
|
2854
|
+
return entities;
|
|
2855
|
+
}
|
|
2856
|
+
areEqual(prev, next) {
|
|
2857
|
+
if (prev === next) return true;
|
|
2858
|
+
if (prev.length !== next.length) return false;
|
|
2859
|
+
for (let i = 0; i < prev.length; i++)
|
|
2860
|
+
if (prev[i] !== next[i]) return false;
|
|
2861
|
+
return true;
|
|
2862
|
+
}
|
|
2863
|
+
};
|
|
2864
|
+
|
|
2865
|
+
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeySetBased.ts
|
|
2866
|
+
var OIMSelectorSourceDependencyEntitiesByIndexKeySetBased = class {
|
|
2867
|
+
constructor(collection, reactiveIndex, key) {
|
|
2868
|
+
this.collection = collection;
|
|
2869
|
+
this.reactiveIndex = reactiveIndex;
|
|
2870
|
+
this.key = key;
|
|
2871
|
+
this.currentPks = [];
|
|
2872
|
+
}
|
|
2873
|
+
subscribe(onUpdate) {
|
|
2874
|
+
const resubscribeCollection = () => {
|
|
2875
|
+
const nextPks = Array.from(this.reactiveIndex.getPksByKey(this.key));
|
|
2876
|
+
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
2877
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2878
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2879
|
+
this.currentPks = nextPks;
|
|
2880
|
+
if (this.currentPks.length === 0) return;
|
|
2881
|
+
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
2882
|
+
};
|
|
2883
|
+
const onIndexUpdate = () => {
|
|
2884
|
+
resubscribeCollection();
|
|
2885
|
+
onUpdate();
|
|
2886
|
+
};
|
|
2887
|
+
resubscribeCollection();
|
|
2888
|
+
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
2889
|
+
this.key,
|
|
2890
|
+
onIndexUpdate
|
|
2891
|
+
);
|
|
2892
|
+
return () => {
|
|
2893
|
+
unsubscribeFromIndex();
|
|
2894
|
+
this.unsubscribeFromCollectionKeys?.();
|
|
2895
|
+
this.unsubscribeFromCollectionKeys = void 0;
|
|
2896
|
+
this.currentPks = [];
|
|
1800
2897
|
};
|
|
1801
2898
|
}
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
return () => false;
|
|
2899
|
+
sameArray(a, b) {
|
|
2900
|
+
if (a === b) return true;
|
|
2901
|
+
if (a.length !== b.length) return false;
|
|
2902
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
2903
|
+
return true;
|
|
1808
2904
|
}
|
|
1809
2905
|
};
|
|
1810
2906
|
|
|
1811
|
-
// src/core/
|
|
1812
|
-
var
|
|
1813
|
-
constructor() {
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
2907
|
+
// src/modules/selector/core/OIMEntitiesByIndexKeySetBasedSelector.ts
|
|
2908
|
+
var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
2909
|
+
constructor(runtime, collection, reactiveIndex, key) {
|
|
2910
|
+
super(runtime, [
|
|
2911
|
+
new OIMSelectorSourceDependencyEntitiesByIndexKeySetBased(collection, reactiveIndex, key)
|
|
2912
|
+
]);
|
|
2913
|
+
this.collection = collection;
|
|
2914
|
+
this.reactiveIndex = reactiveIndex;
|
|
2915
|
+
this.key = key;
|
|
1819
2916
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
2917
|
+
getValue() {
|
|
2918
|
+
const pks = this.reactiveIndex.getPksByKey(this.key);
|
|
2919
|
+
const entities = [];
|
|
2920
|
+
entities.length = pks.size;
|
|
2921
|
+
let writeIndex = 0;
|
|
2922
|
+
for (const pk of pks) {
|
|
2923
|
+
entities[writeIndex++] = this.collection.getOneByPk(pk);
|
|
1825
2924
|
}
|
|
1826
|
-
|
|
1827
|
-
m.set(k2, v);
|
|
2925
|
+
return entities;
|
|
1828
2926
|
}
|
|
1829
|
-
|
|
1830
|
-
|
|
2927
|
+
areEqual(prev, next) {
|
|
2928
|
+
if (prev === next) return true;
|
|
2929
|
+
if (prev.length !== next.length) return false;
|
|
2930
|
+
for (let i = 0; i < prev.length; i++)
|
|
2931
|
+
if (prev[i] !== next[i]) return false;
|
|
2932
|
+
return true;
|
|
1831
2933
|
}
|
|
1832
|
-
|
|
1833
|
-
|
|
2934
|
+
};
|
|
2935
|
+
|
|
2936
|
+
// src/dx/OIMCollectionSelectors.ts
|
|
2937
|
+
var OIMCollectionSelectors = class {
|
|
2938
|
+
constructor(queue, collection) {
|
|
2939
|
+
this.collection = collection;
|
|
2940
|
+
this.runtime = new OIMComputeRuntime(queue);
|
|
1834
2941
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
if (!m) return false;
|
|
1838
|
-
const had = m.delete(k2);
|
|
1839
|
-
if (had) {
|
|
1840
|
-
this._size--;
|
|
1841
|
-
if (m.size === 0) this.map.delete(k1);
|
|
1842
|
-
}
|
|
1843
|
-
return had;
|
|
2942
|
+
byPk(pk) {
|
|
2943
|
+
return new OIMCollectionByPkSelector(this.runtime, this.collection, pk);
|
|
1844
2944
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
2945
|
+
byPks(pks) {
|
|
2946
|
+
return new OIMCollectionByPksSelector(
|
|
2947
|
+
this.runtime,
|
|
2948
|
+
this.collection,
|
|
2949
|
+
pks
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2952
|
+
entitiesBySetIndexKey(index, key) {
|
|
2953
|
+
return new OIMEntitiesByIndexKeySetBasedSelector(
|
|
2954
|
+
this.runtime,
|
|
2955
|
+
this.collection,
|
|
2956
|
+
index,
|
|
2957
|
+
key
|
|
2958
|
+
);
|
|
2959
|
+
}
|
|
2960
|
+
entitiesByArrayIndexKey(index, key) {
|
|
2961
|
+
return new OIMEntitiesByIndexKeyArrayBasedSelector(
|
|
2962
|
+
this.runtime,
|
|
2963
|
+
this.collection,
|
|
2964
|
+
index,
|
|
2965
|
+
key
|
|
2966
|
+
);
|
|
1848
2967
|
}
|
|
1849
2968
|
};
|
|
1850
2969
|
|
|
1851
|
-
// src/
|
|
1852
|
-
|
|
2970
|
+
// src/dx/OIMCollectionContext.ts
|
|
2971
|
+
function createOIMCollectionContext(queue, opts) {
|
|
2972
|
+
const collection = new OIMReactiveCollection(queue, opts);
|
|
2973
|
+
const indexFactory = new OIMCollectionIndexFactory(queue, collection);
|
|
2974
|
+
const select = new OIMCollectionSelectors(queue, collection);
|
|
2975
|
+
return { queue, collection, indexFactory, select };
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2978
|
+
// src/modules/wrapper/collection/OIMCollectionChangedFields.ts
|
|
2979
|
+
var OIMCollectionChangedFields = class {
|
|
1853
2980
|
constructor(queue, collection, opts) {
|
|
1854
2981
|
this.isInWrite = false;
|
|
1855
2982
|
this.lastEntitySnapshotByPk = /* @__PURE__ */ new Map();
|
|
@@ -1869,7 +2996,7 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1869
2996
|
this.collection = collection;
|
|
1870
2997
|
this.selectPk = opts?.selectPk ?? (() => {
|
|
1871
2998
|
throw new Error(
|
|
1872
|
-
`[
|
|
2999
|
+
`[OIMCollectionChangedFields]: selectPk was not provided. Use upsertOneByPk(...) or pass opts.selectPk.`
|
|
1873
3000
|
);
|
|
1874
3001
|
});
|
|
1875
3002
|
this.changedPksEventEmitter = new OIMUpdateEventEmitter(
|
|
@@ -1892,31 +3019,34 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1892
3019
|
);
|
|
1893
3020
|
}
|
|
1894
3021
|
upsertOneByPk(pk, patch) {
|
|
1895
|
-
this.withWrite(() => {
|
|
3022
|
+
const slot = this.withWrite(() => {
|
|
1896
3023
|
this.trackPatch(pk, patch);
|
|
1897
|
-
this.collection.upsertOneByPk(pk, patch);
|
|
3024
|
+
return this.collection.upsertOneByPk(pk, patch);
|
|
1898
3025
|
});
|
|
1899
3026
|
this.updateEntitySnapshot(pk);
|
|
3027
|
+
return slot;
|
|
1900
3028
|
}
|
|
1901
3029
|
upsertOne(entity) {
|
|
1902
|
-
this.withWrite(() => {
|
|
3030
|
+
const slot = this.withWrite(() => {
|
|
1903
3031
|
const pk = this.selectPk(entity);
|
|
1904
3032
|
this.trackPatch(pk, entity);
|
|
1905
|
-
this.collection.upsertOne(entity);
|
|
3033
|
+
return this.collection.upsertOne(entity);
|
|
1906
3034
|
});
|
|
1907
|
-
this.updateEntitySnapshot(
|
|
3035
|
+
this.updateEntitySnapshot(slot.pk);
|
|
3036
|
+
return slot;
|
|
1908
3037
|
}
|
|
1909
3038
|
upsertMany(entities) {
|
|
1910
3039
|
const pks = [];
|
|
1911
|
-
this.withWrite(() => {
|
|
3040
|
+
const slots = this.withWrite(() => {
|
|
1912
3041
|
for (const entity of entities) {
|
|
1913
3042
|
const pk = this.selectPk(entity);
|
|
1914
3043
|
pks.push(pk);
|
|
1915
3044
|
this.trackPatch(pk, entity);
|
|
1916
3045
|
}
|
|
1917
|
-
this.collection.upsertMany(entities);
|
|
3046
|
+
return this.collection.upsertMany(entities);
|
|
1918
3047
|
});
|
|
1919
3048
|
for (let i = 0; i < pks.length; i++) this.updateEntitySnapshot(pks[i]);
|
|
3049
|
+
return slots;
|
|
1920
3050
|
}
|
|
1921
3051
|
getChangedFieldsByPk(pk) {
|
|
1922
3052
|
return this.changedFieldsByPk.get(pk) ?? /* @__PURE__ */ new Set();
|
|
@@ -1947,12 +3077,11 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1947
3077
|
}
|
|
1948
3078
|
withWrite(fn) {
|
|
1949
3079
|
if (this.isInWrite) {
|
|
1950
|
-
fn();
|
|
1951
|
-
return;
|
|
3080
|
+
return fn();
|
|
1952
3081
|
}
|
|
1953
3082
|
this.isInWrite = true;
|
|
1954
3083
|
try {
|
|
1955
|
-
fn();
|
|
3084
|
+
return fn();
|
|
1956
3085
|
} finally {
|
|
1957
3086
|
this.isInWrite = false;
|
|
1958
3087
|
}
|
|
@@ -1994,238 +3123,33 @@ var OIMCollectionChangedFieldsWrapper = class {
|
|
|
1994
3123
|
...entity
|
|
1995
3124
|
});
|
|
1996
3125
|
}
|
|
1997
|
-
trackChangedKeys(pk, keys) {
|
|
1998
|
-
let pkFields = this.changedFieldsByPk.get(pk);
|
|
1999
|
-
if (!pkFields) {
|
|
2000
|
-
pkFields = /* @__PURE__ */ new Set();
|
|
2001
|
-
this.changedFieldsByPk.set(pk, pkFields);
|
|
2002
|
-
}
|
|
2003
|
-
for (const key of keys) {
|
|
2004
|
-
pkFields.add(key);
|
|
2005
|
-
let fieldPks = this.changedPksByField.get(key);
|
|
2006
|
-
if (!fieldPks) {
|
|
2007
|
-
fieldPks = /* @__PURE__ */ new Set();
|
|
2008
|
-
this.changedPksByField.set(key, fieldPks);
|
|
2009
|
-
}
|
|
2010
|
-
fieldPks.add(pk);
|
|
2011
|
-
}
|
|
2012
|
-
this.changedPksEventEmitter.markUpdatedKeys([pk]);
|
|
2013
|
-
this.changedFieldsEventEmitter.markUpdatedKeys(keys);
|
|
2014
|
-
}
|
|
2015
|
-
trackPatch(pk, patch) {
|
|
2016
|
-
if (pk === void 0 || pk === null || pk === "") {
|
|
2017
|
-
throw new Error(
|
|
2018
|
-
`[OIMCollectionChangedFieldsWrapper]: PK is required to track changes.`
|
|
2019
|
-
);
|
|
2020
|
-
}
|
|
2021
|
-
const keys = Object.keys(patch);
|
|
2022
|
-
if (keys.length === 0) return;
|
|
2023
|
-
this.trackChangedKeys(pk, keys);
|
|
2024
|
-
}
|
|
2025
|
-
};
|
|
2026
|
-
|
|
2027
|
-
// src/modules/wrapper/index/OIMIndexManualOrderedArrayBased.ts
|
|
2028
|
-
var OIMIndexManualOrderedArrayBased = class extends OIMIndexArrayBased {
|
|
2029
|
-
clear(key) {
|
|
2030
|
-
if (key === void 0) {
|
|
2031
|
-
const keys = this.getKeys();
|
|
2032
|
-
if (keys.length > 0) {
|
|
2033
|
-
this.store.clear();
|
|
2034
|
-
this.emitUpdate(Array.from(keys));
|
|
2035
|
-
}
|
|
2036
|
-
return;
|
|
2037
|
-
}
|
|
2038
|
-
if (this.store.getOneByKey(key) !== void 0) {
|
|
2039
|
-
this.store.removeOneByKey(key);
|
|
2040
|
-
this.emitUpdate([key]);
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2043
|
-
push(key, itemKey) {
|
|
2044
|
-
const list = this.getOrCreateList(key);
|
|
2045
|
-
const index = list.length;
|
|
2046
|
-
list.push(itemKey);
|
|
2047
|
-
this.emitUpdate([key]);
|
|
2048
|
-
return index;
|
|
2049
|
-
}
|
|
2050
|
-
insertAt(key, index, itemKey) {
|
|
2051
|
-
const list = this.getOrCreateList(key);
|
|
2052
|
-
const safeIndex = Math.max(0, Math.min(index, list.length));
|
|
2053
|
-
list.splice(safeIndex, 0, itemKey);
|
|
2054
|
-
this.emitUpdate([key]);
|
|
2055
|
-
}
|
|
2056
|
-
removeAt(key, index) {
|
|
2057
|
-
const list = this.store.getOneByKey(key);
|
|
2058
|
-
if (!list) return void 0;
|
|
2059
|
-
if (index < 0 || index >= list.length) return void 0;
|
|
2060
|
-
const [removed] = list.splice(index, 1);
|
|
2061
|
-
if (list.length === 0) {
|
|
2062
|
-
this.store.removeOneByKey(key);
|
|
2063
|
-
}
|
|
2064
|
-
this.emitUpdate([key]);
|
|
2065
|
-
return removed;
|
|
2066
|
-
}
|
|
2067
|
-
move(key, fromIndex, toIndex) {
|
|
2068
|
-
const list = this.store.getOneByKey(key);
|
|
2069
|
-
if (!list) return void 0;
|
|
2070
|
-
if (fromIndex < 0 || fromIndex >= list.length) return void 0;
|
|
2071
|
-
if (toIndex < 0 || toIndex >= list.length) return void 0;
|
|
2072
|
-
if (fromIndex === toIndex) return list[fromIndex];
|
|
2073
|
-
const [itemKey] = list.splice(fromIndex, 1);
|
|
2074
|
-
if (itemKey === void 0) return void 0;
|
|
2075
|
-
list.splice(toIndex, 0, itemKey);
|
|
2076
|
-
this.emitUpdate([key]);
|
|
2077
|
-
return itemKey;
|
|
2078
|
-
}
|
|
2079
|
-
reset(key, itemKeys) {
|
|
2080
|
-
if (itemKeys.length === 0) {
|
|
2081
|
-
if (this.store.getOneByKey(key) !== void 0) {
|
|
2082
|
-
this.store.removeOneByKey(key);
|
|
2083
|
-
this.emitUpdate([key]);
|
|
2084
|
-
}
|
|
2085
|
-
return;
|
|
2086
|
-
}
|
|
2087
|
-
this.store.setOneByKey(key, Array.from(itemKeys));
|
|
2088
|
-
this.emitUpdate([key]);
|
|
2089
|
-
}
|
|
2090
|
-
getOrCreateList(key) {
|
|
2091
|
-
let list = this.store.getOneByKey(key);
|
|
2092
|
-
if (!list) {
|
|
2093
|
-
list = [];
|
|
2094
|
-
this.store.setOneByKey(key, list);
|
|
2095
|
-
}
|
|
2096
|
-
return list;
|
|
2097
|
-
}
|
|
2098
|
-
};
|
|
2099
|
-
|
|
2100
|
-
// src/modules/wrapper/index/OIMOrderedListIndexCommandStreamWrapper.ts
|
|
2101
|
-
var OIMOrderedListIndexCommandStreamWrapper = class {
|
|
2102
|
-
constructor(queue, index) {
|
|
2103
|
-
this.isInWrite = false;
|
|
2104
|
-
this.commandsByKey = /* @__PURE__ */ new Map();
|
|
2105
|
-
this.onAfterFlush = () => {
|
|
2106
|
-
this.commandsByKey.clear();
|
|
2107
|
-
};
|
|
2108
|
-
this.onIndexUpdate = (payload) => {
|
|
2109
|
-
if (this.isInWrite) return;
|
|
2110
|
-
if (payload.keys.length === 0) return;
|
|
2111
|
-
for (let i = 0; i < payload.keys.length; i++) {
|
|
2112
|
-
const key = payload.keys[i];
|
|
2113
|
-
const list = this.index.getPksByKey(key);
|
|
2114
|
-
this.appendCommand(key, { type: "set", keys: Array.from(list) });
|
|
2115
|
-
}
|
|
2116
|
-
};
|
|
2117
|
-
this.commandsEventEmitter = new OIMUpdateEventEmitter(
|
|
2118
|
-
queue,
|
|
2119
|
-
"after_flush"
|
|
2120
|
-
);
|
|
2121
|
-
this.index = index ?? new OIMIndexManualOrderedArrayBased();
|
|
2122
|
-
this.unsubscribeAfterFlush = queue.emitter.on(
|
|
2123
|
-
0 /* AFTER_FLUSH */,
|
|
2124
|
-
this.onAfterFlush
|
|
2125
|
-
);
|
|
2126
|
-
this.unsubscribeFromIndexEmitter = this.index.emitter.on(
|
|
2127
|
-
0 /* UPDATE */,
|
|
2128
|
-
this.onIndexUpdate
|
|
2129
|
-
);
|
|
2130
|
-
}
|
|
2131
|
-
getPksByKey(key) {
|
|
2132
|
-
return this.index.getPksByKey(key);
|
|
2133
|
-
}
|
|
2134
|
-
hasKey(key) {
|
|
2135
|
-
return this.index.hasKey(key);
|
|
2136
|
-
}
|
|
2137
|
-
getKeys() {
|
|
2138
|
-
return this.index.getKeys();
|
|
2139
|
-
}
|
|
2140
|
-
push(key, itemKey) {
|
|
2141
|
-
this.withWrite(() => {
|
|
2142
|
-
const index = this.index.push(key, itemKey);
|
|
2143
|
-
this.appendCommand(key, { type: "add", key: itemKey, index });
|
|
2144
|
-
});
|
|
2145
|
-
}
|
|
2146
|
-
removeAt(key, index) {
|
|
2147
|
-
this.withWrite(() => {
|
|
2148
|
-
const itemKey = this.index.removeAt(key, index);
|
|
2149
|
-
if (itemKey === void 0) return;
|
|
2150
|
-
this.appendCommand(key, { type: "remove", key: itemKey, index });
|
|
2151
|
-
});
|
|
2152
|
-
}
|
|
2153
|
-
move(key, fromIndex, toIndex) {
|
|
2154
|
-
this.withWrite(() => {
|
|
2155
|
-
const itemKey = this.index.move(key, fromIndex, toIndex);
|
|
2156
|
-
if (itemKey === void 0) return;
|
|
2157
|
-
this.appendCommand(key, {
|
|
2158
|
-
type: "move",
|
|
2159
|
-
key: itemKey,
|
|
2160
|
-
fromIndex,
|
|
2161
|
-
toIndex
|
|
2162
|
-
});
|
|
2163
|
-
});
|
|
2164
|
-
}
|
|
2165
|
-
set(key, keys) {
|
|
2166
|
-
this.withWrite(() => {
|
|
2167
|
-
this.index.reset(key, keys);
|
|
2168
|
-
this.appendCommand(key, { type: "set", keys });
|
|
2169
|
-
});
|
|
2170
|
-
}
|
|
2171
|
-
/**
|
|
2172
|
-
* Read-only peek at buffered commands without clearing them.
|
|
2173
|
-
*/
|
|
2174
|
-
getBufferedCommands(key) {
|
|
2175
|
-
return this.commandsByKey.get(key) ?? [];
|
|
2176
|
-
}
|
|
2177
|
-
/**
|
|
2178
|
-
* Drain buffered commands for a key, preserving order.
|
|
2179
|
-
* Intended usage: call inside a `commandsEventEmitter.subscribeOnKey(key, ...)` handler.
|
|
2180
|
-
*/
|
|
2181
|
-
consumeCommands(key) {
|
|
2182
|
-
const cmds = this.commandsByKey.get(key);
|
|
2183
|
-
if (!cmds || cmds.length === 0) return [];
|
|
2184
|
-
return cmds.slice();
|
|
2185
|
-
}
|
|
2186
|
-
clear(key) {
|
|
2187
|
-
if (key === void 0) {
|
|
2188
|
-
this.index.destroy();
|
|
2189
|
-
this.commandsByKey.clear();
|
|
2190
|
-
return;
|
|
2191
|
-
}
|
|
2192
|
-
this.index.clear(key);
|
|
2193
|
-
this.commandsByKey.delete(key);
|
|
2194
|
-
}
|
|
2195
|
-
destroy() {
|
|
2196
|
-
this.commandsEventEmitter.destroy();
|
|
2197
|
-
this.unsubscribeAfterFlush();
|
|
2198
|
-
this.unsubscribeFromIndexEmitter();
|
|
2199
|
-
this.clear();
|
|
2200
|
-
}
|
|
2201
|
-
withWrite(fn) {
|
|
2202
|
-
if (this.isInWrite) {
|
|
2203
|
-
fn();
|
|
2204
|
-
return;
|
|
3126
|
+
trackChangedKeys(pk, keys) {
|
|
3127
|
+
let pkFields = this.changedFieldsByPk.get(pk);
|
|
3128
|
+
if (!pkFields) {
|
|
3129
|
+
pkFields = /* @__PURE__ */ new Set();
|
|
3130
|
+
this.changedFieldsByPk.set(pk, pkFields);
|
|
2205
3131
|
}
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
3132
|
+
for (const key of keys) {
|
|
3133
|
+
pkFields.add(key);
|
|
3134
|
+
let fieldPks = this.changedPksByField.get(key);
|
|
3135
|
+
if (!fieldPks) {
|
|
3136
|
+
fieldPks = /* @__PURE__ */ new Set();
|
|
3137
|
+
this.changedPksByField.set(key, fieldPks);
|
|
3138
|
+
}
|
|
3139
|
+
fieldPks.add(pk);
|
|
2211
3140
|
}
|
|
3141
|
+
this.changedPksEventEmitter.markUpdatedKeys([pk]);
|
|
3142
|
+
this.changedFieldsEventEmitter.markUpdatedKeys(keys);
|
|
2212
3143
|
}
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
}
|
|
2219
|
-
if (cmd.type === "set") {
|
|
2220
|
-
cmds.length = 0;
|
|
2221
|
-
cmds.push(cmd);
|
|
2222
|
-
} else if (cmds.length > 0 && cmds[0].type === "set") {
|
|
2223
|
-
const setCmd = cmds[0];
|
|
2224
|
-
setCmd.keys = Array.from(this.index.getPksByKey(key));
|
|
2225
|
-
} else {
|
|
2226
|
-
cmds.push(cmd);
|
|
3144
|
+
trackPatch(pk, patch) {
|
|
3145
|
+
if (pk === void 0 || pk === null || pk === "") {
|
|
3146
|
+
throw new Error(
|
|
3147
|
+
`[OIMCollectionChangedFields]: PK is required to track changes.`
|
|
3148
|
+
);
|
|
2227
3149
|
}
|
|
2228
|
-
|
|
3150
|
+
const keys = Object.keys(patch);
|
|
3151
|
+
if (keys.length === 0) return;
|
|
3152
|
+
this.trackChangedKeys(pk, keys);
|
|
2229
3153
|
}
|
|
2230
3154
|
};
|
|
2231
3155
|
|
|
@@ -2341,7 +3265,9 @@ var OIMEventQueueSchedulerImmediate = class extends OIMEventQueueScheduler {
|
|
|
2341
3265
|
cancel() {
|
|
2342
3266
|
if (this.immediateId === void 0) return;
|
|
2343
3267
|
if (this.useSetImmediate) {
|
|
2344
|
-
clearImmediate(
|
|
3268
|
+
clearImmediate(
|
|
3269
|
+
this.immediateId
|
|
3270
|
+
);
|
|
2345
3271
|
} else if (this.useMessageChannel) {
|
|
2346
3272
|
this.pendingCallback = void 0;
|
|
2347
3273
|
} else {
|
|
@@ -2398,7 +3324,7 @@ var OIMEventQueueSchedulerFactory = class {
|
|
|
2398
3324
|
}
|
|
2399
3325
|
};
|
|
2400
3326
|
|
|
2401
|
-
// src/
|
|
3327
|
+
// src/constants/OIMDBSettings.ts
|
|
2402
3328
|
var OIMDBSettings = class {
|
|
2403
3329
|
};
|
|
2404
3330
|
/**
|
|
@@ -2410,11 +3336,11 @@ OIMDBSettings.FLUSHING_KEYS_INDEX_KEY = "__flushingKeys__";
|
|
|
2410
3336
|
|
|
2411
3337
|
// src/modules/effect/core/OIMEffectDependencyComputed.ts
|
|
2412
3338
|
var OIMEffectDependencyComputed = class {
|
|
2413
|
-
constructor(
|
|
2414
|
-
this.
|
|
3339
|
+
constructor(source) {
|
|
3340
|
+
this.source = source;
|
|
2415
3341
|
}
|
|
2416
3342
|
subscribe(onUpdate) {
|
|
2417
|
-
return this.
|
|
3343
|
+
return this.source.emitter.on("update", onUpdate);
|
|
2418
3344
|
}
|
|
2419
3345
|
};
|
|
2420
3346
|
|
|
@@ -2526,7 +3452,7 @@ var OIMEffect = class {
|
|
|
2526
3452
|
}
|
|
2527
3453
|
};
|
|
2528
3454
|
|
|
2529
|
-
// src/modules/computed/
|
|
3455
|
+
// src/modules/computed/enums/EOIMComputedEventType.ts
|
|
2530
3456
|
var EOIMComputedEventType = /* @__PURE__ */ ((EOIMComputedEventType2) => {
|
|
2531
3457
|
EOIMComputedEventType2["UPDATE"] = "update";
|
|
2532
3458
|
return EOIMComputedEventType2;
|
|
@@ -2541,13 +3467,13 @@ var OIMComputed = class {
|
|
|
2541
3467
|
this.runtime = runtime;
|
|
2542
3468
|
this.compute = opts.compute;
|
|
2543
3469
|
this.compare = opts.compare ?? Object.is;
|
|
2544
|
-
this.
|
|
3470
|
+
this._deps = opts.deps ?? [];
|
|
2545
3471
|
this.updateEventEmitter = new OIMUpdateEventEmitter(
|
|
2546
3472
|
this.runtime.queue,
|
|
2547
3473
|
"immediate"
|
|
2548
3474
|
);
|
|
2549
3475
|
this.effect = new OIMEffect(this.runtime, {
|
|
2550
|
-
deps: this.
|
|
3476
|
+
deps: this._deps,
|
|
2551
3477
|
onUpdate: () => {
|
|
2552
3478
|
this.isDirty = true;
|
|
2553
3479
|
},
|
|
@@ -2556,6 +3482,15 @@ var OIMComputed = class {
|
|
|
2556
3482
|
}
|
|
2557
3483
|
});
|
|
2558
3484
|
}
|
|
3485
|
+
get needsRecompute() {
|
|
3486
|
+
return this.isDirty;
|
|
3487
|
+
}
|
|
3488
|
+
get isReady() {
|
|
3489
|
+
return this.hasValue;
|
|
3490
|
+
}
|
|
3491
|
+
get deps() {
|
|
3492
|
+
return this._deps;
|
|
3493
|
+
}
|
|
2559
3494
|
get() {
|
|
2560
3495
|
this.recomputeAndEmitIfChanged();
|
|
2561
3496
|
return this.value;
|
|
@@ -2590,8 +3525,8 @@ function isReadonlyArray(value) {
|
|
|
2590
3525
|
return Array.isArray(value);
|
|
2591
3526
|
}
|
|
2592
3527
|
var OIMEffectDependencyKeyed = class {
|
|
2593
|
-
constructor(
|
|
2594
|
-
this.
|
|
3528
|
+
constructor(source, keyOrKeys) {
|
|
3529
|
+
this.source = source;
|
|
2595
3530
|
if (isReadonlyArray(keyOrKeys)) {
|
|
2596
3531
|
this.keys = keyOrKeys;
|
|
2597
3532
|
} else {
|
|
@@ -2600,11 +3535,11 @@ var OIMEffectDependencyKeyed = class {
|
|
|
2600
3535
|
}
|
|
2601
3536
|
subscribe(onUpdate) {
|
|
2602
3537
|
if (this.keys !== void 0) {
|
|
2603
|
-
return this.
|
|
3538
|
+
return this.source.subscribeOnKeys(this.keys, onUpdate);
|
|
2604
3539
|
}
|
|
2605
3540
|
if (this.key === void 0) return () => {
|
|
2606
3541
|
};
|
|
2607
|
-
return this.
|
|
3542
|
+
return this.source.subscribeOnKey(this.key, onUpdate);
|
|
2608
3543
|
}
|
|
2609
3544
|
};
|
|
2610
3545
|
|
|
@@ -2616,6 +3551,9 @@ var OIMEffectDependencyKeyedObject = class {
|
|
|
2616
3551
|
keyOrKeys
|
|
2617
3552
|
);
|
|
2618
3553
|
}
|
|
3554
|
+
get source() {
|
|
3555
|
+
return this.dep.source;
|
|
3556
|
+
}
|
|
2619
3557
|
subscribe(onUpdate) {
|
|
2620
3558
|
return this.dep.subscribe(onUpdate);
|
|
2621
3559
|
}
|
|
@@ -2625,221 +3563,31 @@ var OIMEffectDependencyKeyedObject = class {
|
|
|
2625
3563
|
var OIMEffectDependencyKeyedCollection = class {
|
|
2626
3564
|
constructor(collection, pkOrPks) {
|
|
2627
3565
|
this.dep = new OIMEffectDependencyKeyed(
|
|
2628
|
-
collection,
|
|
2629
|
-
pkOrPks
|
|
2630
|
-
);
|
|
2631
|
-
}
|
|
2632
|
-
subscribe(onUpdate) {
|
|
2633
|
-
return this.dep.subscribe(onUpdate);
|
|
2634
|
-
}
|
|
2635
|
-
};
|
|
2636
|
-
|
|
2637
|
-
// src/modules/effect/core/OIMEffectDependencyKeyedIndex.ts
|
|
2638
|
-
var OIMEffectDependencyKeyedIndex = class {
|
|
2639
|
-
constructor(index, keyOrKeys) {
|
|
2640
|
-
this.dep = new OIMEffectDependencyKeyed(
|
|
2641
|
-
index,
|
|
2642
|
-
keyOrKeys
|
|
2643
|
-
);
|
|
2644
|
-
}
|
|
2645
|
-
subscribe(onUpdate) {
|
|
2646
|
-
return this.dep.subscribe(onUpdate);
|
|
2647
|
-
}
|
|
2648
|
-
};
|
|
2649
|
-
|
|
2650
|
-
// src/modules/selector/core/OIMSelector.ts
|
|
2651
|
-
var OIMSelector = class {
|
|
2652
|
-
constructor(runtime, sourceDeps, computedDeps = []) {
|
|
2653
|
-
this.runtime = runtime;
|
|
2654
|
-
this.sourceDeps = sourceDeps;
|
|
2655
|
-
this.computedDeps = computedDeps;
|
|
2656
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
2657
|
-
this.sourceUnsubscribers = [];
|
|
2658
|
-
this.computedUnsubscribers = [];
|
|
2659
|
-
this.isResubscribeEnqueued = false;
|
|
2660
|
-
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2661
|
-
this.isDeliveryEnqueued = false;
|
|
2662
|
-
this.hasLastValue = false;
|
|
2663
|
-
this.onSourceInvalidate = () => {
|
|
2664
|
-
if (this.listeners.size === 0) return;
|
|
2665
|
-
if (!this.isTemporarilyUnsubscribedForFlush) {
|
|
2666
|
-
this.isTemporarilyUnsubscribedForFlush = true;
|
|
2667
|
-
this.unsubscribeFromSourceDeps();
|
|
2668
|
-
this.ensureResubscribeAfterFlush();
|
|
2669
|
-
}
|
|
2670
|
-
if (this.isDeliveryEnqueued) return;
|
|
2671
|
-
this.isDeliveryEnqueued = true;
|
|
2672
|
-
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2673
|
-
};
|
|
2674
|
-
this.onComputedInvalidate = () => {
|
|
2675
|
-
if (this.listeners.size === 0) return;
|
|
2676
|
-
if (this.isDeliveryEnqueued) return;
|
|
2677
|
-
this.isDeliveryEnqueued = true;
|
|
2678
|
-
this.dequeueDelivery = this.runtime.schedule(this.deliver);
|
|
2679
|
-
};
|
|
2680
|
-
this.deliver = () => {
|
|
2681
|
-
this.isDeliveryEnqueued = false;
|
|
2682
|
-
this.dequeueDelivery = void 0;
|
|
2683
|
-
if (this.listeners.size === 0) return;
|
|
2684
|
-
const next = this.getValue();
|
|
2685
|
-
if (this.hasLastValue && this.areEqual(this.lastValue, next)) return;
|
|
2686
|
-
this.setLastValue(next);
|
|
2687
|
-
const snapshot = Array.from(this.listeners);
|
|
2688
|
-
for (let i = 0; i < snapshot.length; i++) {
|
|
2689
|
-
const listener = snapshot[i];
|
|
2690
|
-
if (this.listeners.has(listener)) listener(next);
|
|
2691
|
-
}
|
|
2692
|
-
};
|
|
2693
|
-
this.onAfterFlush = () => {
|
|
2694
|
-
if (!this.isResubscribeEnqueued) return;
|
|
2695
|
-
this.isResubscribeEnqueued = false;
|
|
2696
|
-
this.dequeueResubscribe = void 0;
|
|
2697
|
-
if (this.listeners.size === 0) return;
|
|
2698
|
-
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2699
|
-
if (this.sourceUnsubscribers.length === 0) {
|
|
2700
|
-
for (const dep of this.sourceDeps) {
|
|
2701
|
-
this.sourceUnsubscribers.push(
|
|
2702
|
-
dep.subscribe(this.onSourceInvalidate)
|
|
2703
|
-
);
|
|
2704
|
-
}
|
|
2705
|
-
}
|
|
2706
|
-
};
|
|
2707
|
-
}
|
|
2708
|
-
get queue() {
|
|
2709
|
-
return this.runtime.queue;
|
|
2710
|
-
}
|
|
2711
|
-
/**
|
|
2712
|
-
* Start watching this selector. The callback is called immediately with the current value,
|
|
2713
|
-
* then coalesced and delivered on `queue.flush()` when the selector invalidates.
|
|
2714
|
-
*/
|
|
2715
|
-
watch(onValue) {
|
|
2716
|
-
this.listeners.add(onValue);
|
|
2717
|
-
if (this.listeners.size === 1) {
|
|
2718
|
-
this.subscribeToDeps();
|
|
2719
|
-
}
|
|
2720
|
-
const current = this.getValue();
|
|
2721
|
-
this.setLastValue(current);
|
|
2722
|
-
onValue(current);
|
|
2723
|
-
return () => {
|
|
2724
|
-
this.listeners.delete(onValue);
|
|
2725
|
-
if (this.listeners.size > 0) return;
|
|
2726
|
-
this.unsubscribeFromAllDeps();
|
|
2727
|
-
if (this.dequeueResubscribe) {
|
|
2728
|
-
this.dequeueResubscribe();
|
|
2729
|
-
this.dequeueResubscribe = void 0;
|
|
2730
|
-
}
|
|
2731
|
-
this.isResubscribeEnqueued = false;
|
|
2732
|
-
this.isTemporarilyUnsubscribedForFlush = false;
|
|
2733
|
-
if (this.dequeueDelivery) {
|
|
2734
|
-
this.dequeueDelivery();
|
|
2735
|
-
this.dequeueDelivery = void 0;
|
|
2736
|
-
}
|
|
2737
|
-
this.isDeliveryEnqueued = false;
|
|
2738
|
-
this.hasLastValue = false;
|
|
2739
|
-
};
|
|
2740
|
-
}
|
|
2741
|
-
areEqual(prev, next) {
|
|
2742
|
-
return Object.is(prev, next);
|
|
2743
|
-
}
|
|
2744
|
-
setLastValue(value) {
|
|
2745
|
-
this.lastValue = value;
|
|
2746
|
-
this.hasLastValue = true;
|
|
2747
|
-
}
|
|
2748
|
-
subscribeToDeps() {
|
|
2749
|
-
if (this.sourceUnsubscribers.length > 0 || this.computedUnsubscribers.length > 0)
|
|
2750
|
-
return;
|
|
2751
|
-
for (const dep of this.sourceDeps) {
|
|
2752
|
-
this.sourceUnsubscribers.push(
|
|
2753
|
-
dep.subscribe(this.onSourceInvalidate)
|
|
2754
|
-
);
|
|
2755
|
-
}
|
|
2756
|
-
for (const dep of this.computedDeps) {
|
|
2757
|
-
this.computedUnsubscribers.push(
|
|
2758
|
-
dep.subscribe(this.onComputedInvalidate)
|
|
2759
|
-
);
|
|
2760
|
-
}
|
|
2761
|
-
}
|
|
2762
|
-
unsubscribeFromSourceDeps() {
|
|
2763
|
-
if (this.sourceUnsubscribers.length === 0) return;
|
|
2764
|
-
for (const unsub of this.sourceUnsubscribers) unsub();
|
|
2765
|
-
this.sourceUnsubscribers = [];
|
|
2766
|
-
}
|
|
2767
|
-
unsubscribeFromAllDeps() {
|
|
2768
|
-
this.unsubscribeFromSourceDeps();
|
|
2769
|
-
if (this.computedUnsubscribers.length === 0) return;
|
|
2770
|
-
for (const unsub of this.computedUnsubscribers) unsub();
|
|
2771
|
-
this.computedUnsubscribers = [];
|
|
2772
|
-
}
|
|
2773
|
-
ensureResubscribeAfterFlush() {
|
|
2774
|
-
if (this.isResubscribeEnqueued) return;
|
|
2775
|
-
this.isResubscribeEnqueued = true;
|
|
2776
|
-
this.dequeueResubscribe = this.runtime.scheduleAfterFlush(
|
|
2777
|
-
this.onAfterFlush
|
|
2778
|
-
);
|
|
2779
|
-
}
|
|
2780
|
-
};
|
|
2781
|
-
|
|
2782
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKey.ts
|
|
2783
|
-
var OIMSelectorSourceDependencyUpdateEventEmitterKey = class {
|
|
2784
|
-
constructor(subscription, key) {
|
|
2785
|
-
this.subscription = subscription;
|
|
2786
|
-
this.key = key;
|
|
2787
|
-
}
|
|
2788
|
-
subscribe(onUpdate) {
|
|
2789
|
-
return this.subscription.subscribeOnKey(this.key, onUpdate);
|
|
2790
|
-
}
|
|
2791
|
-
};
|
|
2792
|
-
|
|
2793
|
-
// src/modules/selector/core/OIMCollectionByPkSelector.ts
|
|
2794
|
-
var OIMCollectionByPkSelector = class extends OIMSelector {
|
|
2795
|
-
constructor(runtime, collection, pk) {
|
|
2796
|
-
super(runtime, [
|
|
2797
|
-
new OIMSelectorSourceDependencyUpdateEventEmitterKey(
|
|
2798
|
-
collection,
|
|
2799
|
-
pk
|
|
2800
|
-
)
|
|
2801
|
-
]);
|
|
2802
|
-
this.collection = collection;
|
|
2803
|
-
this.pk = pk;
|
|
2804
|
-
}
|
|
2805
|
-
getValue() {
|
|
2806
|
-
return this.collection.getOneByPk(this.pk);
|
|
2807
|
-
}
|
|
2808
|
-
};
|
|
2809
|
-
|
|
2810
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyUpdateEventEmitterKeys.ts
|
|
2811
|
-
var OIMSelectorSourceDependencyUpdateEventEmitterKeys = class {
|
|
2812
|
-
constructor(subscription, keys) {
|
|
2813
|
-
this.subscription = subscription;
|
|
2814
|
-
this.keys = keys;
|
|
2815
|
-
}
|
|
2816
|
-
subscribe(onUpdate) {
|
|
2817
|
-
return this.subscription.subscribeOnKeys(this.keys, onUpdate);
|
|
2818
|
-
}
|
|
2819
|
-
};
|
|
2820
|
-
|
|
2821
|
-
// src/modules/selector/core/OIMCollectionByPksSelector.ts
|
|
2822
|
-
var OIMCollectionByPksSelector = class extends OIMSelector {
|
|
2823
|
-
constructor(runtime, collection, pks) {
|
|
2824
|
-
super(runtime, [
|
|
2825
|
-
new OIMSelectorSourceDependencyUpdateEventEmitterKeys(
|
|
2826
|
-
collection,
|
|
2827
|
-
pks
|
|
2828
|
-
)
|
|
2829
|
-
]);
|
|
2830
|
-
this.collection = collection;
|
|
2831
|
-
this.pks = pks;
|
|
3566
|
+
collection,
|
|
3567
|
+
pkOrPks
|
|
3568
|
+
);
|
|
2832
3569
|
}
|
|
2833
|
-
|
|
2834
|
-
return this.
|
|
3570
|
+
get source() {
|
|
3571
|
+
return this.dep.source;
|
|
2835
3572
|
}
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
3573
|
+
subscribe(onUpdate) {
|
|
3574
|
+
return this.dep.subscribe(onUpdate);
|
|
3575
|
+
}
|
|
3576
|
+
};
|
|
3577
|
+
|
|
3578
|
+
// src/modules/effect/core/OIMEffectDependencyKeyedIndex.ts
|
|
3579
|
+
var OIMEffectDependencyKeyedIndex = class {
|
|
3580
|
+
constructor(index, keyOrKeys) {
|
|
3581
|
+
this.dep = new OIMEffectDependencyKeyed(
|
|
3582
|
+
index,
|
|
3583
|
+
keyOrKeys
|
|
3584
|
+
);
|
|
3585
|
+
}
|
|
3586
|
+
get source() {
|
|
3587
|
+
return this.dep.source;
|
|
3588
|
+
}
|
|
3589
|
+
subscribe(onUpdate) {
|
|
3590
|
+
return this.dep.subscribe(onUpdate);
|
|
2843
3591
|
}
|
|
2844
3592
|
};
|
|
2845
3593
|
|
|
@@ -2973,241 +3721,6 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
2973
3721
|
return true;
|
|
2974
3722
|
}
|
|
2975
3723
|
};
|
|
2976
|
-
|
|
2977
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeySetBased.ts
|
|
2978
|
-
var OIMSelectorSourceDependencyEntitiesByIndexKeySetBased = class {
|
|
2979
|
-
constructor(collection, reactiveIndex, key) {
|
|
2980
|
-
this.collection = collection;
|
|
2981
|
-
this.reactiveIndex = reactiveIndex;
|
|
2982
|
-
this.key = key;
|
|
2983
|
-
this.currentPks = [];
|
|
2984
|
-
}
|
|
2985
|
-
subscribe(onUpdate) {
|
|
2986
|
-
const resubscribeCollection = () => {
|
|
2987
|
-
const nextPks = Array.from(
|
|
2988
|
-
this.reactiveIndex.getPksByKey(this.key)
|
|
2989
|
-
);
|
|
2990
|
-
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
2991
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
2992
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
2993
|
-
this.currentPks = nextPks;
|
|
2994
|
-
if (this.currentPks.length === 0) return;
|
|
2995
|
-
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
2996
|
-
};
|
|
2997
|
-
const onIndexUpdate = () => {
|
|
2998
|
-
resubscribeCollection();
|
|
2999
|
-
onUpdate();
|
|
3000
|
-
};
|
|
3001
|
-
resubscribeCollection();
|
|
3002
|
-
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
3003
|
-
this.key,
|
|
3004
|
-
onIndexUpdate
|
|
3005
|
-
);
|
|
3006
|
-
return () => {
|
|
3007
|
-
unsubscribeFromIndex();
|
|
3008
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3009
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3010
|
-
this.currentPks = [];
|
|
3011
|
-
};
|
|
3012
|
-
}
|
|
3013
|
-
sameArray(a, b) {
|
|
3014
|
-
if (a === b) return true;
|
|
3015
|
-
if (a.length !== b.length) return false;
|
|
3016
|
-
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3017
|
-
return true;
|
|
3018
|
-
}
|
|
3019
|
-
};
|
|
3020
|
-
|
|
3021
|
-
// src/modules/selector/core/OIMEntitiesByIndexKeySetBasedSelector.ts
|
|
3022
|
-
var OIMEntitiesByIndexKeySetBasedSelector = class extends OIMSelector {
|
|
3023
|
-
constructor(runtime, collection, reactiveIndex, key) {
|
|
3024
|
-
super(runtime, [
|
|
3025
|
-
new OIMSelectorSourceDependencyEntitiesByIndexKeySetBased(collection, reactiveIndex, key)
|
|
3026
|
-
]);
|
|
3027
|
-
this.collection = collection;
|
|
3028
|
-
this.reactiveIndex = reactiveIndex;
|
|
3029
|
-
this.key = key;
|
|
3030
|
-
}
|
|
3031
|
-
getValue() {
|
|
3032
|
-
const pks = Array.from(this.reactiveIndex.getPksByKey(this.key));
|
|
3033
|
-
return pks.map((pk) => this.collection.getOneByPk(pk));
|
|
3034
|
-
}
|
|
3035
|
-
areEqual(prev, next) {
|
|
3036
|
-
if (prev === next) return true;
|
|
3037
|
-
if (prev.length !== next.length) return false;
|
|
3038
|
-
for (let i = 0; i < prev.length; i++)
|
|
3039
|
-
if (prev[i] !== next[i]) return false;
|
|
3040
|
-
return true;
|
|
3041
|
-
}
|
|
3042
|
-
};
|
|
3043
|
-
|
|
3044
|
-
// src/modules/selector/core/OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased.ts
|
|
3045
|
-
var OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased = class {
|
|
3046
|
-
constructor(collection, reactiveIndex, key) {
|
|
3047
|
-
this.collection = collection;
|
|
3048
|
-
this.reactiveIndex = reactiveIndex;
|
|
3049
|
-
this.key = key;
|
|
3050
|
-
this.currentPks = [];
|
|
3051
|
-
}
|
|
3052
|
-
subscribe(onUpdate) {
|
|
3053
|
-
const resubscribeCollection = () => {
|
|
3054
|
-
const nextPks = this.reactiveIndex.getPksByKey(this.key);
|
|
3055
|
-
if (this.sameArray(this.currentPks, nextPks)) return;
|
|
3056
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3057
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3058
|
-
this.currentPks = nextPks;
|
|
3059
|
-
if (this.currentPks.length === 0) return;
|
|
3060
|
-
this.unsubscribeFromCollectionKeys = this.collection.subscribeOnKeys(this.currentPks, onUpdate);
|
|
3061
|
-
};
|
|
3062
|
-
const onIndexUpdate = () => {
|
|
3063
|
-
resubscribeCollection();
|
|
3064
|
-
onUpdate();
|
|
3065
|
-
};
|
|
3066
|
-
resubscribeCollection();
|
|
3067
|
-
const unsubscribeFromIndex = this.reactiveIndex.subscribeOnKey(
|
|
3068
|
-
this.key,
|
|
3069
|
-
onIndexUpdate
|
|
3070
|
-
);
|
|
3071
|
-
return () => {
|
|
3072
|
-
unsubscribeFromIndex();
|
|
3073
|
-
this.unsubscribeFromCollectionKeys?.();
|
|
3074
|
-
this.unsubscribeFromCollectionKeys = void 0;
|
|
3075
|
-
this.currentPks = [];
|
|
3076
|
-
};
|
|
3077
|
-
}
|
|
3078
|
-
sameArray(a, b) {
|
|
3079
|
-
if (a === b) return true;
|
|
3080
|
-
if (a.length !== b.length) return false;
|
|
3081
|
-
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
3082
|
-
return true;
|
|
3083
|
-
}
|
|
3084
|
-
};
|
|
3085
|
-
|
|
3086
|
-
// src/modules/selector/core/OIMEntitiesByIndexKeyArrayBasedSelector.ts
|
|
3087
|
-
var OIMEntitiesByIndexKeyArrayBasedSelector = class extends OIMSelector {
|
|
3088
|
-
constructor(runtime, collection, reactiveIndex, key) {
|
|
3089
|
-
super(runtime, [
|
|
3090
|
-
new OIMSelectorSourceDependencyEntitiesByIndexKeyArrayBased(collection, reactiveIndex, key)
|
|
3091
|
-
]);
|
|
3092
|
-
this.collection = collection;
|
|
3093
|
-
this.reactiveIndex = reactiveIndex;
|
|
3094
|
-
this.key = key;
|
|
3095
|
-
}
|
|
3096
|
-
getValue() {
|
|
3097
|
-
const pks = this.reactiveIndex.getPksByKey(this.key);
|
|
3098
|
-
return pks.map((pk) => this.collection.getOneByPk(pk));
|
|
3099
|
-
}
|
|
3100
|
-
areEqual(prev, next) {
|
|
3101
|
-
if (prev === next) return true;
|
|
3102
|
-
if (prev.length !== next.length) return false;
|
|
3103
|
-
for (let i = 0; i < prev.length; i++)
|
|
3104
|
-
if (prev[i] !== next[i]) return false;
|
|
3105
|
-
return true;
|
|
3106
|
-
}
|
|
3107
|
-
};
|
|
3108
|
-
|
|
3109
|
-
// src/modules/computative/core/OIMComputativeRuntime.ts
|
|
3110
|
-
var OIMComputativeRuntime = class {
|
|
3111
|
-
constructor(queue) {
|
|
3112
|
-
this.queue = queue;
|
|
3113
|
-
this.isFlushScheduled = false;
|
|
3114
|
-
this.isFlushing = false;
|
|
3115
|
-
this.minLevel = Infinity;
|
|
3116
|
-
this.maxLevel = -Infinity;
|
|
3117
|
-
this.dirtyByLevel = /* @__PURE__ */ new Map();
|
|
3118
|
-
this.afterFlushTasks = /* @__PURE__ */ new Set();
|
|
3119
|
-
this.queue.emitter.on(0 /* AFTER_FLUSH */, () => {
|
|
3120
|
-
if (!this.isFlushScheduled) return;
|
|
3121
|
-
this.flush();
|
|
3122
|
-
});
|
|
3123
|
-
}
|
|
3124
|
-
/**
|
|
3125
|
-
* Schedule a one-shot task to run on the next `queue.flush()` (AFTER_FLUSH),
|
|
3126
|
-
* ordered by `level` ascending.
|
|
3127
|
-
*/
|
|
3128
|
-
schedule(task, level = 0) {
|
|
3129
|
-
let isActive = true;
|
|
3130
|
-
const wrapped = () => {
|
|
3131
|
-
if (!isActive) return;
|
|
3132
|
-
task();
|
|
3133
|
-
};
|
|
3134
|
-
let bucket = this.dirtyByLevel.get(level);
|
|
3135
|
-
if (!bucket) {
|
|
3136
|
-
bucket = /* @__PURE__ */ new Set();
|
|
3137
|
-
this.dirtyByLevel.set(level, bucket);
|
|
3138
|
-
}
|
|
3139
|
-
bucket.add(wrapped);
|
|
3140
|
-
if (level < this.minLevel) this.minLevel = level;
|
|
3141
|
-
if (level > this.maxLevel) this.maxLevel = level;
|
|
3142
|
-
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
3143
|
-
return () => {
|
|
3144
|
-
if (!isActive) return;
|
|
3145
|
-
isActive = false;
|
|
3146
|
-
bucket.delete(wrapped);
|
|
3147
|
-
};
|
|
3148
|
-
}
|
|
3149
|
-
/**
|
|
3150
|
-
* Run once at the start of the next runtime flush (i.e. after queue.flush()).
|
|
3151
|
-
* Useful for resubscribing dependencies exactly once per source flush.
|
|
3152
|
-
*/
|
|
3153
|
-
scheduleAfterFlush(task) {
|
|
3154
|
-
let isActive = true;
|
|
3155
|
-
const wrapped = () => {
|
|
3156
|
-
if (!isActive) return;
|
|
3157
|
-
task();
|
|
3158
|
-
};
|
|
3159
|
-
this.afterFlushTasks.add(wrapped);
|
|
3160
|
-
if (!this.isFlushing) this.isFlushScheduled = true;
|
|
3161
|
-
return () => {
|
|
3162
|
-
if (!isActive) return;
|
|
3163
|
-
isActive = false;
|
|
3164
|
-
this.afterFlushTasks.delete(wrapped);
|
|
3165
|
-
};
|
|
3166
|
-
}
|
|
3167
|
-
flush() {
|
|
3168
|
-
this.isFlushScheduled = false;
|
|
3169
|
-
if (this.dirtyByLevel.size === 0 && this.afterFlushTasks.size === 0)
|
|
3170
|
-
return;
|
|
3171
|
-
this.isFlushing = true;
|
|
3172
|
-
try {
|
|
3173
|
-
if (this.afterFlushTasks.size > 0) {
|
|
3174
|
-
const snapshot = Array.from(this.afterFlushTasks);
|
|
3175
|
-
this.afterFlushTasks.clear();
|
|
3176
|
-
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
3177
|
-
}
|
|
3178
|
-
if (this.dirtyByLevel.size === 0) return;
|
|
3179
|
-
let level = this.minLevel;
|
|
3180
|
-
let max = this.maxLevel;
|
|
3181
|
-
while (level <= max) {
|
|
3182
|
-
for (; ; ) {
|
|
3183
|
-
const bucket = this.dirtyByLevel.get(level);
|
|
3184
|
-
if (!bucket || bucket.size === 0) break;
|
|
3185
|
-
this.dirtyByLevel.delete(level);
|
|
3186
|
-
const snapshot = Array.from(bucket);
|
|
3187
|
-
for (let i = 0; i < snapshot.length; i++) snapshot[i]();
|
|
3188
|
-
}
|
|
3189
|
-
if (this.maxLevel > max) max = this.maxLevel;
|
|
3190
|
-
level++;
|
|
3191
|
-
}
|
|
3192
|
-
} finally {
|
|
3193
|
-
this.isFlushing = false;
|
|
3194
|
-
if (this.dirtyByLevel.size === 0) {
|
|
3195
|
-
this.minLevel = Infinity;
|
|
3196
|
-
this.maxLevel = -Infinity;
|
|
3197
|
-
} else {
|
|
3198
|
-
let nextMin = Infinity;
|
|
3199
|
-
let nextMax = -Infinity;
|
|
3200
|
-
this.dirtyByLevel.forEach((_bucket, lvl) => {
|
|
3201
|
-
if (lvl < nextMin) nextMin = lvl;
|
|
3202
|
-
if (lvl > nextMax) nextMax = lvl;
|
|
3203
|
-
});
|
|
3204
|
-
this.minLevel = nextMin;
|
|
3205
|
-
this.maxLevel = nextMax;
|
|
3206
|
-
this.isFlushScheduled = true;
|
|
3207
|
-
}
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
};
|
|
3211
3724
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3212
3725
|
0 && (module.exports = {
|
|
3213
3726
|
EOIMCollectionEventType,
|
|
@@ -3219,13 +3732,19 @@ var OIMComputativeRuntime = class {
|
|
|
3219
3732
|
OIMCollection,
|
|
3220
3733
|
OIMCollectionByPkSelector,
|
|
3221
3734
|
OIMCollectionByPksSelector,
|
|
3222
|
-
|
|
3735
|
+
OIMCollectionChangedFields,
|
|
3736
|
+
OIMCollectionIndexFactory,
|
|
3737
|
+
OIMCollectionIndexManualOrderedArrayBased,
|
|
3738
|
+
OIMCollectionOrderedListCommandStream,
|
|
3739
|
+
OIMCollectionSelectors,
|
|
3223
3740
|
OIMCollectionStore,
|
|
3224
3741
|
OIMCollectionStoreMapDriven,
|
|
3225
3742
|
OIMComparatorFactory,
|
|
3226
|
-
|
|
3743
|
+
OIMComputeRuntime,
|
|
3227
3744
|
OIMComputed,
|
|
3228
3745
|
OIMDBSettings,
|
|
3746
|
+
OIMDerivedCollectionIndexArrayBased,
|
|
3747
|
+
OIMDerivedCollectionIndexSetBased,
|
|
3229
3748
|
OIMEffect,
|
|
3230
3749
|
OIMEffectDependencyComputed,
|
|
3231
3750
|
OIMEffectDependencyKeyed,
|
|
@@ -3243,6 +3762,7 @@ var OIMComputativeRuntime = class {
|
|
|
3243
3762
|
OIMEventQueueSchedulerImmediate,
|
|
3244
3763
|
OIMEventQueueSchedulerMicrotask,
|
|
3245
3764
|
OIMEventQueueSchedulerTimeout,
|
|
3765
|
+
OIMIndex,
|
|
3246
3766
|
OIMIndexArrayBased,
|
|
3247
3767
|
OIMIndexComparatorFactory,
|
|
3248
3768
|
OIMIndexManualArrayBased,
|
|
@@ -3264,14 +3784,18 @@ var OIMComputativeRuntime = class {
|
|
|
3264
3784
|
OIMObjectStoreRecordDriven,
|
|
3265
3785
|
OIMObjectValueByKeySelector,
|
|
3266
3786
|
OIMObjectValuesByKeysSelector,
|
|
3267
|
-
|
|
3787
|
+
OIMOrderedListCommandStream,
|
|
3268
3788
|
OIMPkSelectorFactory,
|
|
3269
|
-
OIMRICollection,
|
|
3270
3789
|
OIMReactiveCollection,
|
|
3790
|
+
OIMReactiveCollectionIndexManualArrayBased,
|
|
3791
|
+
OIMReactiveCollectionIndexManualSetBased,
|
|
3792
|
+
OIMReactiveIndex,
|
|
3271
3793
|
OIMReactiveIndexArrayBased,
|
|
3272
3794
|
OIMReactiveIndexManualArrayBased,
|
|
3273
3795
|
OIMReactiveIndexManualSetBased,
|
|
3274
3796
|
OIMReactiveIndexSetBased,
|
|
3275
3797
|
OIMReactiveObject,
|
|
3276
|
-
OIMSelector
|
|
3798
|
+
OIMSelector,
|
|
3799
|
+
createOIMCollectionContext,
|
|
3800
|
+
createOIMCollectionIndexFactory
|
|
3277
3801
|
});
|