@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 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
- createOIMCollectionContext,
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 = createOIMCollectionContext<User, string>(queue, {
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 `createOIMCollectionContext(...).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.
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 { createOIMCollectionContext, OIMEventQueue } from '@oimdb/core';
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
- createOIMCollectionContext<User, string>(queue, { selectPk: (u) => u.id });
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
- #### `createOIMCollectionContext<TEntity, TPk>(queue, opts?)`
1271
+ #### `createOIMCollectionKit<TEntity, TPk>(queue, opts?)`
1272
1272
  Creates a small facade:
1273
1273
 
1274
1274
  ```typescript
1275
- type TOIMCollectionContext<TEntity, TPk> = {
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
- createOIMCollectionContext: () => createOIMCollectionContext,
97
- createOIMCollectionIndexFactory: () => createOIMCollectionIndexFactory
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.getSlotByPk(pk) : opts.resolveSlot;
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.getSlotByPk(pk) : opts.resolveSlot;
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/OIMCollectionContext.ts
2971
- function createOIMCollectionContext(queue, opts) {
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
- createOIMCollectionContext,
3800
- createOIMCollectionIndexFactory
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 TOIMCollectionContext<TEntity extends object, TPk extends TOIMPk> = {
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 createOIMCollectionContext<TEntity extends object, TPk extends TOIMPk>(queue: OIMEventQueue, opts?: TOIMReactiveCollectionFactoryOptions<TEntity, TPk>): TOIMCollectionContext<TEntity, TPk>;
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 TOIMCollectionContext, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, 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, createOIMCollectionContext, createOIMCollectionIndexFactory };
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 TOIMCollectionContext<TEntity extends object, TPk extends TOIMPk> = {
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 createOIMCollectionContext<TEntity extends object, TPk extends TOIMPk>(queue: OIMEventQueue, opts?: TOIMReactiveCollectionFactoryOptions<TEntity, TPk>): TOIMCollectionContext<TEntity, TPk>;
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 TOIMCollectionContext, type TOIMCollectionEntitiesSelector, type TOIMCollectionEntitySelector, type TOIMCollectionIndexArrayBasedOptions, type TOIMCollectionIndexSetBasedOptions, 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, createOIMCollectionContext, createOIMCollectionIndexFactory };
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.getSlotByPk(pk) : opts.resolveSlot;
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.getSlotByPk(pk) : opts.resolveSlot;
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/OIMCollectionContext.ts
2871
- function createOIMCollectionContext(queue, opts) {
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
- createOIMCollectionContext,
3699
- createOIMCollectionIndexFactory
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
- `createOIMCollectionContext` wires queue + collection + index factory + selectors together.
83
+ `createOIMCollectionKit` wires queue + collection + index factory + selectors together.
84
84
 
85
85
  ```ts
86
- import { createOIMCollectionContext } from '@oimdb/core';
86
+ import { createOIMCollectionKit } from '@oimdb/core';
87
87
 
88
88
  const { collection, indexFactory, select } =
89
- createOIMCollectionContext<User, string>(queue, { selectPk: (u) => u.id });
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
- createOIMCollectionContext<User, string>(queue, { selectPk: (u) => u.id });
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
- createOIMCollectionContext<Task, string>(queue, { selectPk: (t) => t.id });
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]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oimdb/core",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "Core in-memory data library with type-safe indices, reactive subscriptions, and event processing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",