@oimdb/browser 1.0.0 → 1.1.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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/llms.txt +53 -26
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -36,7 +36,7 @@ OIMEffectService.INSTANCE.createEffect(db, () => {
36
36
  }, [onlineSlot]);
37
37
  ```
38
38
 
39
- In React, `useOIMSingleEntity(onlineService, online)` from `@oimdb/react` reads the same entity.
39
+ In React, `useOIMSingleEntity(online)` from `@oimdb/react` reads the same entity.
40
40
 
41
41
  | Factory | Entity | Listens to |
42
42
  |---|---|---|
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/browser",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Browser state as OIMDB single slots: online, window focus, document visibility, location.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",