@oimdb/core 1.4.1 → 1.5.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
@@ -36,17 +36,17 @@ This package exports all the core classes, interfaces, and types needed to build
36
36
 
37
37
  ### Storage & Indexing
38
38
  - **OIMCollectionStoreMapDriven**: Map-based storage backend
39
- - **OIMIndexManualSetBased**: Set-based manual index (returns `Set<TPk>`)
40
- - **OIMIndexManualArrayBased**: Array-based manual index (returns `TPk[]`)
41
- - **OIMIndexStoreMapDrivenSetBased**: Set-based index storage backend
42
- - **OIMIndexStoreMapDrivenArrayBased**: Array-based index storage backend
39
+ - **OIMIndexManualSetBased**: Set-based manual index (stores slots, projects to `Set<TPk>`)
40
+ - **OIMIndexManualArrayBased**: Array-based manual index (stores slots, projects to `TPk[]`)
41
+ - **OIMIndexStoreMapDrivenSetBased**: Set-based slot index storage backend
42
+ - **OIMIndexStoreMapDrivenArrayBased**: Array-based slot index storage backend
43
43
  - **OIMMap2Keys**: Two-key mapping utilities for complex indexing
44
44
 
45
45
  ### Abstract Classes & Interfaces
46
46
  - **OIMCollectionStore**: Storage backend interface
47
47
  - **OIMEventQueueScheduler**: Event processing scheduler interface
48
- - **OIMIndexSetBased**: Base Set-based index interface (returns `Set<TPk>`)
49
- - **OIMIndexArrayBased**: Base Array-based index interface (returns `TPk[]`)
48
+ - **OIMIndexSetBased**: Base Set-based index interface (slot-backed, projects to `Set<TPk>`)
49
+ - **OIMIndexArrayBased**: Base Array-based index interface (slot-backed, projects to `TPk[]`)
50
50
  - **OIMReactiveIndexSetBased**: Reactive Set-based index interface
51
51
  - **OIMReactiveIndexArrayBased**: Reactive Array-based index interface
52
52
 
@@ -108,6 +108,8 @@ const multipleUsers = users.getManyByPks(['user1', 'user2']);
108
108
 
109
109
  OIMDB provides two types of indexes optimized for different use cases:
110
110
 
111
+ Indexes are slot-backed internally. Collections own canonical `{ pk, item }` slots, while indexes store references to those slots. `getPksByKey` remains available as a PK projection (`Set<TPk>` for SetBased, `TPk[]` for ArrayBased), and entity-by-index selectors/hooks read `slot.item` directly for faster reads.
112
+
111
113
  #### SetBased Indexes (for incremental updates)
112
114
 
113
115
  ```typescript
@@ -862,13 +864,17 @@ OIMIndexArrayBased (base for Array-based)
862
864
  ### Index Performance
863
865
 
864
866
  **SetBased Indexes** (`OIMReactiveIndexManualSetBased`):
865
- - **Returns**: `Set<TPk>` for efficient membership checks
867
+ - **Storage**: Set of canonical entity slots
868
+ - **PK projection**: `getPksByKey` returns `Set<TPk>` for efficient membership checks
869
+ - **Entity reads**: selectors/hooks read `slot.item` directly, avoiding per-item collection lookups
866
870
  - **Best for**: Frequent incremental updates using `addPks`/`removePks`
867
871
  - **Performance**: O(1) add/remove operations, O(n) for `setPks` (requires Set creation)
868
872
  - **Use case**: When you need to frequently add/remove individual items
869
873
 
870
874
  **ArrayBased Indexes** (`OIMReactiveIndexManualArrayBased`):
871
- - **Returns**: `TPk[]` for direct array access
875
+ - **Storage**: Array of canonical entity slots
876
+ - **PK projection**: `getPksByKey` returns `TPk[]` for direct array access
877
+ - **Entity reads**: selectors/hooks read `slot.item` directly, preserving array order
872
878
  - **Best for**: Full array replacements using `setPks`
873
879
  - **Performance**: O(1) `setPks` operation (direct assignment, no diff computation)
874
880
  - **Use case**: When you typically replace the entire array (e.g., deck cards, ordered lists) or when you need to preserve element order/sorting
@@ -967,7 +973,9 @@ new OIMReactiveCollection(queue: OIMEventQueue, opts?: TOIMCollectionOptions<TEn
967
973
  - `removeOne(entity: TEntity): void` - Remove single entity
968
974
  - `removeMany(entities: TEntity[]): void` - Remove multiple entities
969
975
  - `getOneByPk(pk: TPk): TEntity | undefined` - Get entity by primary key
970
- - `getManyByPks(pks: readonly TPk[]): Map<TPk, TEntity | undefined>` - Get multiple entities
976
+ - `getManyByPks(pks: readonly TPk[]): TEntity[]` - Get existing entities for primary keys
977
+ - `getSlotByPk(pk: TPk): OIMEntitySlot<TEntity, TPk> | undefined` - Get the canonical slot for a primary key
978
+ - `getSlotsByPks(pks: readonly TPk[]): OIMEntitySlot<TEntity, TPk>[]` - Get existing canonical slots for primary keys
971
979
 
972
980
  #### `OIMRICollection<TEntity, TPk, TIndexName, TIndexKey, TIndex, TReactiveIndex, TReactiveIndexMap>`
973
981
  Reactive collection with integrated indexing capabilities.
@@ -985,7 +993,7 @@ new OIMRICollection(queue: OIMEventQueue, opts: {
985
993
  - *(inherits all OIMReactiveCollection properties)*
986
994
 
987
995
  #### `OIMReactiveIndexManualSetBased<TKey, TPk>`
988
- Reactive Set-based index with manual key-to-entity mapping and change notifications. Returns `Set<TPk>` for efficient membership checks.
996
+ Reactive Set-based index with manual key-to-entity mapping and change notifications. Stores canonical slots internally and projects to `Set<TPk>` for PK reads.
989
997
 
990
998
  **Constructor:**
991
999
  ```typescript
