@oimdb/core 1.2.1 → 1.3.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 +116 -27
- package/dist/index.cjs +347 -27
- package/dist/index.d.cts +227 -39
- package/dist/index.d.ts +227 -39
- package/dist/index.js +335 -23
- package/package.json +13 -1
package/README.md
CHANGED
|
@@ -15,7 +15,8 @@ This package exports all the core classes, interfaces, and types needed to build
|
|
|
15
15
|
### Core Classes
|
|
16
16
|
- **OIMReactiveCollection**: Reactive entity storage with automatic change notifications
|
|
17
17
|
- **OIMRICollection**: Reactive collection with integrated indexing capabilities
|
|
18
|
-
- **
|
|
18
|
+
- **OIMReactiveIndexManualSetBased**: Reactive index with Set-based storage (efficient for incremental updates)
|
|
19
|
+
- **OIMReactiveIndexManualArrayBased**: Reactive index with Array-based storage (efficient for full replacements)
|
|
19
20
|
- **OIMEventQueue**: Configurable event processing queue with scheduler integration
|
|
20
21
|
- **OIMCollection**: Base collection with CRUD operations and event emission
|
|
21
22
|
|
|
@@ -27,14 +28,19 @@ This package exports all the core classes, interfaces, and types needed to build
|
|
|
27
28
|
|
|
28
29
|
### Storage & Indexing
|
|
29
30
|
- **OIMCollectionStoreMapDriven**: Map-based storage backend
|
|
30
|
-
- **
|
|
31
|
+
- **OIMIndexManualSetBased**: Set-based manual index (returns `Set<TPk>`)
|
|
32
|
+
- **OIMIndexManualArrayBased**: Array-based manual index (returns `TPk[]`)
|
|
33
|
+
- **OIMIndexStoreMapDrivenSetBased**: Set-based index storage backend
|
|
34
|
+
- **OIMIndexStoreMapDrivenArrayBased**: Array-based index storage backend
|
|
31
35
|
- **OIMMap2Keys**: Two-key mapping utilities for complex indexing
|
|
32
36
|
|
|
33
37
|
### Abstract Classes & Interfaces
|
|
34
38
|
- **OIMCollectionStore**: Storage backend interface
|
|
35
39
|
- **OIMEventQueueScheduler**: Event processing scheduler interface
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
40
|
+
- **OIMIndexSetBased**: Base Set-based index interface (returns `Set<TPk>`)
|
|
41
|
+
- **OIMIndexArrayBased**: Base Array-based index interface (returns `TPk[]`)
|
|
42
|
+
- **OIMReactiveIndexSetBased**: Reactive Set-based index interface
|
|
43
|
+
- **OIMReactiveIndexArrayBased**: Reactive Array-based index interface
|
|
38
44
|
|
|
39
45
|
### Types & Enums
|
|
40
46
|
- **TOIM\***: Generic types for collections, indices, events, and schedulers
|
|
@@ -92,36 +98,72 @@ const multipleUsers = users.getManyByPks(['user1', 'user2']);
|
|
|
92
98
|
|
|
93
99
|
### Creating a Reactive Index
|
|
94
100
|
|
|
101
|
+
OIMDB provides two types of indexes optimized for different use cases:
|
|
102
|
+
|
|
103
|
+
#### SetBased Indexes (for incremental updates)
|
|
104
|
+
|
|
95
105
|
```typescript
|
|
96
|
-
import {
|
|
106
|
+
import { OIMReactiveIndexManualSetBased, OIMEventQueue } from '@oimdb/core';
|
|
97
107
|
|
|
98
|
-
// Create reactive index for user roles
|
|
108
|
+
// Create Set-based reactive index for user roles
|
|
99
109
|
const queue = new OIMEventQueue({
|
|
100
110
|
scheduler: OIMEventQueueSchedulerFactory.createMicrotask()
|
|
101
111
|
});
|
|
102
112
|
|
|
103
|
-
const userRoleIndex = new
|
|
113
|
+
const userRoleIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
|
|
104
114
|
|
|
105
115
|
// Subscribe to specific index key changes
|
|
106
116
|
userRoleIndex.updateEventEmitter.subscribeOnKey('admin', (pks) => {
|
|
107
|
-
console.log('Admin users changed:', pks);
|
|
117
|
+
console.log('Admin users changed:', pks); // pks is Set<string>
|
|
108
118
|
});
|
|
109
119
|
|
|
110
120
|
// Build the index manually
|
|
111
121
|
userRoleIndex.setPks('admin', ['user1']);
|
|
112
122
|
userRoleIndex.setPks('user', ['user2', 'user3']);
|
|
113
123
|
|
|
114
|
-
// Add more users to existing roles
|
|
124
|
+
// Add more users to existing roles (efficient for Set-based)
|
|
115
125
|
userRoleIndex.addPks('admin', ['user2']);
|
|
116
126
|
|
|
117
|
-
// Query the index
|
|
118
|
-
const adminUsers = userRoleIndex.index.getPksByKey('admin'); // ['user1', 'user2']
|
|
119
|
-
const regularUsers = userRoleIndex.index.getPksByKey('user'); // ['user2', 'user3']
|
|
127
|
+
// Query the index - returns Set
|
|
128
|
+
const adminUsers = userRoleIndex.index.getPksByKey('admin'); // Set(['user1', 'user2'])
|
|
129
|
+
const regularUsers = userRoleIndex.index.getPksByKey('user'); // Set(['user2', 'user3'])
|
|
120
130
|
|
|
121
|
-
// Remove users from roles
|
|
131
|
+
// Remove users from roles (efficient for Set-based)
|
|
122
132
|
userRoleIndex.removePks('admin', ['user1']);
|
|
123
133
|
```
|
|
124
134
|
|
|
135
|
+
#### ArrayBased Indexes (for full replacements)
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import { OIMReactiveIndexManualArrayBased, OIMEventQueue } from '@oimdb/core';
|
|
139
|
+
|
|
140
|
+
// Create Array-based reactive index for deck cards
|
|
141
|
+
const queue = new OIMEventQueue({
|
|
142
|
+
scheduler: OIMEventQueueSchedulerFactory.createMicrotask()
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const cardsByDeckIndex = new OIMReactiveIndexManualArrayBased<string, string>(queue);
|
|
146
|
+
|
|
147
|
+
// Subscribe to specific index key changes
|
|
148
|
+
cardsByDeckIndex.updateEventEmitter.subscribeOnKey('deck1', (pks) => {
|
|
149
|
+
console.log('Deck cards changed:', pks); // pks is string[]
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Build the index manually - set full array
|
|
153
|
+
cardsByDeckIndex.setPks('deck1', ['card1', 'card2', 'card3']);
|
|
154
|
+
|
|
155
|
+
// Query the index - returns Array
|
|
156
|
+
const deckCards = cardsByDeckIndex.index.getPksByKey('deck1'); // ['card1', 'card2', 'card3']
|
|
157
|
+
|
|
158
|
+
// For Array-based indexes, prefer setPks for updates (addPks/removePks are available but less efficient)
|
|
159
|
+
cardsByDeckIndex.setPks('deck1', ['card1', 'card2', 'card4']); // Full replacement (recommended)
|
|
160
|
+
// cardsByDeckIndex.addPks('deck1', ['card5']); // Works but less efficient than SetBased
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**When to use which:**
|
|
164
|
+
- **SetBased**: Use when you frequently add/remove individual items (`addPks`/`removePks` are efficient) and order doesn't matter
|
|
165
|
+
- **ArrayBased**: Use when you typically replace the entire array (`setPks` is more efficient, no diff computation needed) or when you need to preserve element order/sorting
|
|
166
|
+
|
|
125
167
|
### Event Queue and Schedulers
|
|
126
168
|
|
|
127
169
|
```typescript
|
|
@@ -187,9 +229,9 @@ const queue = new OIMEventQueue({
|
|
|
187
229
|
scheduler: OIMEventQueueSchedulerFactory.createMicrotask()
|
|
188
230
|
});
|
|
189
231
|
|
|
190
|
-
// Create indexes
|
|
191
|
-
const teamIndex = new
|
|
192
|
-
const roleIndex = new
|
|
232
|
+
// Create indexes (choose SetBased or ArrayBased based on your needs)
|
|
233
|
+
const teamIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
|
|
234
|
+
const roleIndex = new OIMReactiveIndexManualArrayBased<string, string>(queue);
|
|
193
235
|
|
|
194
236
|
// Create collection with indexes
|
|
195
237
|
const users = new OIMRICollection(queue, {
|
|
@@ -334,9 +376,13 @@ OIMCollection (base)
|
|
|
334
376
|
├── OIMReactiveCollection (adds event emitter + coalescing)
|
|
335
377
|
└── OIMRICollection (reactive collection + indexes)
|
|
336
378
|
|
|
337
|
-
|
|
338
|
-
├──
|
|
339
|
-
└──
|
|
379
|
+
OIMIndexSetBased (base for Set-based)
|
|
380
|
+
├── OIMIndexManualSetBased (manual Set-based index)
|
|
381
|
+
└── OIMReactiveIndexManualSetBased (reactive Set-based index with event emitter)
|
|
382
|
+
|
|
383
|
+
OIMIndexArrayBased (base for Array-based)
|
|
384
|
+
├── OIMIndexManualArrayBased (manual Array-based index)
|
|
385
|
+
└── OIMReactiveIndexManualArrayBased (reactive Array-based index with event emitter)
|
|
340
386
|
```
|
|
341
387
|
|
|
342
388
|
## ⚡ Performance Characteristics
|
|
@@ -352,6 +398,21 @@ OIMIndex (base)
|
|
|
352
398
|
- **Timeout**: Custom delay for batching strategies
|
|
353
399
|
- **AnimationFrame**: 16ms, synced with 60fps rendering
|
|
354
400
|
|
|
401
|
+
### Index Performance
|
|
402
|
+
|
|
403
|
+
**SetBased Indexes** (`OIMReactiveIndexManualSetBased`):
|
|
404
|
+
- **Returns**: `Set<TPk>` for efficient membership checks
|
|
405
|
+
- **Best for**: Frequent incremental updates using `addPks`/`removePks`
|
|
406
|
+
- **Performance**: O(1) add/remove operations, O(n) for `setPks` (requires Set creation)
|
|
407
|
+
- **Use case**: When you need to frequently add/remove individual items
|
|
408
|
+
|
|
409
|
+
**ArrayBased Indexes** (`OIMReactiveIndexManualArrayBased`):
|
|
410
|
+
- **Returns**: `TPk[]` for direct array access
|
|
411
|
+
- **Best for**: Full array replacements using `setPks`
|
|
412
|
+
- **Performance**: O(1) `setPks` operation (direct assignment, no diff computation)
|
|
413
|
+
- **Use case**: When you typically replace the entire array (e.g., deck cards, ordered lists) or when you need to preserve element order/sorting
|
|
414
|
+
- **Note**: While `addPks`/`removePks` are available, they are less efficient (O(n)) than for SetBased indexes. For ArrayBased indexes, prefer `setPks` for better performance.
|
|
415
|
+
|
|
355
416
|
## 🔗 Integration Patterns
|
|
356
417
|
|
|
357
418
|
### With React (@oimdb/react)
|
|
@@ -462,26 +523,54 @@ new OIMRICollection(queue: OIMEventQueue, opts: {
|
|
|
462
523
|
- `indexes: TReactiveIndexMap` - Named reactive indexes preserving index-to-name mapping
|
|
463
524
|
- *(inherits all OIMReactiveCollection properties)*
|
|
464
525
|
|
|
465
|
-
#### `
|
|
466
|
-
Reactive index with manual key-to-entity mapping and change notifications.
|
|
526
|
+
#### `OIMReactiveIndexManualSetBased<TKey, TPk>`
|
|
527
|
+
Reactive Set-based index with manual key-to-entity mapping and change notifications. Returns `Set<TPk>` for efficient membership checks.
|
|
528
|
+
|
|
529
|
+
**Constructor:**
|
|
530
|
+
```typescript
|
|
531
|
+
new OIMReactiveIndexManualSetBased(queue: OIMEventQueue, opts?: {
|
|
532
|
+
index?: OIMIndexManualSetBased<TKey, TPk>
|
|
533
|
+
})
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**Properties:**
|
|
537
|
+
- `index: OIMIndexManualSetBased<TKey, TPk>` - Underlying Set-based index
|
|
538
|
+
- `updateEventEmitter: OIMUpdateEventEmitter<TKey>` - Key-specific subscriptions
|
|
539
|
+
|
|
540
|
+
**Methods:**
|
|
541
|
+
- `setPks(key: TKey, pks: readonly TPk[]): void` - Set primary keys for index key (replaces entire Set)
|
|
542
|
+
- `addPks(key: TKey, pks: readonly TPk[]): void` - Add primary keys to index key (efficient)
|
|
543
|
+
- `removePks(key: TKey, pks: readonly TPk[]): void` - Remove primary keys from index key (efficient)
|
|
544
|
+
- `clear(key?: TKey): void` - Clear all keys or specific key
|
|
545
|
+
|
|
546
|
+
**Query:**
|
|
547
|
+
- `index.getPksByKey(key: TKey): Set<TPk>` - Returns Set of primary keys
|
|
548
|
+
|
|
549
|
+
#### `OIMReactiveIndexManualArrayBased<TKey, TPk>`
|
|
550
|
+
Reactive Array-based index with manual key-to-entity mapping and change notifications. Returns `TPk[]` for direct array access.
|
|
467
551
|
|
|
468
552
|
**Constructor:**
|
|
469
553
|
```typescript
|
|
470
|
-
new
|
|
471
|
-
index?:
|
|
554
|
+
new OIMReactiveIndexManualArrayBased(queue: OIMEventQueue, opts?: {
|
|
555
|
+
index?: OIMIndexManualArrayBased<TKey, TPk>
|
|
472
556
|
})
|
|
473
557
|
```
|
|
474
558
|
|
|
475
559
|
**Properties:**
|
|
476
|
-
- `index:
|
|
560
|
+
- `index: OIMIndexManualArrayBased<TKey, TPk>` - Underlying Array-based index
|
|
477
561
|
- `updateEventEmitter: OIMUpdateEventEmitter<TKey>` - Key-specific subscriptions
|
|
478
562
|
|
|
479
563
|
**Methods:**
|
|
480
|
-
- `setPks(key: TKey, pks: readonly TPk[]): void` - Set primary keys for index key
|
|
481
|
-
- `addPks(key: TKey, pks: readonly TPk[]): void` - Add primary keys to index key
|
|
482
|
-
- `removePks(key: TKey, pks: readonly TPk[]): void` - Remove primary keys from index key
|
|
564
|
+
- `setPks(key: TKey, pks: readonly TPk[]): void` - Set primary keys for index key (direct assignment, no diff) - **Recommended for ArrayBased**
|
|
565
|
+
- `addPks(key: TKey, pks: readonly TPk[]): void` - Add primary keys to index key (O(n) operation, less efficient than SetBased)
|
|
566
|
+
- `removePks(key: TKey, pks: readonly TPk[]): void` - Remove primary keys from index key (O(n) operation, less efficient than SetBased)
|
|
483
567
|
- `clear(key?: TKey): void` - Clear all keys or specific key
|
|
484
568
|
|
|
569
|
+
**Query:**
|
|
570
|
+
- `index.getPksByKey(key: TKey): TPk[]` - Returns Array of primary keys
|
|
571
|
+
|
|
572
|
+
**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.
|
|
573
|
+
|
|
485
574
|
#### `OIMEventQueue`
|
|
486
575
|
Event processing queue with configurable scheduling.
|
|
487
576
|
|