doxum 0.1.31 → 0.1.33

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
@@ -280,6 +280,29 @@ exposes `read`, `select`, `items`, `update`, `batch`, `scope` and `dispose`.
280
280
  `ProjectionScope` mirrors `read`, `select`, `items`, `update`, `batch` and `dispose`, plus
281
281
  `own(definitionOrTree)` for lifecycle ownership of lazy projection definitions.
282
282
 
283
+ ### Commands inside a batch
284
+
285
+ Ordinary reads use `runtime.read`. A batch can read the latest accepted input state through its callback while projection readers keep the last published view:
286
+
287
+ ```ts
288
+ const count = input(0);
289
+ const doubled = derive({ count }, ({ count }) => count * 2);
290
+
291
+ function increment() {
292
+ runtime.batch(read => {
293
+ runtime.update(count, read(count) + 1);
294
+ });
295
+ }
296
+
297
+ runtime.batch(() => {
298
+ increment();
299
+ increment();
300
+ });
301
+ runtime.read(doubled); // 4
302
+ ```
303
+
304
+ The borrowed reader supports scalar and collection inputs and expires with its callback. Nested batches settle at the outer boundary. Cross-input commands can read several latest source values without mirrors. Input equality is checked before acceptance; a failed edit leaves earlier successes intact. A batch is not a transaction. See [batch source reads](docs/projections.md#batch-source-reads) for snapshots, errors and lifecycle.
305
+
283
306
  ### Keyed projection
284
307
 
285
308
  `derive.keyed` preserves a keyed driver's membership and order while deriving entries
@@ -354,14 +377,22 @@ projection dependencies by name:
354
377
  const cardContent = derive.keyed(
355
378
  items,
356
379
  {
380
+ metadata: { source: metadataByItemId },
357
381
  record: { source: records, key: item => item.recordId },
358
382
  view: activeView,
359
383
  fields: visibleFields,
360
384
  },
361
- (item, itemId, { record, view, fields }) => renderCard(itemId, item, record, view, fields)
385
+ (item, itemId, { metadata, record, view, fields }) =>
386
+ renderCard(itemId, item, metadata, record, view, fields)
362
387
  );
363
388
  ```
364
389
 
390
+ Use `{ source }` when driver and dependency use the same key. It directly binds driver
391
+ key `K` to source key `K`, requires the driver key type to be assignable to the source
392
+ key type, and avoids a redundant `key: (_value, id) => id` selector. Source value or
393
+ membership changes invalidate only the driver entry with that key; source order-only
394
+ changes do not invalidate it.
395
+
365
396
  For `{ source, key }` dependencies, the Runtime owns output-key → source-key bindings
366
397
  and reverse invalidation. A missing source entry resolves to `undefined` but remains
367
398
  bound, so adding it later invalidates the dependent output keys. An ordinary projection
@@ -392,6 +423,16 @@ key later creates a new generation. A subscribed missing item stays latent and a
392
423
  if the key is later added. Runtime batches follow the net published membership, so a
393
424
  remove/add collapsed to an update does not create a false lifecycle break.
394
425
 
426
+ ### One-to-many keyed derivation
427
+
428
+ ```ts
429
+ const lines = derive.keyed.flatMap(orders, order =>
430
+ order.lines.map(line => [line.id, line] as const)
431
+ );
432
+ ```
433
+
434
+ Each parent returns ordered `[globalKey, value]` tuples, including zero entries. `flatMap` reuses named/dynamic keyed dependencies and only recomputes invalidated parents. Formal output order follows parent order then child order; parent-only reordering runs no selectors. Duplicate final output keys are errors, and present `undefined` is valid. Same-batch transfers preserve a global key's membership identity. Structural changes can rebuild full order; this is not a claim that every operation costs only the changed entries.
435
+
395
436
  ### Runtime-local keyed state
396
437
 
397
438
  Use `input.collection` for selection, expanded state, local overrides and other
package/dist/advanced.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_transform = require("./transform-B6YxfR0R.cjs");
2
+ const require_transform = require("./transform-CSPGdBe5.cjs");
3
3
  const require_record = require("./record-ChYUi8PP.cjs");
4
4
  //#region core/src/projection/advanced.ts
5
5
  const resetCollectionChange = Object.freeze({ kind: "reset" });
@@ -1,4 +1,4 @@
1
- import { c as ProjectionChange, d as CollectionRead, l as CollectionChange, n as KeyedDependencyValues, o as KeyedProjection, s as Projection, t as KeyedDependencies, u as CollectionDraft } from "./dependency-B3E65M1E.cjs";
1
+ import { c as ProjectionChange, d as CollectionRead, l as CollectionChange, n as KeyedDependencyValues, o as KeyedProjection, s as Projection, t as KeyedDependencies, u as CollectionDraft } from "./dependency-Cbf3C8eJ.cjs";
2
2
 
3
3
  //#region core/src/projection/collection/change.d.ts
4
4
  declare const collectionChange: {
@@ -1,4 +1,4 @@
1
- import { c as ProjectionChange, d as CollectionRead, l as CollectionChange, n as KeyedDependencyValues, o as KeyedProjection, s as Projection, t as KeyedDependencies, u as CollectionDraft } from "./dependency-BYbdDHNa.js";
1
+ import { c as ProjectionChange, d as CollectionRead, l as CollectionChange, n as KeyedDependencyValues, o as KeyedProjection, s as Projection, t as KeyedDependencies, u as CollectionDraft } from "./dependency-DzxXGYe1.js";
2
2
 
3
3
  //#region core/src/projection/collection/change.d.ts
4
4
  declare const collectionChange: {
package/dist/advanced.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D as defineProcessor, S as compileProjectionDependencies, l as assertSynchronous, p as collectionChange, t as createKeyedTransform, w as collectionView } from "./transform-BQY9I6il.js";
1
+ import { C as compileProjectionDependencies, O as defineProcessor, T as collectionView, r as collectionChange, t as createKeyedTransform, v as assertSynchronous } from "./transform-A9Lx5R2l.js";
2
2
  import { n as isPlainObject } from "./record-B2yRhYsc.js";
3
3
  //#region core/src/projection/advanced.ts
4
4
  const resetCollectionChange = Object.freeze({ kind: "reset" });
@@ -113,6 +113,11 @@ type SingularKeyedDependency<DriverKey extends string, DriverValue, SourceKey ex
113
113
  readonly key: (value: DriverValue, key: DriverKey) => Synchronous<SourceKey | undefined>;
114
114
  readonly keys?: never;
115
115
  };
116
+ type SameKeyedDependency<SourceKey extends string, SourceValue> = {
117
+ readonly source: KeyedProjection<SourceKey, SourceValue>;
118
+ readonly key?: never;
119
+ readonly keys?: never;
120
+ };
116
121
  type PluralKeyedDependency<DriverKey extends string, DriverValue, SourceKey extends string, SourceValue> = {
117
122
  readonly source: KeyedProjection<SourceKey, SourceValue>;
118
123
  readonly keys: (value: DriverValue, key: DriverKey) => Synchronous<readonly SourceKey[]>;
@@ -122,8 +127,15 @@ type KeyedDependency<DriverKey extends string, DriverValue> = (Projection<unknow
122
127
  readonly source?: never;
123
128
  readonly key?: never;
124
129
  readonly keys?: never;
125
- }) | SingularKeyedDependency<DriverKey, DriverValue, string, unknown> | PluralKeyedDependency<DriverKey, DriverValue, string, unknown>;
126
- type KeyedDependencies<DriverKey extends string, DriverValue, D extends object> = { readonly [P in keyof D]: P extends string ? KeyedDependency<DriverKey, DriverValue> : never };
130
+ }) | SameKeyedDependency<string, unknown> | SingularKeyedDependency<DriverKey, DriverValue, string, unknown> | PluralKeyedDependency<DriverKey, DriverValue, string, unknown>;
131
+ type SameKeyConstraint<DriverKey extends string, Dependency> = Dependency extends {
132
+ readonly source: KeyedProjection<infer SourceKey extends string, unknown>;
133
+ } ? Dependency extends {
134
+ readonly key: unknown;
135
+ } | {
136
+ readonly keys: unknown;
137
+ } ? unknown : [DriverKey] extends [SourceKey] ? unknown : never : unknown;
138
+ type KeyedDependencies<DriverKey extends string, DriverValue, D extends object> = { readonly [P in keyof D]: P extends string ? KeyedDependency<DriverKey, DriverValue> & SameKeyConstraint<DriverKey, D[P]> : never };
127
139
  type KeyedDependencyValues<D extends object> = { readonly [P in keyof D]: D[P] extends {
128
140
  readonly source: KeyedProjection<infer K extends string, infer V>;
129
141
  readonly keys: (...args: never[]) => unknown;
@@ -132,4 +144,4 @@ type KeyedDependencyValues<D extends object> = { readonly [P in keyof D]: D[P] e
132
144
  } ? V | undefined : D[P] extends Projection<infer T> ? T : never };
133
145
  //#endregion
134
146
  export { ProjectionDisposedError as _, Input as a, ProjectionChange as c, CollectionRead as d, ExternalCollectionEvent as f, ExternalValueSource as g, ExternalValueEvent as h, CollectionInputDraft as i, CollectionChange as l, ExternalCollectionSource as m, KeyedDependencyValues as n, KeyedProjection as o, ExternalCollectionRead as p, CollectionInput as r, Projection as s, KeyedDependencies as t, CollectionDraft as u, ProjectionError as v };
135
- //# sourceMappingURL=dependency-B3E65M1E.d.cts.map
147
+ //# sourceMappingURL=dependency-Cbf3C8eJ.d.cts.map
@@ -113,6 +113,11 @@ type SingularKeyedDependency<DriverKey extends string, DriverValue, SourceKey ex
113
113
  readonly key: (value: DriverValue, key: DriverKey) => Synchronous<SourceKey | undefined>;
114
114
  readonly keys?: never;
115
115
  };
116
+ type SameKeyedDependency<SourceKey extends string, SourceValue> = {
117
+ readonly source: KeyedProjection<SourceKey, SourceValue>;
118
+ readonly key?: never;
119
+ readonly keys?: never;
120
+ };
116
121
  type PluralKeyedDependency<DriverKey extends string, DriverValue, SourceKey extends string, SourceValue> = {
117
122
  readonly source: KeyedProjection<SourceKey, SourceValue>;
118
123
  readonly keys: (value: DriverValue, key: DriverKey) => Synchronous<readonly SourceKey[]>;
@@ -122,8 +127,15 @@ type KeyedDependency<DriverKey extends string, DriverValue> = (Projection<unknow
122
127
  readonly source?: never;
123
128
  readonly key?: never;
124
129
  readonly keys?: never;
125
- }) | SingularKeyedDependency<DriverKey, DriverValue, string, unknown> | PluralKeyedDependency<DriverKey, DriverValue, string, unknown>;
126
- type KeyedDependencies<DriverKey extends string, DriverValue, D extends object> = { readonly [P in keyof D]: P extends string ? KeyedDependency<DriverKey, DriverValue> : never };
130
+ }) | SameKeyedDependency<string, unknown> | SingularKeyedDependency<DriverKey, DriverValue, string, unknown> | PluralKeyedDependency<DriverKey, DriverValue, string, unknown>;
131
+ type SameKeyConstraint<DriverKey extends string, Dependency> = Dependency extends {
132
+ readonly source: KeyedProjection<infer SourceKey extends string, unknown>;
133
+ } ? Dependency extends {
134
+ readonly key: unknown;
135
+ } | {
136
+ readonly keys: unknown;
137
+ } ? unknown : [DriverKey] extends [SourceKey] ? unknown : never : unknown;
138
+ type KeyedDependencies<DriverKey extends string, DriverValue, D extends object> = { readonly [P in keyof D]: P extends string ? KeyedDependency<DriverKey, DriverValue> & SameKeyConstraint<DriverKey, D[P]> : never };
127
139
  type KeyedDependencyValues<D extends object> = { readonly [P in keyof D]: D[P] extends {
128
140
  readonly source: KeyedProjection<infer K extends string, infer V>;
129
141
  readonly keys: (...args: never[]) => unknown;
@@ -132,4 +144,4 @@ type KeyedDependencyValues<D extends object> = { readonly [P in keyof D]: D[P] e
132
144
  } ? V | undefined : D[P] extends Projection<infer T> ? T : never };
133
145
  //#endregion
134
146
  export { ProjectionDisposedError as _, Input as a, ProjectionChange as c, CollectionRead as d, ExternalCollectionEvent as f, ExternalValueSource as g, ExternalValueEvent as h, CollectionInputDraft as i, CollectionChange as l, ExternalCollectionSource as m, KeyedDependencyValues as n, KeyedProjection as o, ExternalCollectionRead as p, CollectionInput as r, Projection as s, KeyedDependencies as t, CollectionDraft as u, ProjectionError as v };
135
- //# sourceMappingURL=dependency-BYbdDHNa.d.ts.map
147
+ //# sourceMappingURL=dependency-DzxXGYe1.d.ts.map