@oimdb/react 3.1.0 → 3.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
@@ -77,7 +77,7 @@ function App() {
77
77
 
78
78
  // One entity, by key.
79
79
  function Card({ pk }: { pk: string }) {
80
- const card = useOIMEntity(cardService, cards, pk);
80
+ const card = useOIMEntity(cards, pk);
81
81
  return <span>{card?.title}</span>;
82
82
  }
83
83
 
@@ -85,7 +85,7 @@ function Card({ pk }: { pk: string }) {
85
85
  // mounted, and gives the hold back when it unmounts or when `deckId` moves —
86
86
  // there is no release to remember here.
87
87
  function DeckList({ deckId }: { deckId: string }) {
88
- const deckCards = useOIMBucketSlotsByKey(byDeckService, byDeck, deckId);
88
+ const deckCards = useOIMBucketSlotsByKey(byDeck, deckId);
89
89
  return <ul>{deckCards.map((s) => <li key={String(s.key)}>{s.entity?.title}</li>)}</ul>;
90
90
  }
91
91
  ```
@@ -101,8 +101,9 @@ throw when it does not.
101
101
 
102
102
  ## The hooks
103
103
 
104
- Every hook that reads a collection takes the collection service first and the store slot second.
105
- The parameter is typed as a `Pick` of `OIMSlotCollectionService` with only the members the hook calls.
104
+ Every hook that reads a collection by key takes the store slot alone and calls the service it carries,
105
+ `storeSlot.slotService`, typed as a `Pick` of `OIMSlotCollectionService` with only the members the hook calls.
106
+ A store aggregate passes its `storeSlot`.
106
107
 
107
108
  - **`useOIMValue(binding)`**: the binding. It subscribes one effect over the binding's roots and
108
109
  derivations (the effect holds each of them for as long as it lives), settles the derivations before
@@ -112,7 +113,7 @@ The parameter is typed as a `Pick` of `OIMSlotCollectionService` with only the m
112
113
  - **`useOIMComputedValue(computedSlot)`**: the value of ONE computed slot, re-rendering
113
114
  when it changes. It is `useOIMValue` over `sourceComputeds: [computedSlot]`, with the
114
115
  value read off `computedSlot.value` after `useOIMValue` settles it.
115
- - **`useOIMEntity(entityCollectionService, entityStoreSlot, key)`**: one entity, by key. The key is resolved
116
+ - **`useOIMEntity(entityStoreSlot, key)`**: one entity, by key. The key is resolved
116
117
  to an identity ON COMMIT, not on render, through `holdSlotByKey(entityStoreSlot, key)`: a render is not a
117
118
  lifetime, and an identity a discarded render minted would have no hold to give back. The render path reads
118
119
  `getSlotByKey(entityStoreSlot, key)`, so the first paint shows current state. That read mints when the key
@@ -127,32 +128,32 @@ The parameter is typed as a `Pick` of `OIMSlotCollectionService` with only the m
127
128
  bucket's order, read through `bucketCollectionService.slotContentService.getBucketMemberSlots`. The array is
128
129
  copied only when the bucket slot's change stamp (`changedAtRevision`, `changedAtEpoch`) moved. That stamp is
129
130
  reliable here because the caller holds the bucket: a write to a slot nothing holds is not stamped.
130
- - **`useOIMBucketSlotsByKey(bucketCollectionService, bucketStoreSlot, key)`**: one bucket by key, as an array of
131
+ - **`useOIMBucketSlotsByKey(bucketStoreSlot, key)`**: one bucket by key, as an array of
131
132
  entity slots. It resolves the bucket on commit, holds it for as long as the component is mounted, and gives the
132
133
  hold back on unmount or when the key changes. It copies the members on every render: the bucket it reads during a
133
134
  render may be held by nothing yet, and an unheld bucket's stamp does not move. **The key may be built inline**,
134
135
  including the array that keys an `OIMSlotTreeStoreService`; the hook settles it by asking the store which
135
136
  bucket each key names.
136
- - **`useOIMSlotsByKeys(slotCollectionService, storeSlot, keys)`**: several identities of one store slot,
137
+ - **`useOIMSlotsByKeys(storeSlot, keys)`**: several identities of one store slot,
137
138
  resolved by key and held for as long as the component is mounted. It returns the slots and takes no subscription,
138
139
  so use it when a component reads **derivations**: a computed slot exists only while something holds it, and a bare
139
140
  read mints one that the next `flush()` takes straight back. See [Holds per component](#holds-per-component).
140
- - **`useOIMComputedValueByKey(computedCollectionService, computedStoreSlot, key)`**: the value of one key of a
141
- computed store slot. Pass `computedService.computedCollectionService`. It has the same body as `useOIMEntity`:
141
+ - **`useOIMComputedValueByKey(computedStoreSlot, key)`**: the value of one key of a
142
+ computed store slot. It has the same body as `useOIMEntity`:
142
143
  it resolves with `holdSlotByKey` on commit, subscribes over that computed slot, gives the resolve-hold straight
143
144
  back, and reads the value through `computedSlot.computedValueService.getValueForSlot`.
144
145
  - **`useOIMComputedCollection(computedService, derive, createSources, deps)`**: a keyed computed store slot the
145
146
  component owns. The SERVICE is yours, built once at module scope with `createOIMComputedService(options)`; the hook
146
147
  only calls `computedService.createComputedStoreSlot(db, derive, createSources)` in a `useMemo` keyed on `deps`, and
147
148
  returns that store slot. `derive` and `createSources` may be `undefined` when the service already has them.
148
- Read it by key with `useOIMComputedValueByKey(computedService.computedCollectionService, computedStoreSlot, key)`.
149
+ Read it by key with `useOIMComputedValueByKey(computedStoreSlot, key)`.
149
150
  - **`useOIMSingleComputedValue(computedService, derive, createSources, deps)`**: a single computed the
150
151
  component owns. The service is `createOIMSingleComputedService<V>()`, built once at module scope; `derive` and
151
152
  `createSources` receive the computed slot. Per mount the hook builds one store slot and reads its slot through
152
153
  `computedSingleSlotService`, so a flush between render and subscribe, which releases the slot the render minted,
153
154
  is safe.
154
- - **`useOIMSingleEntity(singleSlotService, singleSlotStoreSlot)`** and
155
- **`useOIMSingleBucketSlots(singleSlotService, singleSlotStoreSlot)`**: the single entity and the single bucket.
155
+ - **`useOIMSingleEntity(singleSlotStoreSlot)`** and
156
+ **`useOIMSingleBucketSlots(singleSlotStoreSlot)`**: the single entity and the single bucket.
156
157
  See [Singles](#singles).
157
158
  - **`useOIMDB()`**: the `OIMDB` from `OIMDBContext`. It throws if used outside `<OIMDBProvider>`.
158
159
 
@@ -178,8 +179,8 @@ function TotalRank({ ids }: { ids: readonly string[] }) {
178
179
 
179
180
  A single is a store slot that holds ONE identity and has no key: `createOIMSingleSlotService()` and
180
181
  `createOIMSingleSlotService()` hand back an `OIMSingleSlotService`, read through `getSingleSlot(storeSlot)` and
181
- `holdSingleSlot(storeSlot)`. The two single hooks take that service (typed as a `Pick` of `OIMSingleSlotService`)
182
- and its store slot, and have the by-key hooks' mechanics without the key: the render reads `getSingleSlot`, whose
182
+ `holdSingleSlot(storeSlot)`. The two single hooks take the store slot and call its `slotService` (typed as a
183
+ `Pick` of `OIMSingleSlotService`), and have the by-key hooks' mechanics without the key: the render reads `getSingleSlot`, whose
183
184
  mint the next `flush()` takes back if no commit follows; the commit resolves with `holdSingleSlot`, subscribes over
184
185
  that slot and gives the resolve-hold straight back, so a single released while nothing watched it is minted afresh.
185
186
 
@@ -195,8 +196,8 @@ const pickedService = createOIMSingleSlotService({ slotContentService: new OIMSl
195
196
  const picked = pickedService.createStoreSlot(db);
196
197
 
197
198
  function Toolbar() {
198
- const theme = useOIMSingleEntity(settingsService, settings)?.theme;
199
- const pickedCards = useOIMSingleBucketSlots(pickedService, picked);
199
+ const theme = useOIMSingleEntity(settings)?.theme;
200
+ const pickedCards = useOIMSingleBucketSlots(picked);
200
201
  return <span>{theme}: {pickedCards.length} picked</span>;
201
202
  }
202
203
  ```
@@ -236,7 +237,7 @@ const rankService = createOIMComputedService<string, number>({
236
237
  const ranks = rankService.createComputedStoreSlot(db);
237
238
 
238
239
  function Hand({ ids }: { ids: readonly string[] }) {
239
- const slots = useOIMSlotsByKeys(rankService.computedCollectionService, ranks, ids);
240
+ const slots = useOIMSlotsByKeys(ranks, ids);
240
241
  return <ul>{slots.map((s) => <li key={String(s.key)}>{s.computedValueService.getValueForSlot(s)}</li>)}</ul>;
241
242
  }
242
243
  ```
package/dist/index.cjs CHANGED
@@ -142,8 +142,9 @@ function oimSubscribeHeldSlot(channelMap, hookName, snapshotVersion, holdingSlot
142
142
 
143
143
  // src/useOIMSlotByKey.ts
144
144
  var sourcesOfRootSlot = (rootSlot) => [[rootSlot], import_core3.OIM_FROZEN_EMPTY_SLOTS];
145
- function useOIMSlotByKey(hookName, slotCollectionService, storeSlot, key, sourcesOfSlot = sourcesOfRootSlot) {
145
+ function useOIMSlotByKey(hookName, storeSlot, key, sourcesOfSlot = sourcesOfRootSlot) {
146
146
  const db = useOIMDB();
147
+ const slotCollectionService = storeSlot.slotService;
147
148
  const lastSeenKeyRef = (0, import_react6.useRef)(key);
148
149
  const settledKeyRef = (0, import_react6.useRef)(key);
149
150
  if (key !== lastSeenKeyRef.current) {
@@ -175,16 +176,17 @@ function useOIMSlotByKey(hookName, slotCollectionService, storeSlot, key, source
175
176
  }
176
177
 
177
178
  // src/useOIMEntity.ts
178
- function useOIMEntity(entityCollectionService, entityStoreSlot, key) {
179
- return useOIMSlotByKey("useOIMEntity", entityCollectionService, entityStoreSlot, key).entity;
179
+ function useOIMEntity(entityStoreSlot, key) {
180
+ return useOIMSlotByKey("useOIMEntity", entityStoreSlot, key).entity;
180
181
  }
181
182
 
182
183
  // src/useOIMSingleSlot.ts
183
184
  var import_react7 = require("react");
184
185
  var import_core4 = require("@oimdb/core");
185
186
  var sourcesOfRootSlot2 = (rootSlot) => [[rootSlot], import_core4.OIM_FROZEN_EMPTY_SLOTS];
186
- function useOIMSingleSlot(hookName, singleSlotService, singleSlotStoreSlot, sourcesOfSlot = sourcesOfRootSlot2) {
187
+ function useOIMSingleSlot(hookName, singleSlotStoreSlot, sourcesOfSlot = sourcesOfRootSlot2) {
187
188
  const db = useOIMDB();
189
+ const singleSlotService = singleSlotStoreSlot.slotService;
188
190
  const store = (0, import_react7.useMemo)(() => {
189
191
  const snapshotVersion = new OIMSnapshotVersion();
190
192
  let subscribedSlot = void 0;
@@ -207,14 +209,14 @@ function useOIMSingleSlot(hookName, singleSlotService, singleSlotStoreSlot, sour
207
209
  }
208
210
 
209
211
  // src/useOIMSingleEntity.ts
210
- function useOIMSingleEntity(singleSlotService, singleSlotStoreSlot) {
211
- return useOIMSingleSlot("useOIMSingleEntity", singleSlotService, singleSlotStoreSlot).entity;
212
+ function useOIMSingleEntity(singleSlotStoreSlot) {
213
+ return useOIMSingleSlot("useOIMSingleEntity", singleSlotStoreSlot).entity;
212
214
  }
213
215
 
214
216
  // src/useOIMSingleBucketSlots.ts
215
- function useOIMSingleBucketSlots(singleSlotService, singleSlotStoreSlot) {
216
- const bucketSlot = useOIMSingleSlot("useOIMSingleBucketSlots", singleSlotService, singleSlotStoreSlot);
217
- return Array.from(singleSlotService.slotContentService.getBucketMemberSlots(bucketSlot));
217
+ function useOIMSingleBucketSlots(singleSlotStoreSlot) {
218
+ const bucketSlot = useOIMSingleSlot("useOIMSingleBucketSlots", singleSlotStoreSlot);
219
+ return Array.from(singleSlotStoreSlot.slotService.slotContentService.getBucketMemberSlots(bucketSlot));
218
220
  }
219
221
 
220
222
  // src/useOIMField.ts
@@ -280,15 +282,15 @@ function useOIMBucketSlots(bucketCollectionService, bucketSlot) {
280
282
  }
281
283
 
282
284
  // src/useOIMBucketSlotsByKey.ts
283
- function useOIMBucketSlotsByKey(bucketCollectionService, bucketStoreSlot, key) {
284
- const bucketSlot = useOIMSlotByKey("useOIMBucketSlotsByKey", bucketCollectionService, bucketStoreSlot, key);
285
- return Array.from(bucketCollectionService.slotContentService.getBucketMemberSlots(bucketSlot));
285
+ function useOIMBucketSlotsByKey(bucketStoreSlot, key) {
286
+ const bucketSlot = useOIMSlotByKey("useOIMBucketSlotsByKey", bucketStoreSlot, key);
287
+ return Array.from(bucketStoreSlot.slotService.slotContentService.getBucketMemberSlots(bucketSlot));
286
288
  }
287
289
 
288
290
  // src/useOIMSlotsByKeys.ts
289
291
  var import_react10 = require("react");
290
292
  var import_core6 = require("@oimdb/core");
291
- function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
293
+ function useOIMSlotsByKeys(storeSlot, keys) {
292
294
  const settledKeys = (0, import_react10.useRef)(keys);
293
295
  const previousKeys = settledKeys.current;
294
296
  if (!(0, import_core6.oimSameKeySequence)(previousKeys, keys)) settledKeys.current = keys;
@@ -296,16 +298,14 @@ function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
296
298
  const [, resolveAgain] = (0, import_react10.useState)(0);
297
299
  const resolvedSlots = (0, import_react10.useRef)(void 0);
298
300
  const resolvedKeys = (0, import_react10.useRef)(keysToHold);
299
- const resolvedSlotCollectionService = (0, import_react10.useRef)(slotCollectionService);
300
301
  const resolvedStoreSlot = (0, import_react10.useRef)(storeSlot);
301
- if (resolvedSlots.current === void 0 || resolvedKeys.current !== keysToHold || resolvedSlotCollectionService.current !== slotCollectionService || resolvedStoreSlot.current !== storeSlot) {
302
+ if (resolvedSlots.current === void 0 || resolvedKeys.current !== keysToHold || resolvedStoreSlot.current !== storeSlot) {
302
303
  const slots2 = [];
303
304
  for (let i = 0; i < keysToHold.length; i++) {
304
- slots2.push(slotCollectionService.getSlotByKey(storeSlot, keysToHold[i]));
305
+ slots2.push(storeSlot.slotService.getSlotByKey(storeSlot, keysToHold[i]));
305
306
  }
306
307
  resolvedSlots.current = slots2;
307
308
  resolvedKeys.current = keysToHold;
308
- resolvedSlotCollectionService.current = slotCollectionService;
309
309
  resolvedStoreSlot.current = storeSlot;
310
310
  }
311
311
  const slots = resolvedSlots.current;
@@ -314,7 +314,7 @@ function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
314
314
  const heldSlots = [];
315
315
  let someKeyNamesAnotherIdentityNow = false;
316
316
  for (let i = 0; i < keysToHold.length; i++) {
317
- const slot = slotCollectionService.holdSlotByKey(storeSlot, keysToHold[i]);
317
+ const slot = storeSlot.slotService.holdSlotByKey(storeSlot, keysToHold[i]);
318
318
  heldSlots.push(slot);
319
319
  if (slot !== renderedSlots?.[i]) someKeyNamesAnotherIdentityNow = true;
320
320
  }
@@ -328,21 +328,15 @@ function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
328
328
  heldSlot.owner.unholdSlot(heldSlot);
329
329
  }
330
330
  };
331
- }, [slotCollectionService, storeSlot, keysToHold]);
331
+ }, [storeSlot, keysToHold]);
332
332
  return slots;
333
333
  }
334
334
 
335
335
  // src/useOIMComputedValueByKey.ts
336
336
  var import_core7 = require("@oimdb/core");
337
337
  var sourcesOfComputedSlot = (computedSlot) => [import_core7.OIM_FROZEN_EMPTY_SLOTS, [computedSlot]];
338
- function useOIMComputedValueByKey(computedCollectionService, computedStoreSlot, key) {
339
- const computedSlot = useOIMSlotByKey(
340
- "useOIMComputedValueByKey",
341
- computedCollectionService,
342
- computedStoreSlot,
343
- key,
344
- sourcesOfComputedSlot
345
- );
338
+ function useOIMComputedValueByKey(computedStoreSlot, key) {
339
+ const computedSlot = useOIMSlotByKey("useOIMComputedValueByKey", computedStoreSlot, key, sourcesOfComputedSlot);
346
340
  return computedSlot.computedValueService.getValueForSlot(computedSlot);
347
341
  }
348
342
 
@@ -357,12 +351,7 @@ function useOIMSingleComputedValue(computedService, derive, createSources, depen
357
351
  // eslint-disable-next-line react-hooks/exhaustive-deps -- the caller's list is checked at the call site
358
352
  [db, computedService, ...dependencyList]
359
353
  );
360
- const computedSlot = useOIMSingleSlot(
361
- "useOIMSingleComputedValue",
362
- computedService.computedSingleSlotService,
363
- computedStoreSlot,
364
- sourcesOfComputedSlot2
365
- );
354
+ const computedSlot = useOIMSingleSlot("useOIMSingleComputedValue", computedStoreSlot, sourcesOfComputedSlot2);
366
355
  return computedSlot.computedValueService.getValueForSlot(computedSlot);
367
356
  }
368
357
 
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { DependencyList } from 'react';
3
- import { OIMDB, TOIMSlot, TOIMComputedContentSlot, TOIMStoreKey, OIMSlotCollectionService, TOIMEntitySlot, TOIMStoreSlot, OIMSingleSlotService, TOIMEntityContentSlot, TOIMSingleSlotStore, TOIMBucketContentSlot, OIMSlotContentBucketService, TOIMEntityColumnName, OIMColumnSlotService, TOIMColumnSlot, OIMColumnSlotOwner, TOIMEntityColumnValue, TOIMBucketSlot, TOIMIndexableSlot, TOIMComputedSlot, OIMSingleComputedService, TOIMComputedSources, OIMComputedService, TOIMComputedStoreSlot } from '@oimdb/core';
3
+ import { OIMDB, TOIMSlot, TOIMComputedContentSlot, TOIMStoreKey, TOIMStoreSlot, TOIMEntitySlot, OIMSlotCollectionService, TOIMSingleSlotStore, TOIMEntityContentSlot, OIMSingleSlotService, TOIMBucketContentSlot, OIMSlotContentBucketService, TOIMEntityColumnName, OIMColumnSlotService, TOIMColumnSlot, OIMColumnSlotOwner, TOIMEntityColumnValue, TOIMBucketSlot, TOIMIndexableSlot, TOIMComputedSlot, OIMSingleComputedService, TOIMComputedSources, OIMComputedService, TOIMComputedStoreSlot } from '@oimdb/core';
4
4
 
5
5
  declare const OIMDBContext: React.Context<OIMDB | undefined>;
6
6
 
@@ -28,11 +28,11 @@ declare function useOIMValue<TValue>(binding: TOIMBinding<TValue>): TValue;
28
28
 
29
29
  declare function useOIMComputedValue<TValue>(computedSlot: TOIMComputedContentSlot<TValue>): TValue;
30
30
 
31
- declare function useOIMEntity<TEntity extends object, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(entityCollectionService: Pick<OIMSlotCollectionService<TKey, TOIMEntitySlot<TEntity, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>, entityStoreSlot: TOIMStoreSlot<TStore, TOIMEntitySlot<TEntity, TKey>>, key: TKey): TEntity | undefined;
31
+ declare function useOIMEntity<TEntity extends object, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(entityStoreSlot: TOIMStoreSlot<TStore, TOIMEntitySlot<TEntity, TKey>, unknown, Pick<OIMSlotCollectionService<TKey, TOIMEntitySlot<TEntity, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>>, key: TKey): TEntity | undefined;
32
32
 
33
- declare function useOIMSingleEntity<TEntity extends object>(singleSlotService: Pick<OIMSingleSlotService<TOIMEntityContentSlot<TEntity>, unknown>, 'getSingleSlot' | 'holdSingleSlot'>, singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMEntityContentSlot<TEntity>>, TOIMEntityContentSlot<TEntity>>): TEntity | undefined;
33
+ declare function useOIMSingleEntity<TEntity extends object>(singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMEntityContentSlot<TEntity>>, TOIMEntityContentSlot<TEntity>, unknown, Pick<OIMSingleSlotService<TOIMEntityContentSlot<TEntity>, unknown>, 'getSingleSlot' | 'holdSingleSlot'>>): TEntity | undefined;
34
34
 
35
- declare function useOIMSingleBucketSlots<TEntity extends object, TSlots = unknown>(singleSlotService: Pick<OIMSingleSlotService<TOIMBucketContentSlot<TSlots>, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSingleSlot' | 'holdSingleSlot' | 'slotContentService'>, singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMBucketContentSlot<TSlots>>, TOIMBucketContentSlot<TSlots>>): readonly TOIMEntitySlot<TEntity>[];
35
+ declare function useOIMSingleBucketSlots<TEntity extends object, TSlots = unknown>(singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMBucketContentSlot<TSlots>>, TOIMBucketContentSlot<TSlots>, unknown, Pick<OIMSingleSlotService<TOIMBucketContentSlot<TSlots>, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSingleSlot' | 'holdSingleSlot' | 'slotContentService'>>): readonly TOIMEntitySlot<TEntity>[];
36
36
 
37
37
  /**
38
38
  * One field of one identity. It cannot go through {@link useOIMValue}: a column identity is
@@ -48,14 +48,14 @@ declare function useOIMBucketSlots<TEntity extends object, TSlots = unknown>(buc
48
48
  readonly slotContentService: Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>;
49
49
  }, bucketSlot: TOIMBucketContentSlot<TSlots>): readonly TOIMEntitySlot<TEntity>[];
50
50
 
51
- declare function useOIMBucketSlotsByKey<TEntity extends object, TSlots = unknown, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(bucketCollectionService: Pick<OIMSlotCollectionService<TKey, TOIMBucketSlot<TSlots, TKey>, TStore, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSlotByKey' | 'holdSlotByKey' | 'slotContentService'>, bucketStoreSlot: TOIMStoreSlot<TStore, TOIMBucketSlot<TSlots, TKey>>, key: TKey): readonly TOIMEntitySlot<TEntity>[];
51
+ declare function useOIMBucketSlotsByKey<TEntity extends object, TSlots = unknown, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(bucketStoreSlot: TOIMStoreSlot<TStore, TOIMBucketSlot<TSlots, TKey>, unknown, Pick<OIMSlotCollectionService<TKey, TOIMBucketSlot<TSlots, TKey>, TStore, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSlotByKey' | 'holdSlotByKey' | 'slotContentService'>>, key: TKey): readonly TOIMEntitySlot<TEntity>[];
52
52
 
53
- declare function useOIMSlotsByKeys<TKey extends NonNullable<unknown>, TSlot extends TOIMIndexableSlot<TKey>, TStore = unknown>(slotCollectionService: Pick<OIMSlotCollectionService<TKey, TSlot, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>, storeSlot: TOIMStoreSlot<TStore, TSlot>, keys: readonly TKey[]): readonly TSlot[];
53
+ declare function useOIMSlotsByKeys<TKey extends NonNullable<unknown>, TSlot extends TOIMIndexableSlot<TKey>, TStore = unknown>(storeSlot: TOIMStoreSlot<TStore, TSlot, unknown, Pick<OIMSlotCollectionService<TKey, TSlot, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>>, keys: readonly TKey[]): readonly TSlot[];
54
54
 
55
- declare function useOIMComputedValueByKey<TValue, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(computedCollectionService: Pick<OIMSlotCollectionService<TKey, TOIMComputedSlot<TValue, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>, computedStoreSlot: TOIMStoreSlot<TStore, TOIMComputedSlot<TValue, TKey>>, key: TKey): TValue;
55
+ declare function useOIMComputedValueByKey<TValue, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(computedStoreSlot: TOIMStoreSlot<TStore, TOIMComputedSlot<TValue, TKey>, unknown, Pick<OIMSlotCollectionService<TKey, TOIMComputedSlot<TValue, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>>, key: TKey): TValue;
56
56
 
57
57
  declare function useOIMSingleComputedValue<TValue>(computedService: OIMSingleComputedService<TValue>, derive: ((computedSlot: TOIMComputedContentSlot<TValue>) => TValue) | undefined, createSources: ((computedSlot: TOIMComputedContentSlot<TValue>) => Partial<TOIMComputedSources>) | undefined, dependencyList: DependencyList): TValue;
58
58
 
59
- declare function useOIMComputedCollection<TKey extends NonNullable<unknown>, TValue, TStore>(computedService: OIMComputedService<TKey, TValue, TStore>, derive: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => TValue) | undefined, createSources: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => Partial<TOIMComputedSources>) | undefined, dependencyList: DependencyList): TOIMComputedStoreSlot<TStore, TValue, TOIMComputedSlot<TValue, TKey>>;
59
+ declare function useOIMComputedCollection<TKey extends NonNullable<unknown>, TValue, TStore>(computedService: OIMComputedService<TKey, TValue, TStore>, derive: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => TValue) | undefined, createSources: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => Partial<TOIMComputedSources>) | undefined, dependencyList: DependencyList): TOIMComputedStoreSlot<TStore, TValue, TOIMComputedSlot<TValue, TKey>, OIMComputedService<TKey, TValue, TStore>['computedCollectionService']>;
60
60
 
61
61
  export { OIMDBContext, OIMDBProvider, type TOIMBinding, useOIMBucketSlots, useOIMBucketSlotsByKey, useOIMComputedCollection, useOIMComputedValue, useOIMComputedValueByKey, useOIMDB, useOIMEntity, useOIMField, useOIMSingleBucketSlots, useOIMSingleComputedValue, useOIMSingleEntity, useOIMSlotsByKeys, useOIMValue };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { DependencyList } from 'react';
3
- import { OIMDB, TOIMSlot, TOIMComputedContentSlot, TOIMStoreKey, OIMSlotCollectionService, TOIMEntitySlot, TOIMStoreSlot, OIMSingleSlotService, TOIMEntityContentSlot, TOIMSingleSlotStore, TOIMBucketContentSlot, OIMSlotContentBucketService, TOIMEntityColumnName, OIMColumnSlotService, TOIMColumnSlot, OIMColumnSlotOwner, TOIMEntityColumnValue, TOIMBucketSlot, TOIMIndexableSlot, TOIMComputedSlot, OIMSingleComputedService, TOIMComputedSources, OIMComputedService, TOIMComputedStoreSlot } from '@oimdb/core';
3
+ import { OIMDB, TOIMSlot, TOIMComputedContentSlot, TOIMStoreKey, TOIMStoreSlot, TOIMEntitySlot, OIMSlotCollectionService, TOIMSingleSlotStore, TOIMEntityContentSlot, OIMSingleSlotService, TOIMBucketContentSlot, OIMSlotContentBucketService, TOIMEntityColumnName, OIMColumnSlotService, TOIMColumnSlot, OIMColumnSlotOwner, TOIMEntityColumnValue, TOIMBucketSlot, TOIMIndexableSlot, TOIMComputedSlot, OIMSingleComputedService, TOIMComputedSources, OIMComputedService, TOIMComputedStoreSlot } from '@oimdb/core';
4
4
 
5
5
  declare const OIMDBContext: React.Context<OIMDB | undefined>;
6
6
 
@@ -28,11 +28,11 @@ declare function useOIMValue<TValue>(binding: TOIMBinding<TValue>): TValue;
28
28
 
29
29
  declare function useOIMComputedValue<TValue>(computedSlot: TOIMComputedContentSlot<TValue>): TValue;
30
30
 
31
- declare function useOIMEntity<TEntity extends object, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(entityCollectionService: Pick<OIMSlotCollectionService<TKey, TOIMEntitySlot<TEntity, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>, entityStoreSlot: TOIMStoreSlot<TStore, TOIMEntitySlot<TEntity, TKey>>, key: TKey): TEntity | undefined;
31
+ declare function useOIMEntity<TEntity extends object, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(entityStoreSlot: TOIMStoreSlot<TStore, TOIMEntitySlot<TEntity, TKey>, unknown, Pick<OIMSlotCollectionService<TKey, TOIMEntitySlot<TEntity, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>>, key: TKey): TEntity | undefined;
32
32
 
33
- declare function useOIMSingleEntity<TEntity extends object>(singleSlotService: Pick<OIMSingleSlotService<TOIMEntityContentSlot<TEntity>, unknown>, 'getSingleSlot' | 'holdSingleSlot'>, singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMEntityContentSlot<TEntity>>, TOIMEntityContentSlot<TEntity>>): TEntity | undefined;
33
+ declare function useOIMSingleEntity<TEntity extends object>(singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMEntityContentSlot<TEntity>>, TOIMEntityContentSlot<TEntity>, unknown, Pick<OIMSingleSlotService<TOIMEntityContentSlot<TEntity>, unknown>, 'getSingleSlot' | 'holdSingleSlot'>>): TEntity | undefined;
34
34
 
35
- declare function useOIMSingleBucketSlots<TEntity extends object, TSlots = unknown>(singleSlotService: Pick<OIMSingleSlotService<TOIMBucketContentSlot<TSlots>, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSingleSlot' | 'holdSingleSlot' | 'slotContentService'>, singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMBucketContentSlot<TSlots>>, TOIMBucketContentSlot<TSlots>>): readonly TOIMEntitySlot<TEntity>[];
35
+ declare function useOIMSingleBucketSlots<TEntity extends object, TSlots = unknown>(singleSlotStoreSlot: TOIMStoreSlot<TOIMSingleSlotStore<TOIMBucketContentSlot<TSlots>>, TOIMBucketContentSlot<TSlots>, unknown, Pick<OIMSingleSlotService<TOIMBucketContentSlot<TSlots>, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSingleSlot' | 'holdSingleSlot' | 'slotContentService'>>): readonly TOIMEntitySlot<TEntity>[];
36
36
 
37
37
  /**
38
38
  * One field of one identity. It cannot go through {@link useOIMValue}: a column identity is
@@ -48,14 +48,14 @@ declare function useOIMBucketSlots<TEntity extends object, TSlots = unknown>(buc
48
48
  readonly slotContentService: Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>;
49
49
  }, bucketSlot: TOIMBucketContentSlot<TSlots>): readonly TOIMEntitySlot<TEntity>[];
50
50
 
51
- declare function useOIMBucketSlotsByKey<TEntity extends object, TSlots = unknown, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(bucketCollectionService: Pick<OIMSlotCollectionService<TKey, TOIMBucketSlot<TSlots, TKey>, TStore, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSlotByKey' | 'holdSlotByKey' | 'slotContentService'>, bucketStoreSlot: TOIMStoreSlot<TStore, TOIMBucketSlot<TSlots, TKey>>, key: TKey): readonly TOIMEntitySlot<TEntity>[];
51
+ declare function useOIMBucketSlotsByKey<TEntity extends object, TSlots = unknown, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(bucketStoreSlot: TOIMStoreSlot<TStore, TOIMBucketSlot<TSlots, TKey>, unknown, Pick<OIMSlotCollectionService<TKey, TOIMBucketSlot<TSlots, TKey>, TStore, Pick<OIMSlotContentBucketService<TOIMEntitySlot<TEntity>, TSlots>, 'getBucketMemberSlots'>>, 'getSlotByKey' | 'holdSlotByKey' | 'slotContentService'>>, key: TKey): readonly TOIMEntitySlot<TEntity>[];
52
52
 
53
- declare function useOIMSlotsByKeys<TKey extends NonNullable<unknown>, TSlot extends TOIMIndexableSlot<TKey>, TStore = unknown>(slotCollectionService: Pick<OIMSlotCollectionService<TKey, TSlot, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>, storeSlot: TOIMStoreSlot<TStore, TSlot>, keys: readonly TKey[]): readonly TSlot[];
53
+ declare function useOIMSlotsByKeys<TKey extends NonNullable<unknown>, TSlot extends TOIMIndexableSlot<TKey>, TStore = unknown>(storeSlot: TOIMStoreSlot<TStore, TSlot, unknown, Pick<OIMSlotCollectionService<TKey, TSlot, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>>, keys: readonly TKey[]): readonly TSlot[];
54
54
 
55
- declare function useOIMComputedValueByKey<TValue, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(computedCollectionService: Pick<OIMSlotCollectionService<TKey, TOIMComputedSlot<TValue, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>, computedStoreSlot: TOIMStoreSlot<TStore, TOIMComputedSlot<TValue, TKey>>, key: TKey): TValue;
55
+ declare function useOIMComputedValueByKey<TValue, TKey extends NonNullable<unknown> = TOIMStoreKey, TStore = unknown>(computedStoreSlot: TOIMStoreSlot<TStore, TOIMComputedSlot<TValue, TKey>, unknown, Pick<OIMSlotCollectionService<TKey, TOIMComputedSlot<TValue, TKey>, TStore, unknown>, 'getSlotByKey' | 'holdSlotByKey'>>, key: TKey): TValue;
56
56
 
57
57
  declare function useOIMSingleComputedValue<TValue>(computedService: OIMSingleComputedService<TValue>, derive: ((computedSlot: TOIMComputedContentSlot<TValue>) => TValue) | undefined, createSources: ((computedSlot: TOIMComputedContentSlot<TValue>) => Partial<TOIMComputedSources>) | undefined, dependencyList: DependencyList): TValue;
58
58
 
59
- declare function useOIMComputedCollection<TKey extends NonNullable<unknown>, TValue, TStore>(computedService: OIMComputedService<TKey, TValue, TStore>, derive: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => TValue) | undefined, createSources: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => Partial<TOIMComputedSources>) | undefined, dependencyList: DependencyList): TOIMComputedStoreSlot<TStore, TValue, TOIMComputedSlot<TValue, TKey>>;
59
+ declare function useOIMComputedCollection<TKey extends NonNullable<unknown>, TValue, TStore>(computedService: OIMComputedService<TKey, TValue, TStore>, derive: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => TValue) | undefined, createSources: ((computedSlot: TOIMComputedSlot<TValue, TKey>) => Partial<TOIMComputedSources>) | undefined, dependencyList: DependencyList): TOIMComputedStoreSlot<TStore, TValue, TOIMComputedSlot<TValue, TKey>, OIMComputedService<TKey, TValue, TStore>['computedCollectionService']>;
60
60
 
61
61
  export { OIMDBContext, OIMDBProvider, type TOIMBinding, useOIMBucketSlots, useOIMBucketSlotsByKey, useOIMComputedCollection, useOIMComputedValue, useOIMComputedValueByKey, useOIMDB, useOIMEntity, useOIMField, useOIMSingleBucketSlots, useOIMSingleComputedValue, useOIMSingleEntity, useOIMSlotsByKeys, useOIMValue };
package/dist/index.js CHANGED
@@ -102,8 +102,9 @@ function oimSubscribeHeldSlot(channelMap, hookName, snapshotVersion, holdingSlot
102
102
 
103
103
  // src/useOIMSlotByKey.ts
104
104
  var sourcesOfRootSlot = (rootSlot) => [[rootSlot], OIM_FROZEN_EMPTY_SLOTS2];
105
- function useOIMSlotByKey(hookName, slotCollectionService, storeSlot, key, sourcesOfSlot = sourcesOfRootSlot) {
105
+ function useOIMSlotByKey(hookName, storeSlot, key, sourcesOfSlot = sourcesOfRootSlot) {
106
106
  const db = useOIMDB();
107
+ const slotCollectionService = storeSlot.slotService;
107
108
  const lastSeenKeyRef = useRef(key);
108
109
  const settledKeyRef = useRef(key);
109
110
  if (key !== lastSeenKeyRef.current) {
@@ -135,16 +136,17 @@ function useOIMSlotByKey(hookName, slotCollectionService, storeSlot, key, source
135
136
  }
136
137
 
137
138
  // src/useOIMEntity.ts
138
- function useOIMEntity(entityCollectionService, entityStoreSlot, key) {
139
- return useOIMSlotByKey("useOIMEntity", entityCollectionService, entityStoreSlot, key).entity;
139
+ function useOIMEntity(entityStoreSlot, key) {
140
+ return useOIMSlotByKey("useOIMEntity", entityStoreSlot, key).entity;
140
141
  }
141
142
 
142
143
  // src/useOIMSingleSlot.ts
143
144
  import { useMemo as useMemo4 } from "react";
144
145
  import { OIM_FROZEN_EMPTY_SLOTS as OIM_FROZEN_EMPTY_SLOTS3 } from "@oimdb/core";
145
146
  var sourcesOfRootSlot2 = (rootSlot) => [[rootSlot], OIM_FROZEN_EMPTY_SLOTS3];
146
- function useOIMSingleSlot(hookName, singleSlotService, singleSlotStoreSlot, sourcesOfSlot = sourcesOfRootSlot2) {
147
+ function useOIMSingleSlot(hookName, singleSlotStoreSlot, sourcesOfSlot = sourcesOfRootSlot2) {
147
148
  const db = useOIMDB();
149
+ const singleSlotService = singleSlotStoreSlot.slotService;
148
150
  const store = useMemo4(() => {
149
151
  const snapshotVersion = new OIMSnapshotVersion();
150
152
  let subscribedSlot = void 0;
@@ -167,14 +169,14 @@ function useOIMSingleSlot(hookName, singleSlotService, singleSlotStoreSlot, sour
167
169
  }
168
170
 
169
171
  // src/useOIMSingleEntity.ts
170
- function useOIMSingleEntity(singleSlotService, singleSlotStoreSlot) {
171
- return useOIMSingleSlot("useOIMSingleEntity", singleSlotService, singleSlotStoreSlot).entity;
172
+ function useOIMSingleEntity(singleSlotStoreSlot) {
173
+ return useOIMSingleSlot("useOIMSingleEntity", singleSlotStoreSlot).entity;
172
174
  }
173
175
 
174
176
  // src/useOIMSingleBucketSlots.ts
175
- function useOIMSingleBucketSlots(singleSlotService, singleSlotStoreSlot) {
176
- const bucketSlot = useOIMSingleSlot("useOIMSingleBucketSlots", singleSlotService, singleSlotStoreSlot);
177
- return Array.from(singleSlotService.slotContentService.getBucketMemberSlots(bucketSlot));
177
+ function useOIMSingleBucketSlots(singleSlotStoreSlot) {
178
+ const bucketSlot = useOIMSingleSlot("useOIMSingleBucketSlots", singleSlotStoreSlot);
179
+ return Array.from(singleSlotStoreSlot.slotService.slotContentService.getBucketMemberSlots(bucketSlot));
178
180
  }
179
181
 
180
182
  // src/useOIMField.ts
@@ -240,15 +242,15 @@ function useOIMBucketSlots(bucketCollectionService, bucketSlot) {
240
242
  }
241
243
 
242
244
  // src/useOIMBucketSlotsByKey.ts
243
- function useOIMBucketSlotsByKey(bucketCollectionService, bucketStoreSlot, key) {
244
- const bucketSlot = useOIMSlotByKey("useOIMBucketSlotsByKey", bucketCollectionService, bucketStoreSlot, key);
245
- return Array.from(bucketCollectionService.slotContentService.getBucketMemberSlots(bucketSlot));
245
+ function useOIMBucketSlotsByKey(bucketStoreSlot, key) {
246
+ const bucketSlot = useOIMSlotByKey("useOIMBucketSlotsByKey", bucketStoreSlot, key);
247
+ return Array.from(bucketStoreSlot.slotService.slotContentService.getBucketMemberSlots(bucketSlot));
246
248
  }
247
249
 
248
250
  // src/useOIMSlotsByKeys.ts
249
251
  import { useEffect, useRef as useRef2, useState } from "react";
250
252
  import { oimSameKeySequence } from "@oimdb/core";
251
- function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
253
+ function useOIMSlotsByKeys(storeSlot, keys) {
252
254
  const settledKeys = useRef2(keys);
253
255
  const previousKeys = settledKeys.current;
254
256
  if (!oimSameKeySequence(previousKeys, keys)) settledKeys.current = keys;
@@ -256,16 +258,14 @@ function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
256
258
  const [, resolveAgain] = useState(0);
257
259
  const resolvedSlots = useRef2(void 0);
258
260
  const resolvedKeys = useRef2(keysToHold);
259
- const resolvedSlotCollectionService = useRef2(slotCollectionService);
260
261
  const resolvedStoreSlot = useRef2(storeSlot);
261
- if (resolvedSlots.current === void 0 || resolvedKeys.current !== keysToHold || resolvedSlotCollectionService.current !== slotCollectionService || resolvedStoreSlot.current !== storeSlot) {
262
+ if (resolvedSlots.current === void 0 || resolvedKeys.current !== keysToHold || resolvedStoreSlot.current !== storeSlot) {
262
263
  const slots2 = [];
263
264
  for (let i = 0; i < keysToHold.length; i++) {
264
- slots2.push(slotCollectionService.getSlotByKey(storeSlot, keysToHold[i]));
265
+ slots2.push(storeSlot.slotService.getSlotByKey(storeSlot, keysToHold[i]));
265
266
  }
266
267
  resolvedSlots.current = slots2;
267
268
  resolvedKeys.current = keysToHold;
268
- resolvedSlotCollectionService.current = slotCollectionService;
269
269
  resolvedStoreSlot.current = storeSlot;
270
270
  }
271
271
  const slots = resolvedSlots.current;
@@ -274,7 +274,7 @@ function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
274
274
  const heldSlots = [];
275
275
  let someKeyNamesAnotherIdentityNow = false;
276
276
  for (let i = 0; i < keysToHold.length; i++) {
277
- const slot = slotCollectionService.holdSlotByKey(storeSlot, keysToHold[i]);
277
+ const slot = storeSlot.slotService.holdSlotByKey(storeSlot, keysToHold[i]);
278
278
  heldSlots.push(slot);
279
279
  if (slot !== renderedSlots?.[i]) someKeyNamesAnotherIdentityNow = true;
280
280
  }
@@ -288,21 +288,15 @@ function useOIMSlotsByKeys(slotCollectionService, storeSlot, keys) {
288
288
  heldSlot.owner.unholdSlot(heldSlot);
289
289
  }
290
290
  };
291
- }, [slotCollectionService, storeSlot, keysToHold]);
291
+ }, [storeSlot, keysToHold]);
292
292
  return slots;
293
293
  }
294
294
 
295
295
  // src/useOIMComputedValueByKey.ts
296
296
  import { OIM_FROZEN_EMPTY_SLOTS as OIM_FROZEN_EMPTY_SLOTS4 } from "@oimdb/core";
297
297
  var sourcesOfComputedSlot = (computedSlot) => [OIM_FROZEN_EMPTY_SLOTS4, [computedSlot]];
298
- function useOIMComputedValueByKey(computedCollectionService, computedStoreSlot, key) {
299
- const computedSlot = useOIMSlotByKey(
300
- "useOIMComputedValueByKey",
301
- computedCollectionService,
302
- computedStoreSlot,
303
- key,
304
- sourcesOfComputedSlot
305
- );
298
+ function useOIMComputedValueByKey(computedStoreSlot, key) {
299
+ const computedSlot = useOIMSlotByKey("useOIMComputedValueByKey", computedStoreSlot, key, sourcesOfComputedSlot);
306
300
  return computedSlot.computedValueService.getValueForSlot(computedSlot);
307
301
  }
308
302
 
@@ -317,12 +311,7 @@ function useOIMSingleComputedValue(computedService, derive, createSources, depen
317
311
  // eslint-disable-next-line react-hooks/exhaustive-deps -- the caller's list is checked at the call site
318
312
  [db, computedService, ...dependencyList]
319
313
  );
320
- const computedSlot = useOIMSingleSlot(
321
- "useOIMSingleComputedValue",
322
- computedService.computedSingleSlotService,
323
- computedStoreSlot,
324
- sourcesOfComputedSlot2
325
- );
314
+ const computedSlot = useOIMSingleSlot("useOIMSingleComputedValue", computedStoreSlot, sourcesOfComputedSlot2);
326
315
  return computedSlot.computedValueService.getValueForSlot(computedSlot);
327
316
  }
328
317
 
package/llms.txt CHANGED
@@ -697,7 +697,7 @@ derivation survives a settle, is the SAME instance on the next read (built once)
697
697
  is rebuilt only after the arena is flushed, and `open`/`close` nest so an inner
698
698
  scope ending drops nothing an outer one stands on.
699
699
 
700
- `@oimdb/react`'s `useOIMSlotsByKeys(slotCollectionService, storeSlot, keys)` does not use an arena: it takes a
700
+ `@oimdb/react`'s `useOIMSlotsByKeys(storeSlot, keys)` does not use an arena: it takes a
701
701
  plain `holdSlotByKey` per key on commit and gives the same holds back on unmount or when the key list moves.
702
702
 
703
703
  ```ts signature
@@ -790,10 +790,6 @@ type TOIMDBOptions = {
790
790
  onBeforeFlush?: () => void; // start of the flush, before the frame; READ ONLY, a write is refused
791
791
  getNowMs?: () => number; // the release collectors' clock; absent = Date.now
792
792
  releaseTimer?: TOIMTimer; // the release collectors' timer; absent = an unref'd setTimeout
793
- entityWriter?: IOIMEntityWriter; // default entity writer for every entity factory
794
- indexKeysService?: IOIMIndexKeysService;
795
- slotStamp?: IOIMSlotStamp<TOIMSlot>;
796
- slotReleasePolicy?: IOIMSlotReleasePolicy; // default release policy for every factory
797
793
  };
798
794
 
799
795
  db.clock // TOIMChannelClock, the same object as db.defaultChannelSlot.clock
@@ -1176,9 +1172,8 @@ frame, with no further code. Every mutation goes through a domain neuron — a w
1176
1172
  from outside the orchestrator is the mistake, not a case to cover with a fallback.
1177
1173
  Full page: `website/docs/guides/with-cnstra.md`.
1178
1174
 
1179
- The doors are free functions, one module each, so a consumer ships only the one they import. The collection,
1180
- single and index factories take `db` first and ONE options object second; the computed factories take only
1181
- the options object. Each builds a SERVICE,
1175
+ The doors are free functions, one module each, so a consumer ships only the one they import. Every factory
1176
+ takes ONE options object and no `db`; the `db` goes to `createStoreSlot(db)`. Each builds a SERVICE,
1182
1177
  once per collection type; the store slot is made separately:
1183
1178
 
1184
1179
  | Door | Builds | Store slot |
@@ -1192,8 +1187,36 @@ once per collection type; the store slot is made separately:
1192
1187
  | `createOIMSortedComputedService({ indexService, sortColumns?, comparator?, slotReleasePolicy?, columnSlotStoreService?, computedSlotStoreService? })` | `OIMSortedComputedService` — per key, the entity slots of the index bucket under that key, sorted; see [Sorted lists](#sorted-lists) | `createSortedStoreSlot(indexStoreSlot)` |
1193
1188
  | `createOIMBucketMemoComputedService({ bucketCollectionService, slotReleasePolicy?, columnSlotStoreService?, computedSlotStoreService? })` | `OIMBucketMemoComputedService` — per key, the bucket's slots as one array; see [The order of a bucket](#the-order-of-a-bucket-as-one-derivation-per-key) | `createBucketMemoStoreSlot(bucketStoreSlot)` |
1194
1189
 
1195
- `entityWriter` and `slotReleasePolicy` on these doors default to the
1196
- db's, so naming one overrides it for that service alone.
1190
+ `entityWriter` and `slotReleasePolicy` on these doors default to those of the
1191
+ `defaults` option, so naming one overrides it for that service alone.
1192
+
1193
+ **A store aggregate is the store slot with its store methods, so a call does not pass the store slot.**
1194
+ `service.createStoreAggregate(storeSlot)` wraps a store slot you have (the collection, single and index
1195
+ services each return their own aggregate); `createOIMSlotCollectionStoreAggregate(db, options)` and
1196
+ `createOIMSingleSlotStoreAggregate(db, options)` build service + store slot + aggregate in one call, with the
1197
+ options of `createOIMSlotCollectionService` / `createOIMSingleSlotService` (a new service per call: for many
1198
+ store slots of one type, build the service once).
1199
+
1200
+ ```ts
1201
+ import { createOIMSlotCollectionStoreAggregate } from '@oimdb/core';
1202
+
1203
+ const deckStoreAggregate = createOIMSlotCollectionStoreAggregate(db, { slotContentService: createOIMSlotContentEntityService<Card>() });
1204
+ const aceSlot = deckStoreAggregate.writeSlotContentByKey('c1', { id: 'c1', title: 'Ace', rank: 1, deck: 'spades' }); // = service.writeSlotContentByKey(storeSlot, 'c1', …)
1205
+ deckStoreAggregate.slotContentService.updateEntity(aceSlot, { rank: 14 });
1206
+ deckStoreAggregate.storeSlot; // for hooks, indexes and computeds
1207
+ deckStoreAggregate.slotService; // the service itself
1208
+ ```
1209
+
1210
+ | Aggregate | Methods (the service's, minus the store slot argument) |
1211
+ |---|---|
1212
+ | `OIMSlotCollectionStoreAggregate` | `findSlotByKey`, `hasSlotContentByKey`, `getSlotByKey`, `holdSlotByKey`, `getSlots`, `getSlotCount`, `openBatch`, `closeBatch`, `writeInBatch` |
1213
+ | `OIMWritableSlotCollectionStoreAggregate` | + `writeSlotContentByKey` |
1214
+ | `OIMSingleSlotStoreAggregate` | `findSingleSlot`, `hasSingleSlotContent`, `getSingleSlot`, `holdSingleSlot` |
1215
+ | `OIMWritableSingleSlotStoreAggregate` | + `writeSingleSlotContent`, `clearSingleSlotContent` |
1216
+ | `OIMSlotCollectionIndexStoreAggregate` | the collection methods + `getEntitiesByKey`, `getSlotsByKeys`, `holdSlotsByKeys`, `get/holdBucketColumnByKey`, `get/holdAnyBucketColumnByKey`, `disposeIndexStoreSlot` |
1217
+
1218
+ Every aggregate carries `storeSlot`, `slotService` (typed as the service it came from), `slotContentService`.
1219
+ Methods that take a slot stay on their service.
1197
1220
 
1198
1221
  **A DOOR ALWAYS PASSES; IT NEVER LETS A CLASS REACH FOR A GLOBAL.** Every option
1199
1222
  a service would otherwise answer with `?? OIMDefaults.x` is in the object its
@@ -3085,7 +3108,11 @@ that matches what you are comparing; they are not interchangeable.
3085
3108
 
3086
3109
  ## Full export list
3087
3110
 
3088
- **230 names, every export of `packages/core/src/index.ts`, grouped by topic.**
3111
+ **237 names, every export of `packages/core/src/index.ts`, grouped by topic.**
3112
+
3113
+ *Store aggregates* — `OIMSlotCollectionStoreAggregate` · `OIMWritableSlotCollectionStoreAggregate` ·
3114
+ `OIMSingleSlotStoreAggregate` · `OIMWritableSingleSlotStoreAggregate` · `OIMSlotCollectionIndexStoreAggregate` ·
3115
+ `createOIMSlotCollectionStoreAggregate` · `createOIMSingleSlotStoreAggregate`
3089
3116
 
3090
3117
  *Channel and database slots* — `OIMChannelService` · `TOIMChannelSlot` · `TOIMChannelSlotOptions` · `createOIMChannelSlot` ·
3091
3118
  `IOIMChannelMap` · `TOIMDBOptions` · `OIMFlushSchedulerService` · `TOIMFlushSchedulerSlot` · `IOIMFlushSchedulerListener`
@@ -3241,18 +3268,19 @@ source before generating code against it.
3241
3268
  `@oimdb/react` — `<OIMDBProvider db={db}>` carries the `OIMDB` (`useOIMDB()`) and nothing else: the effect
3242
3269
  service is stateless (`OIMEffectService.INSTANCE`) and every hook subscribes with
3243
3270
  `OIMEffectService.INSTANCE.subscribeEffect(db, …)`. A hook that resolves or takes a slot filed on another `OIMDB`
3244
- throws, since nothing below would wake. Every hook that reads a collection takes the collection service, typed as a
3245
- `Pick` of `OIMSlotCollectionService` with only the members it calls, and then the store slot:
3246
- `useOIMEntity(entityCollectionService, entityStoreSlot, key)`,
3247
- `useOIMField(entityCollectionService, slot, name)` (calls `getColumn(slot, name)`; no store slot, the slot carries it),
3248
- `useOIMBucketSlots(bucketCollectionService, bucketSlot)` and
3249
- `useOIMBucketSlotsByKey(bucketCollectionService, bucketStoreSlot, key)` (both read
3250
- `bucketCollectionService.slotContentService.getBucketMemberSlots`; an index service and its index store slot fit too), and
3271
+ throws, since nothing below would wake. Every hook that reads a collection by key takes the store slot alone and
3272
+ calls the service it carries, `storeSlot.slotService`, typed as a `Pick` of `OIMSlotCollectionService` with only
3273
+ the members it calls (a store aggregate passes its `storeSlot`):
3274
+ `useOIMEntity(entityStoreSlot, key)` and
3275
+ `useOIMBucketSlotsByKey(bucketStoreSlot, key)` (reads `bucketStoreSlot.slotService.slotContentService.getBucketMemberSlots`;
3276
+ an index store slot fits too). The hooks over a slot you already hold take the service and the slot:
3277
+ `useOIMField(entityCollectionService, slot, name)` (calls `getColumn(slot, name)`),
3278
+ `useOIMBucketSlots(bucketCollectionService, bucketSlot)`, and
3251
3279
  `useOIMValue(binding)`, where a binding is `{ sourceSlots?, sourceComputeds?, derive }` (a missing list means none)
3252
3280
  and must keep its identity across renders.
3253
3281
  `useOIMComputedValue(computedSlot: TOIMComputedSlot<TValue>): TValue` is the one-computed case: it subscribes to
3254
3282
  the slot, settles it and reads `computedSlot.value`, with no binding to memoise.
3255
- `useOIMComputedValueByKey(computedService.computedCollectionService, computedStoreSlot, key)` reads one key of a
3283
+ `useOIMComputedValueByKey(computedStoreSlot, key)` reads one key of a
3256
3284
  computed store slot (plain, sorted, bucket memo) with the same by-key body as `useOIMEntity` /
3257
3285
  `useOIMBucketSlotsByKey`: resolve on commit with `holdSlotByKey`, effect over that slot, resolve-hold given back,
3258
3286
  a key built inline settled by meaning.
@@ -3261,16 +3289,15 @@ The computed SERVICE is the caller's, built once at module scope with `createOIM
3261
3289
  slot per mount — `computedService.createComputedStoreSlot(db, derive, createSources)` in a `useMemo` on `deps`;
3262
3290
  `derive` / `createSources` may be `undefined` when the service has them.
3263
3291
  `useOIMSingleComputedValue(computedService, derive, createSources, deps): TValue` is the same for a void-keyed
3264
- service whose `computedSlotStoreService` is `OIMSingleSlotStoreService.INSTANCE`, read through
3265
- `useOIMComputedValueByKey(computedService.computedCollectionService, computedStoreSlot, undefined)`, so a flush
3266
- between render and subscribe is safe.
3267
- `useOIMSlotsByKeys(slotCollectionService, storeSlot, keys)` holds the identities its keys name for as long as the
3292
+ service built with `createOIMSingleComputedService`, its slot read through the store slot's single slot service,
3293
+ so a flush between render and subscribe is safe.
3294
+ `useOIMSlotsByKeys(storeSlot, keys)` holds the identities its keys name for as long as the
3268
3295
  component is mounted (a `holdSlotByKey` per key on commit, the same holds given back on unmount or when the list
3269
3296
  moves) and subscribes to nothing; it needs no provider.
3270
3297
  Singles are not keyed collections: `createOIMSingleSlotService({ slotContentService })` returns an
3271
3298
  `OIMWritableSingleSlotService` (`getSingleSlot(storeSlot)`, `holdSingleSlot(storeSlot)`), read by
3272
- `useOIMSingleEntity(singleSlotService, singleSlotStoreSlot): TEntity | undefined` and
3273
- `useOIMSingleBucketSlots(singleSlotService, singleSlotStoreSlot): readonly TOIMEntitySlot<TEntity>[]` — the by-key
3299
+ `useOIMSingleEntity(singleSlotStoreSlot): TEntity | undefined` and
3300
+ `useOIMSingleBucketSlots(singleSlotStoreSlot): readonly TOIMEntitySlot<TEntity>[]` — the by-key
3274
3301
  mechanics without a key (getSingleSlot on render, holdSingleSlot on commit, resolve-hold given back once the
3275
3302
  effect exists; the bucket members are copied per render). See `packages/react/README.md`.
3276
3303
 
@@ -4013,7 +4040,7 @@ createOIMBrowserLocationSingleSlotService(options?): TOIMBrowserSingleSlotServic
4013
4040
  ```
4014
4041
 
4015
4042
  Read it like any single: `const onlineSlot = onlineService.getSingleSlot(onlineService.createStoreSlot(db))`, then
4016
- an effect over `[onlineSlot]`, or `useOIMSingleEntity(onlineService, online)` in React. `isOnline` is
4043
+ an effect over `[onlineSlot]`, or `useOIMSingleEntity(online)` in React. `isOnline` is
4017
4044
  `navigator.onLine` (a network interface exists, not a reachable internet); the location follows the
4018
4045
  Navigation API's `currententrychange` where it exists and `popstate` + `hashchange` otherwise, so without it a
4019
4046
  `history.pushState` is not seen until the next of those events. Without the API a sensor needs, the slot holds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oimdb/react",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "React bindings for @oimdb/core: hooks that subscribe through OIMChannel and read the slots it wakes.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": "^18.0.0 || ^19.0.0",
33
- "@oimdb/core": "^4.2.0"
33
+ "@oimdb/core": "^4.3.0"
34
34
  },
35
35
  "license": "MIT",
36
36
  "author": "Andrei Baikov",