@oimdb/react 1.1.0 → 1.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
@@ -8,7 +8,8 @@ React integration for OIMDB - Hooks for selection and subscription with reactive
8
8
 
9
9
  ## Features
10
10
 
11
- - **Reactive Integration**: Hooks work with `OIMReactiveCollection` and `OIMReactiveIndex` from `@oimdb/core`
11
+ - **Reactive Integration**: Hooks work with `OIMReactiveCollection` and reactive indexes from `@oimdb/core`
12
+ - **Index Type Support**: Separate hooks for SetBased indexes (return `Set<TPk>`) and ArrayBased indexes (return `TPk[]`)
12
13
  - **Automatic Subscription**: Uses `useSyncExternalStore` for optimal React 18+ performance
13
14
  - **Event Coalescing**: Leverages OIMDB's built-in event coalescing for efficient updates
14
15
  - **Type Safety**: Full TypeScript support with advanced generic type inference
@@ -26,16 +27,28 @@ npm install @oimdb/react @oimdb/core
26
27
  ### Basic Setup
27
28
 
28
29
  ```typescript
29
- import { OIMEventQueue, OIMRICollection, OIMReactiveIndexManual } from '@oimdb/core';
30
+ import {
31
+ OIMEventQueue,
32
+ OIMRICollection,
33
+ OIMReactiveIndexManualSetBased,
34
+ OIMReactiveIndexManualArrayBased
35
+ } from '@oimdb/core';
30
36
  import {
31
37
  useSelectEntitiesByPks,
32
- useSelectEntitiesByIndexKey,
38
+ useSelectEntitiesByIndexKeySetBased,
39
+ useSelectEntitiesByIndexKeyArrayBased,
33
40
  useSelectEntityByPk
34
41
  } from '@oimdb/react';
35
42
 
36
43
  // Create event queue and reactive collections
37
44
  const queue = new OIMEventQueue();
38
- const userTeamIndex = new OIMReactiveIndexManual<string, string>(queue);
45
+
46
+ // Choose index type based on your needs:
47
+ // - SetBased: for frequent add/remove operations, order doesn't matter
48
+ // - ArrayBased: for full replacements or when order/sorting matters
49
+ const userTeamIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
50
+ const deckCardsIndex = new OIMReactiveIndexManualArrayBased<string, string>(queue);
51
+
39
52
  const usersCollection = new OIMRICollection(queue, {
40
53
  collectionOpts: { selectPk: (user: User) => user.id },
41
54
  indexes: { byTeam: userTeamIndex },
@@ -79,14 +92,27 @@ function UserList({ userIds }: { userIds: string[] }) {
79
92
 
80
93
  ### Index-based Selection
81
94
 
95
+ OIMDB provides separate hooks for SetBased and ArrayBased indexes:
96
+
97
+ #### SetBased Indexes (returns Set)
98
+
82
99
  ```typescript
