@oimdb/core 2.0.1 → 2.2.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 +7 -7
- package/dist/index.cjs +48 -22
- package/dist/index.d.cts +13 -3
- package/dist/index.d.ts +13 -3
- package/dist/index.js +46 -20
- package/llms.txt +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,7 +94,7 @@ Use the `dx` factories when you want a concise entrypoint without changing the u
|
|
|
94
94
|
|
|
95
95
|
```typescript
|
|
96
96
|
import {
|
|
97
|
-
|
|
97
|
+
createOIMCollectionKit,
|
|
98
98
|
OIMEventQueue,
|
|
99
99
|
OIMEventQueueSchedulerFactory
|
|
100
100
|
} from '@oimdb/core';
|
|
@@ -108,7 +108,7 @@ type User = {
|
|
|
108
108
|
const queue = new OIMEventQueue({
|
|
109
109
|
scheduler: OIMEventQueueSchedulerFactory.createMicrotask()
|
|
110
110
|
});
|
|
111
|
-
const users =
|
|
111
|
+
const users = createOIMCollectionKit<User, string>(queue, {
|
|
112
112
|
selectPk: user => user.id,
|
|
113
113
|
});
|
|
114
114
|
|
|
@@ -191,7 +191,7 @@ OIMDB provides two types of indexes optimized for different use cases:
|
|
|
191
191
|
|
|
192
192
|
Indexes are slot-backed internally and expose PK projections through `getPksByKey` (`Set<TPk>` for SetBased, `TPk[]` for ArrayBased). Raw indexes can be used as standalone PK/slot structures. When an index belongs to a collection, prefer `OIMReactiveCollectionIndexManual*`; it binds the collection at construction time so PK writes resolve canonical collection slots without a later lifecycle setter.
|
|
193
193
|
|
|
194
|
-
For most app-level entity relations, start with `
|
|
194
|
+
For most app-level entity relations, start with `createOIMCollectionKit(...).indexFactory.derivedSetIndex(...)` or `.derivedArrayIndex(...)`. The manual indexes below are the advanced path for externally maintained memberships such as search results, permissions, or server-provided order.
|
|
195
195
|
|
|
196
196
|
#### SetBased Indexes (for incremental updates)
|
|
197
197
|
|
|
@@ -1158,7 +1158,7 @@ npm install @oimdb/react
|
|
|
1158
1158
|
Create your collections outside React, wire them up once, then use hooks inside components:
|
|
1159
1159
|
|
|
1160
1160
|
```typescript
|
|
1161
|
-
import {
|
|
1161
|
+
import { createOIMCollectionKit, OIMEventQueue } from '@oimdb/core';
|
|
1162
1162
|
import {
|
|
1163
1163
|
OIMCollectionsProvider,
|
|
1164
1164
|
useOIMCollectionsContext,
|
|
@@ -1169,7 +1169,7 @@ import {
|
|
|
1169
1169
|
// --- store.ts (created once, outside React) ---
|
|
1170
1170
|
const queue = new OIMEventQueue();
|
|
1171
1171
|
const { collection: users, indexFactory } =
|
|
1172
|
-
|
|
1172
|
+
createOIMCollectionKit<User, string>(queue, { selectPk: (u) => u.id });
|
|
1173
1173
|
const byTeam = indexFactory.derivedSetIndex((u) => [u.teamId]);
|
|
1174
1174
|
export const collections = { users };
|
|
1175
1175
|
export { byTeam };
|
|
@@ -1268,11 +1268,11 @@ unsubscribe();
|
|
|
1268
1268
|
#### `createOIMReactiveCollection<TEntity, TPk>(queue, opts?)`
|
|
1269
1269
|
Creates an `OIMReactiveCollection<TEntity, TPk>` with less constructor noise.
|
|
1270
1270
|
|
|
1271
|
-
#### `
|
|
1271
|
+
#### `createOIMCollectionKit<TEntity, TPk>(queue, opts?)`
|
|
1272
1272
|
Creates a small facade:
|
|
1273
1273
|
|
|
1274
1274
|
```typescript
|
|
1275
|
-
type
|
|
1275
|
+
type TOIMCollectionKit<TEntity, TPk> = {
|
|
1276
1276
|
queue: OIMEventQueue;
|
|
1277
1277
|
collection: OIMReactiveCollection<TEntity, TPk>;
|
|
1278
1278
|
relations: OIMCollectionRelations<TEntity, TPk>;
|
package/dist/index.cjs
CHANGED
|
@@ -93,8 +93,8 @@ __export(index_exports, {
|
|
|
93
93
|
OIMReactiveIndexSetBased: () => OIMReactiveIndexSetBased,
|
|
94
94
|
OIMReactiveObject: () => OIMReactiveObject,
|
|
95
95
|
OIMSelector: () => OIMSelector,
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
createOIMCollectionIndexFactory: () => createOIMCollectionIndexFactory,
|
|
97
|
+
createOIMCollectionKit: () => createOIMCollectionKit
|
|
98
98
|
});
|
|
99
99
|
module.exports = __toCommonJS(index_exports);
|
|
100
100
|
|
|
@@ -879,17 +879,39 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
879
879
|
constructor() {
|
|
880
880
|
super(...arguments);
|
|
881
881
|
this.slots = /* @__PURE__ */ new Map();
|
|
882
|
+
// Slots reserved by indexes for PKs whose entity has not arrived yet.
|
|
883
|
+
// They carry `item: undefined` and live apart from `slots` so they do not
|
|
884
|
+
// leak into entity enumeration (getAll/getAllPks/countAll). When the entity
|
|
885
|
+
// is finally written, the reserved slot is promoted into `slots` — keeping
|
|
886
|
+
// the reference that indexes already hold, so it fills in live.
|
|
887
|
+
this.reservedSlots = /* @__PURE__ */ new Map();
|
|
882
888
|
}
|
|
883
889
|
setOneByPk(pk, entity) {
|
|
884
890
|
const slot = this.slots.get(pk);
|
|
885
891
|
if (slot) {
|
|
886
892
|
slot.item = entity;
|
|
887
893
|
return slot;
|
|
888
|
-
} else {
|
|
889
|
-
const nextSlot = { pk, item: entity };
|
|
890
|
-
this.slots.set(pk, nextSlot);
|
|
891
|
-
return nextSlot;
|
|
892
894
|
}
|
|
895
|
+
const reserved = this.reservedSlots.get(pk);
|
|
896
|
+
if (reserved) {
|
|
897
|
+
reserved.item = entity;
|
|
898
|
+
this.reservedSlots.delete(pk);
|
|
899
|
+
this.slots.set(pk, reserved);
|
|
900
|
+
return reserved;
|
|
901
|
+
}
|
|
902
|
+
const nextSlot = { pk, item: entity };
|
|
903
|
+
this.slots.set(pk, nextSlot);
|
|
904
|
+
return nextSlot;
|
|
905
|
+
}
|
|
906
|
+
getOrReserveSlotByPk(pk) {
|
|
907
|
+
const slot = this.slots.get(pk);
|
|
908
|
+
if (slot) return slot;
|
|
909
|
+
let reserved = this.reservedSlots.get(pk);
|
|
910
|
+
if (!reserved) {
|
|
911
|
+
reserved = { pk, item: void 0 };
|
|
912
|
+
this.reservedSlots.set(pk, reserved);
|
|
913
|
+
}
|
|
914
|
+
return reserved;
|
|
893
915
|
}
|
|
894
916
|
setManyByPks(pks, entities) {
|
|
895
917
|
const slots = [];
|
|
@@ -922,6 +944,11 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
922
944
|
const slot = this.slots.get(pk);
|
|
923
945
|
if (slot) slot.item = void 0;
|
|
924
946
|
this.slots.delete(pk);
|
|
947
|
+
const reserved = this.reservedSlots.get(pk);
|
|
948
|
+
if (reserved) {
|
|
949
|
+
reserved.item = void 0;
|
|
950
|
+
this.reservedSlots.delete(pk);
|
|
951
|
+
}
|
|
925
952
|
}
|
|
926
953
|
removeManyByPks(pks) {
|
|
927
954
|
for (const pk of pks) {
|
|
@@ -959,6 +986,10 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
959
986
|
slot.item = void 0;
|
|
960
987
|
}
|
|
961
988
|
this.slots.clear();
|
|
989
|
+
for (const slot of this.reservedSlots.values()) {
|
|
990
|
+
slot.item = void 0;
|
|
991
|
+
}
|
|
992
|
+
this.reservedSlots.clear();
|
|
962
993
|
}
|
|
963
994
|
getAllPks() {
|
|
964
995
|
return Array.from(this.slots.keys());
|
|
@@ -1000,6 +1031,9 @@ var OIMCollection = class {
|
|
|
1000
1031
|
getSlotByPk(pk) {
|
|
1001
1032
|
return this.store.getSlotByPk(pk);
|
|
1002
1033
|
}
|
|
1034
|
+
getOrReserveSlotByPk(pk) {
|
|
1035
|
+
return this.store.getOrReserveSlotByPk(pk);
|
|
1036
|
+
}
|
|
1003
1037
|
getSlotsByPks(pks) {
|
|
1004
1038
|
return this.store.getSlotsByPks(pks);
|
|
1005
1039
|
}
|
|
@@ -1625,7 +1659,7 @@ var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased
|
|
|
1625
1659
|
// src/core/OIMReactiveCollectionIndexManualArrayBased.ts
|
|
1626
1660
|
var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexManualArrayBased {
|
|
1627
1661
|
constructor(queue, opts) {
|
|
1628
|
-
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.
|
|
1662
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
1629
1663
|
super(queue, {
|
|
1630
1664
|
indexOptions: opts.indexOptions
|
|
1631
1665
|
});
|
|
@@ -1675,11 +1709,7 @@ var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexM
|
|
|
1675
1709
|
}
|
|
1676
1710
|
resolveRequiredSlot(pk) {
|
|
1677
1711
|
const slot = this.resolveSlot(pk);
|
|
1678
|
-
if (!slot) {
|
|
1679
|
-
throw new Error(
|
|
1680
|
-
`[OIMReactiveCollectionIndexManualArrayBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1681
|
-
);
|
|
1682
|
-
}
|
|
1712
|
+
if (!slot) return { pk, item: void 0 };
|
|
1683
1713
|
return slot;
|
|
1684
1714
|
}
|
|
1685
1715
|
};
|
|
@@ -1747,7 +1777,7 @@ var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
|
1747
1777
|
// src/core/OIMReactiveCollectionIndexManualSetBased.ts
|
|
1748
1778
|
var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexManualSetBased {
|
|
1749
1779
|
constructor(queue, opts) {
|
|
1750
|
-
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.
|
|
1780
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
1751
1781
|
super(queue, {
|
|
1752
1782
|
indexOptions: opts.indexOptions
|
|
1753
1783
|
});
|
|
@@ -1801,11 +1831,7 @@ var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexMan
|
|
|
1801
1831
|
}
|
|
1802
1832
|
resolveRequiredSlot(pk) {
|
|
1803
1833
|
const slot = this.resolveSlot(pk);
|
|
1804
|
-
if (!slot) {
|
|
1805
|
-
throw new Error(
|
|
1806
|
-
`[OIMReactiveCollectionIndexManualSetBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1807
|
-
);
|
|
1808
|
-
}
|
|
1834
|
+
if (!slot) return { pk, item: void 0 };
|
|
1809
1835
|
return slot;
|
|
1810
1836
|
}
|
|
1811
1837
|
};
|
|
@@ -2967,8 +2993,8 @@ var OIMCollectionSelectors = class {
|
|
|
2967
2993
|
}
|
|
2968
2994
|
};
|
|
2969
2995
|
|
|
2970
|
-
// src/dx/
|
|
2971
|
-
function
|
|
2996
|
+
// src/dx/OIMCollectionKit.ts
|
|
2997
|
+
function createOIMCollectionKit(queue, opts) {
|
|
2972
2998
|
const collection = new OIMReactiveCollection(queue, opts);
|
|
2973
2999
|
const indexFactory = new OIMCollectionIndexFactory(queue, collection);
|
|
2974
3000
|
const select = new OIMCollectionSelectors(queue, collection);
|
|
@@ -3796,6 +3822,6 @@ var OIMIndexPksByKeysArrayBasedSelector = class extends OIMSelector {
|
|
|
3796
3822
|
OIMReactiveIndexSetBased,
|
|
3797
3823
|
OIMReactiveObject,
|
|
3798
3824
|
OIMSelector,
|
|
3799
|
-
|
|
3800
|
-
|
|
3825
|
+
createOIMCollectionIndexFactory,
|
|
3826
|
+
createOIMCollectionKit
|
|
3801
3827
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -10,6 +10,13 @@ type TOIMEntitySlotResolver<TPk extends TOIMPk> = (pk: TPk) => TOIMAnyEntitySlot
|
|
|
10
10
|
declare abstract class OIMCollectionStore<TEntity extends object, TPk extends TOIMPk> {
|
|
11
11
|
abstract setOneByPk(pk: TPk, entity: TEntity): TOIMEntitySlot<TEntity, TPk>;
|
|
12
12
|
abstract getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the canonical slot for `pk`, creating a reserved empty slot
|
|
15
|
+
* (`item: undefined`) if no entity exists yet. The reserved slot is a stable
|
|
16
|
+
* reference that fills in when the entity is later written, so indexes can
|
|
17
|
+
* hold it ahead of the entity's arrival without crashing.
|
|
18
|
+
*/
|
|
19
|
+
abstract getOrReserveSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk>;
|
|
13
20
|
abstract getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
14
21
|
abstract getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
|
|
15
22
|
abstract removeOneByPk(pk: TPk): void;
|
|
@@ -381,6 +388,7 @@ declare class OIMCollection<TEntity extends object, TPk extends TOIMPk> {
|
|
|
381
388
|
getOneByPk(pk: TPk): TEntity | undefined;
|
|
382
389
|
getManyByPks(pks: readonly TPk[]): TEntity[];
|
|
383
390
|
getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
|
|
391
|
+
getOrReserveSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk>;
|
|
384
392
|
getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
385
393
|
getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
|
|
386
394
|
upsertOneByPk(pk: TPk, entity: Partial<TEntity>): TOIMEntitySlot<TEntity, TPk>;
|
|
@@ -849,7 +857,9 @@ declare class OIMReactiveObject<TKey extends string, TValue> extends OIMObject<T
|
|
|
849
857
|
|
|
850
858
|
declare class OIMCollectionStoreMapDriven<TEntity extends object, TPk extends TOIMPk> extends OIMCollectionStore<TEntity, TPk> {
|
|
851
859
|
protected readonly slots: Map<TPk, TOIMEntitySlot<TEntity, TPk>>;
|
|
860
|
+
protected readonly reservedSlots: Map<TPk, TOIMEntitySlot<TEntity, TPk>>;
|
|
852
861
|
setOneByPk(pk: TPk, entity: TEntity): TOIMEntitySlot<TEntity, TPk>;
|
|
862
|
+
getOrReserveSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk>;
|
|
853
863
|
setManyByPks(pks: readonly TPk[], entities: TEntity[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
854
864
|
getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
|
|
855
865
|
getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
@@ -1064,14 +1074,14 @@ declare class OIMCollectionSelectors<TEntity extends object, TPk extends TOIMPk>
|
|
|
1064
1074
|
}
|
|
1065
1075
|
|
|
1066
1076
|
type TOIMReactiveCollectionFactoryOptions<TEntity extends object, TPk extends TOIMPk> = TOIMCollectionOptions<TEntity, TPk>;
|
|
1067
|
-
type
|
|
1077
|
+
type TOIMCollectionKit<TEntity extends object, TPk extends TOIMPk> = {
|
|
1068
1078
|
queue: OIMEventQueue;
|
|
1069
1079
|
collection: OIMReactiveCollection<TEntity, TPk>;
|
|
1070
1080
|
indexFactory: OIMCollectionIndexFactory<TEntity, TPk>;
|
|
1071
1081
|
select: OIMCollectionSelectors<TEntity, TPk>;
|
|
1072
1082
|
};
|
|
1073
1083
|
|
|
1074
|
-
declare function
|
|
1084
|
+
declare function createOIMCollectionKit<TEntity extends object, TPk extends TOIMPk>(queue: OIMEventQueue, opts?: TOIMReactiveCollectionFactoryOptions<TEntity, TPk>): TOIMCollectionKit<TEntity, TPk>;
|
|
1075
1085
|
|
|
1076
1086
|
type TOIMFieldKey<TEntity extends object> = keyof TEntity & string;
|
|
1077
1087
|
/**
|
|
@@ -1479,4 +1489,4 @@ declare class OIMEntitiesByIndexKeyArrayBasedSelector<TEntity extends object, TP
|
|
|
1479
1489
|
protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
|
|
1480
1490
|
}
|
|
1481
1491
|
|
|
1482
|
-
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type
|
|
1492
|
+
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, type TOIMCollectionKit, type TOIMCollectionOptions, type TOIMCollectionOrderedIndexOptions, type TOIMCollectionOrderedListCommandStreamOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMDerivedCollectionIndexArrayBasedOptions, type TOIMDerivedCollectionIndexSetBasedOptions, type TOIMDerivedEntityComparator, type TOIMDerivedEntityOrderSelector, type TOIMDerivedEntityOrderValue, type TOIMDerivedIndexKeySelector, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMReactiveCollectionFactoryOptions, type TOIMRelationsArrayIndexOptions, type TOIMRelationsDerivedArrayIndexOptions, type TOIMRelationsDerivedSetIndexOptions, type TOIMRelationsOrderedListOptions, type TOIMRelationsSetIndexOptions, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload, createOIMCollectionIndexFactory, createOIMCollectionKit };
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,13 @@ type TOIMEntitySlotResolver<TPk extends TOIMPk> = (pk: TPk) => TOIMAnyEntitySlot
|
|
|
10
10
|
declare abstract class OIMCollectionStore<TEntity extends object, TPk extends TOIMPk> {
|
|
11
11
|
abstract setOneByPk(pk: TPk, entity: TEntity): TOIMEntitySlot<TEntity, TPk>;
|
|
12
12
|
abstract getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the canonical slot for `pk`, creating a reserved empty slot
|
|
15
|
+
* (`item: undefined`) if no entity exists yet. The reserved slot is a stable
|
|
16
|
+
* reference that fills in when the entity is later written, so indexes can
|
|
17
|
+
* hold it ahead of the entity's arrival without crashing.
|
|
18
|
+
*/
|
|
19
|
+
abstract getOrReserveSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk>;
|
|
13
20
|
abstract getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
14
21
|
abstract getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
|
|
15
22
|
abstract removeOneByPk(pk: TPk): void;
|
|
@@ -381,6 +388,7 @@ declare class OIMCollection<TEntity extends object, TPk extends TOIMPk> {
|
|
|
381
388
|
getOneByPk(pk: TPk): TEntity | undefined;
|
|
382
389
|
getManyByPks(pks: readonly TPk[]): TEntity[];
|
|
383
390
|
getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
|
|
391
|
+
getOrReserveSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk>;
|
|
384
392
|
getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
385
393
|
getAllSlots(): TOIMEntitySlot<TEntity, TPk>[];
|
|
386
394
|
upsertOneByPk(pk: TPk, entity: Partial<TEntity>): TOIMEntitySlot<TEntity, TPk>;
|
|
@@ -849,7 +857,9 @@ declare class OIMReactiveObject<TKey extends string, TValue> extends OIMObject<T
|
|
|
849
857
|
|
|
850
858
|
declare class OIMCollectionStoreMapDriven<TEntity extends object, TPk extends TOIMPk> extends OIMCollectionStore<TEntity, TPk> {
|
|
851
859
|
protected readonly slots: Map<TPk, TOIMEntitySlot<TEntity, TPk>>;
|
|
860
|
+
protected readonly reservedSlots: Map<TPk, TOIMEntitySlot<TEntity, TPk>>;
|
|
852
861
|
setOneByPk(pk: TPk, entity: TEntity): TOIMEntitySlot<TEntity, TPk>;
|
|
862
|
+
getOrReserveSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk>;
|
|
853
863
|
setManyByPks(pks: readonly TPk[], entities: TEntity[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
854
864
|
getSlotByPk(pk: TPk): TOIMEntitySlot<TEntity, TPk> | undefined;
|
|
855
865
|
getSlotsByPks(pks: readonly TPk[]): TOIMEntitySlot<TEntity, TPk>[];
|
|
@@ -1064,14 +1074,14 @@ declare class OIMCollectionSelectors<TEntity extends object, TPk extends TOIMPk>
|
|
|
1064
1074
|
}
|
|
1065
1075
|
|
|
1066
1076
|
type TOIMReactiveCollectionFactoryOptions<TEntity extends object, TPk extends TOIMPk> = TOIMCollectionOptions<TEntity, TPk>;
|
|
1067
|
-
type
|
|
1077
|
+
type TOIMCollectionKit<TEntity extends object, TPk extends TOIMPk> = {
|
|
1068
1078
|
queue: OIMEventQueue;
|
|
1069
1079
|
collection: OIMReactiveCollection<TEntity, TPk>;
|
|
1070
1080
|
indexFactory: OIMCollectionIndexFactory<TEntity, TPk>;
|
|
1071
1081
|
select: OIMCollectionSelectors<TEntity, TPk>;
|
|
1072
1082
|
};
|
|
1073
1083
|
|
|
1074
|
-
declare function
|
|
1084
|
+
declare function createOIMCollectionKit<TEntity extends object, TPk extends TOIMPk>(queue: OIMEventQueue, opts?: TOIMReactiveCollectionFactoryOptions<TEntity, TPk>): TOIMCollectionKit<TEntity, TPk>;
|
|
1075
1085
|
|
|
1076
1086
|
type TOIMFieldKey<TEntity extends object> = keyof TEntity & string;
|
|
1077
1087
|
/**
|
|
@@ -1479,4 +1489,4 @@ declare class OIMEntitiesByIndexKeyArrayBasedSelector<TEntity extends object, TP
|
|
|
1479
1489
|
protected areEqual(prev: readonly (TEntity | undefined)[], next: readonly (TEntity | undefined)[]): boolean;
|
|
1480
1490
|
}
|
|
1481
1491
|
|
|
1482
|
-
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type
|
|
1492
|
+
export { EOIMCollectionEventType, EOIMComputedEventType, EOIMEventQueueEventType, EOIMEventQueueSchedulerEventType, EOIMIndexEventType, EOIMObjectEventType, type IOIMComputedEventSource, type IOIMEffectDependency, type IOIMEventQueueSchedulerEvents, type IOIMIndexStore, OIMCollection, OIMCollectionByPkSelector, OIMCollectionByPksSelector, OIMCollectionChangedFields, OIMCollectionIndexFactory, OIMCollectionIndexManualOrderedArrayBased, OIMCollectionOrderedListCommandStream, OIMCollectionSelectors, OIMCollectionStore, OIMCollectionStoreMapDriven, OIMComparatorFactory, OIMComputeRuntime, OIMComputed, OIMDBSettings, OIMDerivedCollectionIndexArrayBased, OIMDerivedCollectionIndexSetBased, OIMEffect, OIMEffectDependencyComputed, OIMEffectDependencyKeyed, OIMEffectDependencyKeyedCollection, OIMEffectDependencyKeyedIndex, OIMEffectDependencyKeyedObject, OIMEntitiesByIndexKeyArrayBasedSelector, OIMEntitiesByIndexKeySetBasedSelector, OIMEntityUpdaterFactory, OIMEventEmitter, OIMEventQueue, OIMEventQueueScheduler, OIMEventQueueSchedulerAnimationFrame, OIMEventQueueSchedulerFactory, OIMEventQueueSchedulerImmediate, OIMEventQueueSchedulerMicrotask, OIMEventQueueSchedulerTimeout, OIMIndex, OIMIndexArrayBased, OIMIndexComparatorFactory, OIMIndexManualArrayBased, OIMIndexManualOrderedArrayBased, OIMIndexManualSetBased, OIMIndexPksByKeyArrayBasedSelector, OIMIndexPksByKeySetBasedSelector, OIMIndexPksByKeysArrayBasedSelector, OIMIndexPksByKeysSetBasedSelector, OIMIndexSetBased, OIMIndexStoreArrayBased, OIMIndexStoreMapDrivenArrayBased, OIMIndexStoreMapDrivenSetBased, OIMIndexStoreSetBased, OIMMap2Keys, OIMObject, OIMObjectStore, OIMObjectStoreMapDriven, OIMObjectStoreRecordDriven, OIMObjectValueByKeySelector, OIMObjectValuesByKeysSelector, OIMOrderedListCommandStream, OIMPkSelectorFactory, OIMReactiveCollection, OIMReactiveCollectionIndexManualArrayBased, OIMReactiveCollectionIndexManualSetBased, OIMReactiveIndex, OIMReactiveIndexArrayBased, OIMReactiveIndexManualArrayBased, OIMReactiveIndexManualSetBased, OIMReactiveIndexSetBased, OIMReactiveObject, OIMSelector, type TOIMAnyEntitySlot, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, type TOIMCollectionKit, type TOIMCollectionOptions, type TOIMCollectionOrderedIndexOptions, type TOIMCollectionOrderedListCommandStreamOptions, type TOIMCollectionUpdatePayload, type TOIMComparator, type TOIMComputedOptions, type TOIMComputedUpdatePayload, type TOIMDerivedCollectionIndexArrayBasedOptions, type TOIMDerivedCollectionIndexSetBasedOptions, type TOIMDerivedEntityComparator, type TOIMDerivedEntityOrderSelector, type TOIMDerivedEntityOrderValue, type TOIMDerivedIndexKeySelector, type TOIMEffectOptions, type TOIMEntitySlot, type TOIMEntitySlotResolver, type TOIMEntityUpdater, type TOIMEventHandler, type TOIMEventQueueOptions, type TOIMIndexComparator, type TOIMIndexKey, type TOIMIndexOptionsArrayBased, type TOIMIndexOptionsSetBased, type TOIMIndexPksUpdatePayload, type TOIMIndexUpdatePayload, type TOIMObjectOptions, type TOIMOrderedListCommand, type TOIMPk, type TOIMPkSelector, type TOIMReactiveCollectionFactoryOptions, type TOIMRelationsArrayIndexOptions, type TOIMRelationsDerivedArrayIndexOptions, type TOIMRelationsDerivedSetIndexOptions, type TOIMRelationsOrderedListOptions, type TOIMRelationsSetIndexOptions, type TOIMSchedulerOptions, type TOIMSchedulerType, type TOIMUpdatePayload, createOIMCollectionIndexFactory, createOIMCollectionKit };
|
package/dist/index.js
CHANGED
|
@@ -779,17 +779,39 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
779
779
|
constructor() {
|
|
780
780
|
super(...arguments);
|
|
781
781
|
this.slots = /* @__PURE__ */ new Map();
|
|
782
|
+
// Slots reserved by indexes for PKs whose entity has not arrived yet.
|
|
783
|
+
// They carry `item: undefined` and live apart from `slots` so they do not
|
|
784
|
+
// leak into entity enumeration (getAll/getAllPks/countAll). When the entity
|
|
785
|
+
// is finally written, the reserved slot is promoted into `slots` — keeping
|
|
786
|
+
// the reference that indexes already hold, so it fills in live.
|
|
787
|
+
this.reservedSlots = /* @__PURE__ */ new Map();
|
|
782
788
|
}
|
|
783
789
|
setOneByPk(pk, entity) {
|
|
784
790
|
const slot = this.slots.get(pk);
|
|
785
791
|
if (slot) {
|
|
786
792
|
slot.item = entity;
|
|
787
793
|
return slot;
|
|
788
|
-
} else {
|
|
789
|
-
const nextSlot = { pk, item: entity };
|
|
790
|
-
this.slots.set(pk, nextSlot);
|
|
791
|
-
return nextSlot;
|
|
792
794
|
}
|
|
795
|
+
const reserved = this.reservedSlots.get(pk);
|
|
796
|
+
if (reserved) {
|
|
797
|
+
reserved.item = entity;
|
|
798
|
+
this.reservedSlots.delete(pk);
|
|
799
|
+
this.slots.set(pk, reserved);
|
|
800
|
+
return reserved;
|
|
801
|
+
}
|
|
802
|
+
const nextSlot = { pk, item: entity };
|
|
803
|
+
this.slots.set(pk, nextSlot);
|
|
804
|
+
return nextSlot;
|
|
805
|
+
}
|
|
806
|
+
getOrReserveSlotByPk(pk) {
|
|
807
|
+
const slot = this.slots.get(pk);
|
|
808
|
+
if (slot) return slot;
|
|
809
|
+
let reserved = this.reservedSlots.get(pk);
|
|
810
|
+
if (!reserved) {
|
|
811
|
+
reserved = { pk, item: void 0 };
|
|
812
|
+
this.reservedSlots.set(pk, reserved);
|
|
813
|
+
}
|
|
814
|
+
return reserved;
|
|
793
815
|
}
|
|
794
816
|
setManyByPks(pks, entities) {
|
|
795
817
|
const slots = [];
|
|
@@ -822,6 +844,11 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
822
844
|
const slot = this.slots.get(pk);
|
|
823
845
|
if (slot) slot.item = void 0;
|
|
824
846
|
this.slots.delete(pk);
|
|
847
|
+
const reserved = this.reservedSlots.get(pk);
|
|
848
|
+
if (reserved) {
|
|
849
|
+
reserved.item = void 0;
|
|
850
|
+
this.reservedSlots.delete(pk);
|
|
851
|
+
}
|
|
825
852
|
}
|
|
826
853
|
removeManyByPks(pks) {
|
|
827
854
|
for (const pk of pks) {
|
|
@@ -859,6 +886,10 @@ var OIMCollectionStoreMapDriven = class extends OIMCollectionStore {
|
|
|
859
886
|
slot.item = void 0;
|
|
860
887
|
}
|
|
861
888
|
this.slots.clear();
|
|
889
|
+
for (const slot of this.reservedSlots.values()) {
|
|
890
|
+
slot.item = void 0;
|
|
891
|
+
}
|
|
892
|
+
this.reservedSlots.clear();
|
|
862
893
|
}
|
|
863
894
|
getAllPks() {
|
|
864
895
|
return Array.from(this.slots.keys());
|
|
@@ -900,6 +931,9 @@ var OIMCollection = class {
|
|
|
900
931
|
getSlotByPk(pk) {
|
|
901
932
|
return this.store.getSlotByPk(pk);
|
|
902
933
|
}
|
|
934
|
+
getOrReserveSlotByPk(pk) {
|
|
935
|
+
return this.store.getOrReserveSlotByPk(pk);
|
|
936
|
+
}
|
|
903
937
|
getSlotsByPks(pks) {
|
|
904
938
|
return this.store.getSlotsByPks(pks);
|
|
905
939
|
}
|
|
@@ -1525,7 +1559,7 @@ var OIMReactiveIndexManualArrayBased = class extends OIMReactiveIndexArrayBased
|
|
|
1525
1559
|
// src/core/OIMReactiveCollectionIndexManualArrayBased.ts
|
|
1526
1560
|
var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexManualArrayBased {
|
|
1527
1561
|
constructor(queue, opts) {
|
|
1528
|
-
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.
|
|
1562
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
1529
1563
|
super(queue, {
|
|
1530
1564
|
indexOptions: opts.indexOptions
|
|
1531
1565
|
});
|
|
@@ -1575,11 +1609,7 @@ var OIMReactiveCollectionIndexManualArrayBased = class extends OIMReactiveIndexM
|
|
|
1575
1609
|
}
|
|
1576
1610
|
resolveRequiredSlot(pk) {
|
|
1577
1611
|
const slot = this.resolveSlot(pk);
|
|
1578
|
-
if (!slot) {
|
|
1579
|
-
throw new Error(
|
|
1580
|
-
`[OIMReactiveCollectionIndexManualArrayBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1581
|
-
);
|
|
1582
|
-
}
|
|
1612
|
+
if (!slot) return { pk, item: void 0 };
|
|
1583
1613
|
return slot;
|
|
1584
1614
|
}
|
|
1585
1615
|
};
|
|
@@ -1647,7 +1677,7 @@ var OIMReactiveIndexManualSetBased = class extends OIMReactiveIndexSetBased {
|
|
|
1647
1677
|
// src/core/OIMReactiveCollectionIndexManualSetBased.ts
|
|
1648
1678
|
var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexManualSetBased {
|
|
1649
1679
|
constructor(queue, opts) {
|
|
1650
|
-
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.
|
|
1680
|
+
const resolveSlot = opts.collection !== void 0 ? (pk) => opts.collection.getOrReserveSlotByPk(pk) : opts.resolveSlot;
|
|
1651
1681
|
super(queue, {
|
|
1652
1682
|
indexOptions: opts.indexOptions
|
|
1653
1683
|
});
|
|
@@ -1701,11 +1731,7 @@ var OIMReactiveCollectionIndexManualSetBased = class extends OIMReactiveIndexMan
|
|
|
1701
1731
|
}
|
|
1702
1732
|
resolveRequiredSlot(pk) {
|
|
1703
1733
|
const slot = this.resolveSlot(pk);
|
|
1704
|
-
if (!slot) {
|
|
1705
|
-
throw new Error(
|
|
1706
|
-
`[OIMReactiveCollectionIndexManualSetBased]: Unable to resolve slot for PK "${String(pk)}".`
|
|
1707
|
-
);
|
|
1708
|
-
}
|
|
1734
|
+
if (!slot) return { pk, item: void 0 };
|
|
1709
1735
|
return slot;
|
|
1710
1736
|
}
|
|
1711
1737
|
};
|
|
@@ -2867,8 +2893,8 @@ var OIMCollectionSelectors = class {
|
|
|
2867
2893
|
}
|
|
2868
2894
|
};
|
|
2869
2895
|
|
|
2870
|
-
// src/dx/
|
|
2871
|
-
function
|
|
2896
|
+
// src/dx/OIMCollectionKit.ts
|
|
2897
|
+
function createOIMCollectionKit(queue, opts) {
|
|
2872
2898
|
const collection = new OIMReactiveCollection(queue, opts);
|
|
2873
2899
|
const indexFactory = new OIMCollectionIndexFactory(queue, collection);
|
|
2874
2900
|
const select = new OIMCollectionSelectors(queue, collection);
|
|
@@ -3695,6 +3721,6 @@ export {
|
|
|
3695
3721
|
OIMReactiveIndexSetBased,
|
|
3696
3722
|
OIMReactiveObject,
|
|
3697
3723
|
OIMSelector,
|
|
3698
|
-
|
|
3699
|
-
|
|
3724
|
+
createOIMCollectionIndexFactory,
|
|
3725
|
+
createOIMCollectionKit
|
|
3700
3726
|
};
|
package/llms.txt
CHANGED
|
@@ -80,13 +80,13 @@ queue.flush(); // delivers subscription
|
|
|
80
80
|
|
|
81
81
|
### DX Layer — Collection Model
|
|
82
82
|
|
|
83
|
-
`
|
|
83
|
+
`createOIMCollectionKit` wires queue + collection + index factory + selectors together.
|
|
84
84
|
|
|
85
85
|
```ts
|
|
86
|
-
import {
|
|
86
|
+
import { createOIMCollectionKit } from '@oimdb/core';
|
|
87
87
|
|
|
88
88
|
const { collection, indexFactory, select } =
|
|
89
|
-
|
|
89
|
+
createOIMCollectionKit<User, string>(queue, { selectPk: (u) => u.id });
|
|
90
90
|
|
|
91
91
|
// Derived index: built automatically from entity data
|
|
92
92
|
const byRole = indexFactory.derivedSetIndex((u) => [u.role]);
|
|
@@ -181,7 +181,7 @@ import {
|
|
|
181
181
|
// store.ts — outside React
|
|
182
182
|
const queue = new OIMEventQueue();
|
|
183
183
|
const { collection: users, indexFactory } =
|
|
184
|
-
|
|
184
|
+
createOIMCollectionKit<User, string>(queue, { selectPk: (u) => u.id });
|
|
185
185
|
const byTeam = indexFactory.derivedSetIndex((u) => [u.teamId]);
|
|
186
186
|
export const collections = { users };
|
|
187
187
|
|
|
@@ -329,7 +329,7 @@ Variable names: drop the prefix, start lowercase. Context goes first: `prevColle
|
|
|
329
329
|
const queue = new OIMEventQueue({ scheduler: new OIMEventQueueSchedulerImmediate() });
|
|
330
330
|
|
|
331
331
|
const { collection: tasks, indexFactory, select } =
|
|
332
|
-
|
|
332
|
+
createOIMCollectionKit<Task, string>(queue, { selectPk: (t) => t.id });
|
|
333
333
|
|
|
334
334
|
const byStatus = indexFactory.derivedSetIndex((t) => [t.status]);
|
|
335
335
|
const byAssignee = indexFactory.derivedSetIndex((t) => [t.assigneeId]);
|