@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 +18 -17
- package/dist/index.cjs +22 -33
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +22 -33
- package/llms.txt +53 -26
- package/package.json +2 -2
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(
|
|
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(
|
|
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
|
|
105
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
141
|
-
computed store slot.
|
|
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(
|
|
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(
|
|
155
|
-
**`useOIMSingleBucketSlots(
|
|
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
|
|
182
|
-
|
|
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(
|
|
199
|
-
const pickedCards = useOIMSingleBucketSlots(
|
|
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(
|
|
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,
|
|
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(
|
|
179
|
-
return useOIMSlotByKey("useOIMEntity",
|
|
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,
|
|
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(
|
|
211
|
-
return useOIMSingleSlot("useOIMSingleEntity",
|
|
212
|
+
function useOIMSingleEntity(singleSlotStoreSlot) {
|
|
213
|
+
return useOIMSingleSlot("useOIMSingleEntity", singleSlotStoreSlot).entity;
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
// src/useOIMSingleBucketSlots.ts
|
|
215
|
-
function useOIMSingleBucketSlots(
|
|
216
|
-
const bucketSlot = useOIMSingleSlot("useOIMSingleBucketSlots",
|
|
217
|
-
return Array.from(
|
|
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(
|
|
284
|
-
const bucketSlot = useOIMSlotByKey("useOIMBucketSlotsByKey",
|
|
285
|
-
return Array.from(
|
|
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(
|
|
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 ||
|
|
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(
|
|
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 =
|
|
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
|
-
}, [
|
|
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(
|
|
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,
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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,
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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>(
|
|
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,
|
|
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(
|
|
139
|
-
return useOIMSlotByKey("useOIMEntity",
|
|
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,
|
|
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(
|
|
171
|
-
return useOIMSingleSlot("useOIMSingleEntity",
|
|
172
|
+
function useOIMSingleEntity(singleSlotStoreSlot) {
|
|
173
|
+
return useOIMSingleSlot("useOIMSingleEntity", singleSlotStoreSlot).entity;
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
// src/useOIMSingleBucketSlots.ts
|
|
175
|
-
function useOIMSingleBucketSlots(
|
|
176
|
-
const bucketSlot = useOIMSingleSlot("useOIMSingleBucketSlots",
|
|
177
|
-
return Array.from(
|
|
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(
|
|
244
|
-
const bucketSlot = useOIMSlotByKey("useOIMBucketSlotsByKey",
|
|
245
|
-
return Array.from(
|
|
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(
|
|
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 ||
|
|
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(
|
|
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 =
|
|
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
|
-
}, [
|
|
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(
|
|
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(
|
|
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.
|
|
1180
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
|
3245
|
-
`Pick` of `OIMSlotCollectionService` with only
|
|
3246
|
-
|
|
3247
|
-
`
|
|
3248
|
-
`
|
|
3249
|
-
|
|
3250
|
-
`
|
|
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(
|
|
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
|
|
3265
|
-
|
|
3266
|
-
|
|
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(
|
|
3273
|
-
`useOIMSingleBucketSlots(
|
|
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(
|
|
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.
|
|
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.
|
|
33
|
+
"@oimdb/core": "^4.3.0"
|
|
34
34
|
},
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"author": "Andrei Baikov",
|