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