@oimdb/react 2.1.1 → 2.1.2

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.
Files changed (2) hide show
  1. package/README.md +32 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -123,6 +123,38 @@ function TeamUsers({ teamId }: { teamId: string }) {
123
123
  - `useSelectValueByObjectKey(object, key)` watches one object key.
124
124
  - `useSelectValuesByObjectKeys(object, keys)` watches several object keys.
125
125
 
126
+ All entity/index hooks return holes as `undefined` (`(TEntity | undefined)[]`), aligned 1:1 with the requested pks/keys — render with a guard (`user ? … : null`).
127
+
128
+ ## Mutable mode + signal hooks (advanced)
129
+
130
+ The default hooks use `useSyncExternalStore`, which detects change by **reference** (`Object.is`). That requires the store to produce a new entity object per update — the default immutable merge (`{ ...prev, ...draft }`), whose copy is the biggest per-update data-layer cost.
131
+
132
+ For update-heavy, fine-grained UIs you can run a collection in **in-place / mutable** mode and bind it with the lighter **signal hooks**:
133
+
134
+ ```tsx
135
+ import { OIMReactiveCollection, createInPlaceEntityUpdater } from '@oimdb/core';
136
+ import {
137
+ useSelectEntityByPkSignal,
138
+ useSelectPksByIndexKeyArrayBasedSignal,
139
+ useSelectPksByIndexKeySetBasedSignal,
140
+ } from '@oimdb/react';
141
+
142
+ // Mutate entities in place — no per-update object allocation.
143
+ const cards = new OIMReactiveCollection<Card, string>(queue, {
144
+ selectPk: (c) => c.id,
145
+ updateEntity: createInPlaceEntityUpdater(),
146
+ });
147
+
148
+ // Signal hooks re-render on the keyed notification (no Object.is), so they see
149
+ // in-place mutations the default uSES hooks would miss.
150
+ const card = useSelectEntityByPkSignal(cards, id);
151
+ const ids = useSelectPksByIndexKeyArrayBasedSignal(cardsByDeck, deckId);
152
+ ```
153
+
154
+ Available signal hooks (same signatures as their default counterparts): `useSelectEntityByPkSignal`, `useSelectPksByIndexKeyArrayBasedSignal`, `useSelectPksByIndexKeySetBasedSignal`. Compose the fine-grained pattern from them: a parent reads pks by index key, each row reads its own entity by pk.
155
+
156
+ **Use only when every reader is subscription-driven.** Trade-offs: not Concurrent-Mode tearing-safe; the entity reference is stable across changes, so `React.memo` on entities, prev/next diffing, time-travel, and the default uSES hooks on the same collection won't see updates. Select each entity where you render it (by pk); don't pass mutable entities into `React.memo` children. See [Performance](https://abaikov.github.io/oimdb/docs/guides/performance) for when this actually pays off (in plain React the per-component commit usually dominates).
157
+
126
158
  ## Context API
127
159
 
128
160
  ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oimdb/react",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "React integration for OIMDB - Hooks for selection and subscription with external storage",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",