@@ -993,6 +1001,7 @@ new OIMReactiveIndexManualSetBased(queue: OIMEventQueue, opts?: {
993
1001
  indexOptions?: {
994
1002
  comparePks?: TOIMIndexComparator<TPk>;
995
1003
  store?: OIMIndexStoreSetBased<TKey, TPk>;
1004
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
996
1005
  }
997
1006
  })
998
1007
  ```
@@ -1005,13 +1014,15 @@ new OIMReactiveIndexManualSetBased(queue: OIMEventQueue, opts?: {
1005
1014
  - `setPks(key: TKey, pks: readonly TPk[]): void` - Set primary keys for index key (replaces entire Set)
1006
1015
  - `addPks(key: TKey, pks: readonly TPk[]): void` - Add primary keys to index key (efficient)
1007
1016
  - `removePks(key: TKey, pks: readonly TPk[]): void` - Remove primary keys from index key (efficient)
1017
+ - `setSlots(key: TKey, slots: Iterable<TOIMAnyEntitySlot<TPk>>): void` - Set canonical slots directly
1008
1018
  - `clear(key?: TKey): void` - Clear all keys or specific key
1009
1019
 
1010
1020
  **Query:**
1011
- - `index.getPksByKey(key: TKey): Set<TPk>` - Returns Set of primary keys
1021
+ - `index.getPksByKey(key: TKey): Set<TPk>` - Returns Set projection of primary keys
1022
+ - `index.getSlotsByKey(key: TKey): ReadonlySet<TOIMAnyEntitySlot<TPk>>` - Returns stored slots for fast entity reads
1012
1023
 
1013
1024
  #### `OIMReactiveIndexManualArrayBased<TKey, TPk>`
1014
- Reactive Array-based index with manual key-to-entity mapping and change notifications. Returns `TPk[]` for direct array access.
1025
+ Reactive Array-based index with manual key-to-entity mapping and change notifications. Stores canonical slots internally and projects to `TPk[]` for PK reads.
1015
1026
 
1016
1027
  **Constructor:**
1017
1028
  ```typescript
@@ -1019,6 +1030,7 @@ new OIMReactiveIndexManualArrayBased(queue: OIMEventQueue, opts?: {
1019
1030
  indexOptions?: {
1020
1031
  comparePks?: TOIMIndexComparator<TPk>;
1021
1032
  store?: OIMIndexStoreArrayBased<TKey, TPk>;
1033
+ resolveSlot?: TOIMEntitySlotResolver<TPk>;
1022
1034
  }
1023
1035
  })
1024
1036
  ```
@@ -1031,10 +1043,12 @@ new OIMReactiveIndexManualArrayBased(queue: OIMEventQueue, opts?: {
1031
1043
  - `setPks(key: TKey, pks: readonly TPk[]): void` - Set primary keys for index key (direct assignment, no diff) - **Recommended for ArrayBased**
1032
1044
  - `addPks(key: TKey, pks: readonly TPk[]): void` - Add primary keys to index key (O(n) operation, less efficient than SetBased)
1033
1045
  - `removePks(key: TKey, pks: readonly TPk[]): void` - Remove primary keys from index key (O(n) operation, less efficient than SetBased)
1046
+ - `setSlots(key: TKey, slots: TOIMAnyEntitySlot<TPk>[]): void` - Set canonical slots directly
1034
1047
  - `clear(key?: TKey): void` - Clear all keys or specific key
1035
1048
 
1036
1049
  **Query:**
1037
- - `index.getPksByKey(key: TKey): TPk[]` - Returns Array of primary keys
1050
+ - `index.getPksByKey(key: TKey): TPk[]` - Returns Array projection of primary keys
1051
+ - `index.getSlotsByKey(key: TKey): readonly TOIMAnyEntitySlot<TPk>[]` - Returns stored slots for fast entity reads
1038
1052
 
1039
1053
  **Note**: While `addPks`/`removePks` are available, they require array operations (Set creation, filtering) making them O(n) compared to O(1) for SetBased indexes. For ArrayBased indexes, prefer `setPks` for better performance when replacing the entire array.
1040
1054