100
+ import { useSelectEntitiesByIndexKeySetBased, useSelectPksByIndexKeySetBased } from '@oimdb/react';
101
+
83
102
  function TeamMembers({ teamId }: { teamId: string }) {
84
- const teamUsers = useSelectEntitiesByIndexKey(
103
+ // For SetBased indexes, use SetBased hooks
104
+ const teamUsers = useSelectEntitiesByIndexKeySetBased(
85
105
  usersCollection,
86
- usersCollection.indexes.byTeam,
106
+ usersCollection.indexes.byTeam, // OIMReactiveIndexManualSetBased
87
107
  teamId
88
108
  );
89
109
 
110
+ // Or get just the PKs as Set
111
+ const teamUserIds = useSelectPksByIndexKeySetBased(
112
+ usersCollection.indexes.byTeam,
113
+ teamId
114
+ ); // Returns Set<string>
115
+
90
116
  return (
91
117
  <div>
92
118
  {teamUsers.map((user, index) => (
@@ -99,6 +125,37 @@ function TeamMembers({ teamId }: { teamId: string }) {
99
125
  }
100
126
  ```
101
127
 
128
+ #### ArrayBased Indexes (returns Array)
129
+
130
+ ```typescript
131
+ import { useSelectEntitiesByIndexKeyArrayBased, useSelectPksByIndexKeyArrayBased } from '@oimdb/react';
132
+
133
+ function DeckCards({ deckId }: { deckId: string }) {
134
+ // For ArrayBased indexes, use ArrayBased hooks
135
+ const cards = useSelectEntitiesByIndexKeyArrayBased(
136
+ cardsCollection,
137
+ cardsCollection.indexes.byDeck, // OIMReactiveIndexManualArrayBased
138
+ deckId
139
+ );
140
+
141
+ // Or get just the PKs as Array (preserves order)
142
+ const cardIds = useSelectPksByIndexKeyArrayBased(
143
+ cardsCollection.indexes.byDeck,
144
+ deckId
145
+ ); // Returns string[] (preserves order/sorting)
146
+
147
+ return (
148
+ <div>
149
+ {cards.map((card, index) => (
150
+ <div key={card?.id || index}>
151
+ {card ? `${index + 1}. ${card.name}` : 'Loading...'}
152
+ </div>
153
+ ))}
154
+ </div>
155
+ );
156
+ }
157
+ ```
158
+
102
159
  ## React Context Integration
103
160
 
104
161
  For applications with multiple collections, use the React Context pattern for centralized management:
@@ -108,8 +165,7 @@ For applications with multiple collections, use the React Context pattern for ce
108
165
  ```typescript
109
166
  import {
110
167
  OIMRICollectionsProvider,
111
- useOIMCollectionsContext,
112
- StrictCollectionsDictionary
168
+ useOIMCollectionsContext
113
169
  } from '@oimdb/react';
114
170
 
115
171
  interface User {
@@ -126,7 +182,8 @@ interface Team {
126
182
  function createCollections() {
127
183
  const queue = new OIMEventQueue();
128
184
 
129
- const userTeamIndex = new OIMReactiveIndexManual<string, string>(queue);
185
+ // Use SetBased for frequent add/remove operations
186
+ const userTeamIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
130
187
  const usersCollection = new OIMRICollection(queue, {
131
188
  collectionOpts: { selectPk: (user: User) => user.id },
132
189
  indexes: { byTeam: userTeamIndex },
@@ -140,9 +197,156 @@ function createCollections() {
140
197
  return { users: usersCollection, teams: teamsCollection } as const;
141
198
  }
142
199
 
143
- type AppCollections = StrictCollectionsDictionary<ReturnType<typeof createCollections>>;
200
+ type AppCollections = ReturnType<typeof createCollections>;
201
+ ```
202
+
203
+ ## TypeScript Typing Strategies
204
+
205
+ For maximum type safety, you should properly type your collections dictionary. There are two main approaches, similar to how Redux handles state typing:
206
+
207
+ ### Approach 1: Using `typeof` (Recommended for Simple Cases)
208
+
209
+ The simplest approach is to use TypeScript's `typeof` operator to infer types from your collection instances:
210
+
211
+ ```typescript
212
+ import { OIMEventQueue, OIMRICollection, OIMReactiveIndexManual } from '@oimdb/core';
213
+
214
+ interface User {
215
+ id: string;
216
+ name: string;
217
+ teamId: string;
218
+ }
219
+
220
+ interface Team {
221
+ id: string;
222
+ name: string;
223
+ }
224
+
225
+ // Create collections
226
+ const queue = new OIMEventQueue();
227
+ const userTeamIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
228
+ const usersCollection = new OIMRICollection(queue, {
229
+ collectionOpts: { selectPk: (user: User) => user.id },
230
+ indexes: { byTeam: userTeamIndex },
231
+ });
232
+
233
+ const teamsCollection = new OIMRICollection(queue, {
234
+ collectionOpts: { selectPk: (team: Team) => team.id },
235
+ indexes: {},
236
+ });
237
+
238
+ // Infer types using typeof
239
+ const collections = {
240
+ users: usersCollection,
241
+ teams: teamsCollection,
242
+ } as const;
243
+
244
+ // Extract the type
245
+ type AppCollections = typeof collections;
246
+ ```
247
+
248
+ **Usage:**
249
+ ```typescript
250
+ function MyComponent() {
251
+ const { users, teams } = useOIMCollectionsContext<AppCollections>();
252
+ // users and teams are fully typed with all their generics preserved
253
+ }
254
+ ```
255
+
256
+ ### Approach 2: Creating Explicit Types (Recommended for Complex Projects)
257
+
258
+ For larger applications or when you need more control, create explicit type definitions similar to Redux's approach:
259
+
260
+ ```typescript
261
+ import {
262
+ OIMEventQueue,
263
+ OIMRICollection,
264
+ OIMReactiveIndexManualSetBased
265
+ } from '@oimdb/core';
266
+ import type {
267
+ TOIMPk,
268
+ OIMIndexSetBased,
269
+ OIMReactiveIndexSetBased
270
+ } from '@oimdb/core';
271
+
272
+ interface User {
273
+ id: string;
274
+ name: string;
275
+ teamId: string;
276
+ }
277
+
278
+ interface Team {
279
+ id: string;
280
+ name: string;
281
+ }
282
+
283
+ // Define your collection types explicitly
284
+ type UserCollection = OIMRICollection<
285
+ User,
286
+ string,
287
+ 'byTeam',
288
+ string,
289
+ OIMIndexSetBased<string, string>,
290
+ OIMReactiveIndexSetBased<string, string, OIMIndexSetBased<string, string>>
291
+ >;
292
+
293
+ type TeamCollection = OIMRICollection<
294
+ Team,
295
+ string,
296
+ never,
297
+ never,
298
+ OIMIndexSetBased<never, never>,
299
+ OIMReactiveIndexSetBased<never, never, OIMIndexSetBased<never, never>>
300
+ >;
301
+
302
+ // Define your collections dictionary type
303
+ interface AppCollections {
304
+ users: UserCollection;
305
+ teams: TeamCollection;
306
+ }
307
+
308
+ // Factory function that returns properly typed collections
309
+ function createCollections(): AppCollections {
310
+ const queue = new OIMEventQueue();
311
+ const userTeamIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
312
+
313
+ return {
314
+ users: new OIMRICollection(queue, {
315
+ collectionOpts: { selectPk: (user: User) => user.id },
316
+ indexes: { byTeam: userTeamIndex },
317
+ }) as UserCollection,
318
+
319
+ teams: new OIMRICollection(queue, {
320
+ collectionOpts: { selectPk: (team: Team) => team.id },
321
+ indexes: {},
322
+ }) as TeamCollection,
323
+ };
324
+ }
325
+ ```
326
+
327
+ **Usage:**
328
+ ```typescript
329
+ function MyComponent() {
330
+ const { users, teams } = useOIMCollectionsContext<AppCollections>();
331
+ // Full type safety with explicit types
332
+ }
144
333
  ```
145
334
 
335
+ ### When to Use Each Approach
336
+
337
+ - **Use `typeof`** when:
338
+ - You have simple collection setups
339
+ - You want TypeScript to infer everything automatically
340
+ - You prefer less boilerplate
341
+ - Your collections are created in one place
342
+
343
+ - **Use explicit types** when:
344
+ - You need to share types across multiple files
345
+ - You want to document your data structure explicitly
346
+ - You're building a library or shared module
347
+ - You need to ensure type consistency across your application
348
+ - You prefer Redux-style explicit typing patterns
349
+
146
350
  ### Provider Setup
147
351
 
148
352
  ```typescript
@@ -165,9 +369,10 @@ function UserDashboard() {
165
369
 
166
370
  // Use collections with hooks
167
371
  const allUsers = useSelectEntitiesByPks(users, []);
168
- const teamMembers = useSelectEntitiesByIndexKey(
372
+ // Use appropriate hook based on index type
373
+ const teamMembers = useSelectEntitiesByIndexKeySetBased(
169
374
  users,
170
- users.indexes.byTeam,
375
+ users.indexes.byTeam, // SetBased index
171
376
  'team1'
172
377
  );
173
378
 
@@ -227,51 +432,105 @@ Subscribes to multiple entities from a reactive collection.
227
432
  **Returns:**
228
433
  - `(TEntity | undefined)[]` - Array of entities (undefined for missing entities)
229
434
 
230
- ### `useSelectEntitiesByIndexKey(reactiveCollection, reactiveIndex, key)`
435
+ ### Index-based Selection Hooks
436
+
437
+ OIMDB provides separate hooks for SetBased and ArrayBased indexes to ensure type safety and correct return types.
438
+
439
+ #### SetBased Index Hooks
231
440
 
232
- Subscribes to entities indexed by a specific key.
441
+ ##### `useSelectEntitiesByIndexKeySetBased(reactiveCollection, reactiveIndex, key)`
442
+
443
+ Subscribes to entities indexed by a specific key from a SetBased index.
233
444
 
234
445
  **Parameters:**
235
446
  - `reactiveCollection: OIMReactiveCollection<TEntity, TPk>` - Reactive collection instance
236
- - `reactiveIndex: OIMReactiveIndex<TKey, TPk, TIndex>` - Reactive index instance
447
+ - `reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>` - SetBased reactive index instance
237
448
  - `key: TKey` - Index key to query
238
449
 
239
450
  **Returns:**
240
451
  - `(TEntity | undefined)[]` - Array of entities for the given index key
241
452
 
242
- ### `useSelectEntitiesByIndexKeys(reactiveCollection, reactiveIndex, keys)`
453
+ ##### `useSelectEntitiesByIndexKeysSetBased(reactiveCollection, reactiveIndex, keys)`
243
454
 
244
- Subscribes to entities indexed by multiple keys.
455
+ Subscribes to entities indexed by multiple keys from a SetBased index.
245
456
 
246
457
  **Parameters:**
247
458
  - `reactiveCollection: OIMReactiveCollection<TEntity, TPk>` - Reactive collection instance
248
- - `reactiveIndex: OIMReactiveIndex<TKey, TPk, TIndex>` - Reactive index instance
459
+ - `reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>` - SetBased reactive index instance
249
460
  - `keys: readonly TKey[]` - Array of index keys to query
250
461
 
251
462
  **Returns:**
252
463
  - `(TEntity | undefined)[]` - Array of entities for the given index keys
253
464
 
254
- ### `useSelectPksByIndexKey(reactiveIndex, key)`
465
+ ##### `useSelectPksByIndexKeySetBased(reactiveIndex, key)`
466
+
467
+ Subscribes to primary keys indexed by a specific key from a SetBased index.
468
+
469
+ **Parameters:**
470
+ - `reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>` - SetBased reactive index instance
471
+ - `key: TKey` - Index key to query
472
+
473
+ **Returns:**
474
+ - `Set<TPk>` - Set of primary keys for the given index key
475
+
476
+ ##### `useSelectPksByIndexKeysSetBased(reactiveIndex, keys)`
477
+
478
+ Subscribes to primary keys indexed by multiple keys from a SetBased index.
479
+
480
+ **Parameters:**
481
+ - `reactiveIndex: OIMReactiveIndexSetBased<TKey, TPk, TIndex>` - SetBased reactive index instance
482
+ - `keys: readonly TKey[]` - Array of index keys to query
483
+
484
+ **Returns:**
485
+ - `Map<TKey, Set<TPk>>` - Map of index keys to their corresponding primary key Sets
486
+
487
+ #### ArrayBased Index Hooks
255
488
 
256
- Subscribes to primary keys indexed by a specific key.
489
+ ##### `useSelectEntitiesByIndexKeyArrayBased(reactiveCollection, reactiveIndex, key)`
490
+
491
+ Subscribes to entities indexed by a specific key from an ArrayBased index.
257
492
 
258
493
  **Parameters:**
259
- - `reactiveIndex: OIMReactiveIndex<TKey, TPk, TIndex>` - Reactive index instance
494
+ - `reactiveCollection: OIMReactiveCollection<TEntity, TPk>` - Reactive collection instance
495
+ - `reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>` - ArrayBased reactive index instance
260
496
  - `key: TKey` - Index key to query
261
497
 
262
498
  **Returns:**
263
- - `TPk[]` - Array of primary keys for the given index key
499
+ - `(TEntity | undefined)[]` - Array of entities for the given index key (preserves order)
264
500
 
265
- ### `useSelectPksByIndexKeys(reactiveIndex, keys)`
501
+ ##### `useSelectEntitiesByIndexKeysArrayBased(reactiveCollection, reactiveIndex, keys)`
266
502
 
267
- Subscribes to primary keys indexed by multiple keys.
503
+ Subscribes to entities indexed by multiple keys from an ArrayBased index.
268
504
 
269
505
  **Parameters:**
270
- - `reactiveIndex: OIMReactiveIndex<TKey, TPk, TIndex>` - Reactive index instance
506
+ - `reactiveCollection: OIMReactiveCollection<TEntity, TPk>` - Reactive collection instance
507
+ - `reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>` - ArrayBased reactive index instance
271
508
  - `keys: readonly TKey[]` - Array of index keys to query
272
509
 
273
510
  **Returns:**
274
- - `Map<TKey, TPk[]>` - Map of index keys to their corresponding primary keys
511
+ - `(TEntity | undefined)[]` - Array of entities for the given index keys (preserves order)
512
+
513
+ ##### `useSelectPksByIndexKeyArrayBased(reactiveIndex, key)`
514
+
515
+ Subscribes to primary keys indexed by a specific key from an ArrayBased index.
516
+
517
+ **Parameters:**
518
+ - `reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>` - ArrayBased reactive index instance
519
+ - `key: TKey` - Index key to query
520
+
521
+ **Returns:**
522
+ - `TPk[]` - Array of primary keys for the given index key (preserves order/sorting)
523
+
524
+ ##### `useSelectPksByIndexKeysArrayBased(reactiveIndex, keys)`
525
+
526
+ Subscribes to primary keys indexed by multiple keys from an ArrayBased index.
527
+
528
+ **Parameters:**
529
+ - `reactiveIndex: OIMReactiveIndexArrayBased<TKey, TPk, TIndex>` - ArrayBased reactive index instance
530
+ - `keys: readonly TKey[]` - Array of index keys to query
531
+
532
+ **Returns:**
533
+ - `Map<TKey, TPk[]>` - Map of index keys to their corresponding primary key arrays (preserves order)
275
534
 
276
535
  ## Context API Reference
277
536
 
@@ -306,17 +565,9 @@ Creates a custom collections context with specific typing.
306
565
 
307
566
  ### Type Utilities
308
567
 
309
- #### `StrictCollectionsDictionary<T>`
310
-
311
- Ensures collections dictionary maintains exact types.
312
-
313
568
  #### `CollectionsDictionary`
314
569
 
315
- Base type for any collections dictionary.
316
-
317
- #### `ExtractEntityType<T>`, `ExtractPkType<T>`, etc.
318
-
319
- Type utilities for extracting specific types from collections.
570
+ Base type for any collections dictionary. Use `typeof` to extract types from your collection instances, or define explicit types using `OIMRICollection` generics.
320
571
 
321
572
  ## Architecture
322
573
 
@@ -327,7 +578,19 @@ The hooks work directly with OIMDB reactive objects:
327
578
  ```typescript
328
579
  // Use reactive collections and indexes directly
329
580
  const user = useSelectEntityByPk(reactiveCollection, 'user123');
330
- const posts = useSelectEntitiesByIndexKey(reactiveCollection, reactiveIndex, 'tech');
581
+
582
+ // Use appropriate hook based on index type
583
+ const posts = useSelectEntitiesByIndexKeySetBased(
584
+ reactiveCollection,
585
+ reactiveIndexSetBased, // SetBased index
586
+ 'tech'
587
+ );
588
+
589
+ const orderedCards = useSelectEntitiesByIndexKeyArrayBased(
590
+ reactiveCollection,
591
+ reactiveIndexArrayBased, // ArrayBased index
592
+ 'deck1'
593
+ );
331
594
  ```
332
595
 
333
596
  ### Event Subscription
@@ -339,6 +602,15 @@ Hooks automatically subscribe to OIMDB reactive events using `useSyncExternalSto
339
602
  - **Optimized subscriptions**: Subscribe only to specific keys for efficient updates
340
603
  - **Automatic cleanup**: Unsubscribe when component unmounts
341
604
 
605
+ ### Index Type Selection
606
+
607
+ When working with indexes, choose the appropriate hook based on your index type:
608
+
609
+ - **SetBased indexes** (`OIMReactiveIndexManualSetBased`): Use `*SetBased` hooks (e.g., `useSelectPksByIndexKeySetBased`) - returns `Set<TPk>`
610
+ - **ArrayBased indexes** (`OIMReactiveIndexManualArrayBased`): Use `*ArrayBased` hooks (e.g., `useSelectPksByIndexKeyArrayBased`) - returns `TPk[]` (preserves order)
611
+
612
+ This ensures type safety and correct return types. TypeScript will enforce the correct hook usage based on your index type.
613
+
342
614
  ### Performance
343
615
 
344
616
  - **React 18+ Integration**: Uses `useSyncExternalStore` for optimal performance
@@ -353,8 +625,18 @@ Hooks automatically subscribe to OIMDB reactive events using `useSyncExternalSto
353
625
 
354
626
  ```typescript
355
627
  import React from 'react';
356
- import { OIMEventQueue, OIMRICollection, OIMReactiveIndexManual } from '@oimdb/core';
357
- import { useSelectEntityByPk, useSelectEntitiesByPks, useSelectEntitiesByIndexKey } from '@oimdb/react';
628
+ import {
629
+ OIMEventQueue,
630
+ OIMRICollection,
631
+ OIMReactiveIndexManualSetBased,
632
+ OIMReactiveIndexManualArrayBased
633
+ } from '@oimdb/core';
634
+ import {
635
+ useSelectEntityByPk,
636
+ useSelectEntitiesByPks,
637
+ useSelectEntitiesByIndexKeySetBased,
638
+ useSelectEntitiesByIndexKeyArrayBased
639
+ } from '@oimdb/react';
358
640
 
359
641
  interface User {
360
642
  id: string;
@@ -366,7 +648,8 @@ interface User {
366
648
  // Setup
367
649
  function createUserCollection() {
368
650
  const queue = new OIMEventQueue();
369
- const teamIndex = new OIMReactiveIndexManual<string, string>(queue);
651
+ // Use SetBased for frequent add/remove operations
652
+ const teamIndex = new OIMReactiveIndexManualSetBased<string, string>(queue);
370
653
 
371
654
  return new OIMRICollection(queue, {
372
655
  collectionOpts: { selectPk: (user: User) => user.id },
@@ -386,9 +669,10 @@ function UserProfile({ userId }: { userId: string }) {
386
669
  }
387
670
 
388
671
  function TeamDashboard({ teamId }: { teamId: string }) {
389
- const teamMembers = useSelectEntitiesByIndexKey(
672
+ // Use SetBased hook for SetBased index
673
+ const teamMembers = useSelectEntitiesByIndexKeySetBased(
390
674
  usersCollection,
391
- usersCollection.indexes.byTeam,
675
+ usersCollection.indexes.byTeam, // OIMReactiveIndexManualSetBased
392
676
  teamId
393
677
  );
394
678
 
@@ -396,7 +680,7 @@ function TeamDashboard({ teamId }: { teamId: string }) {
396
680
  <div>
397
681
  <h3>Team Members ({teamMembers.length})</h3>
398
682
  {teamMembers.map(user => (
399
- <div key={user.id}>{user.name}</div>
683
+ <div key={user?.id}>{user?.name}</div>
400
684
  ))}
401
685
  </div>
402
686
  );
@@ -444,10 +728,20 @@ const user = useEntity(userStorage, 'user123');
444
728
  const users = useEntities(userStorage, userIds);
445
729
  const posts = useIndex(postStorage, categoryIndex, 'tech');
446
730
 
447
- // v1.x - Reactive collections
731
+ // v1.x - Reactive collections with typed indexes
448
732
  const user = useSelectEntityByPk(reactiveCollection, 'user123');
449
733
  const users = useSelectEntitiesByPks(reactiveCollection, userIds);
450
- const posts = useSelectEntitiesByIndexKey(reactiveCollection, reactiveIndex, 'tech');
734
+ // Use appropriate hook based on index type
735
+ const posts = useSelectEntitiesByIndexKeySetBased(
736
+ reactiveCollection,
737
+ reactiveIndexSetBased,
738
+ 'tech'
739
+ );
740
+ const orderedItems = useSelectEntitiesByIndexKeyArrayBased(
741
+ reactiveCollection,
742
+ reactiveIndexArrayBased,
743
+ 'category1'
744
+ );
451
745
  ```
452
746
 
453
747
  ### Collection Creation