doxum 0.1.21 → 0.1.23

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 (72) hide show
  1. package/README.md +35 -7
  2. package/dist/{advanced-FgdTwu5b.d.ts → advanced-CLJCWkHa.d.cts} +3 -3
  3. package/dist/{advanced-COFJtWMT.js → advanced-CRNHfJBu.js} +482 -446
  4. package/dist/advanced-CRNHfJBu.js.map +1 -0
  5. package/dist/{advanced-BRL5pN0y.cjs → advanced-Cle5g3B4.cjs} +615 -459
  6. package/dist/advanced-Cle5g3B4.cjs.map +1 -0
  7. package/dist/{advanced-DfKc7TZR.d.cts → advanced-d6J61er9.d.ts} +3 -3
  8. package/dist/advanced.cjs +1 -1
  9. package/dist/advanced.d.cts +1 -1
  10. package/dist/advanced.d.ts +1 -1
  11. package/dist/advanced.js +1 -1
  12. package/dist/context-BcLKGfq8.cjs +149 -0
  13. package/dist/context-BcLKGfq8.cjs.map +1 -0
  14. package/dist/context-DFEaDUv5.js +84 -0
  15. package/dist/context-DFEaDUv5.js.map +1 -0
  16. package/dist/{contract-CdmDHRUq.d.cts → contract-SYJFP0lM.d.cts} +62 -88
  17. package/dist/{contract-KG5XnQZt.d.ts → contract-ULPQmiEs.d.ts} +62 -88
  18. package/dist/driver-BD3DQOW6.cjs +382 -0
  19. package/dist/driver-BD3DQOW6.cjs.map +1 -0
  20. package/dist/{driver-CLYJOGDQ.js → driver-yFfvDMX5.js} +155 -26
  21. package/dist/driver-yFfvDMX5.js.map +1 -0
  22. package/dist/index.cjs +2370 -406
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +6 -5
  25. package/dist/index.d.ts +6 -5
  26. package/dist/index.js +2293 -330
  27. package/dist/index.js.map +1 -1
  28. package/dist/local-sync.cjs +5 -5
  29. package/dist/local-sync.cjs.map +1 -1
  30. package/dist/local-sync.d.cts +1 -1
  31. package/dist/local-sync.d.ts +1 -1
  32. package/dist/local-sync.js +2 -2
  33. package/dist/local-sync.js.map +1 -1
  34. package/dist/react.cjs +2 -69
  35. package/dist/react.cjs.map +1 -1
  36. package/dist/react.d.cts +0 -1
  37. package/dist/react.d.ts +1 -2
  38. package/dist/react.js +3 -70
  39. package/dist/react.js.map +1 -1
  40. package/package.json +1 -6
  41. package/skills/doxum-runtime/SKILL.md +7 -1
  42. package/skills/doxum-runtime/references/guide.en.md +17 -6
  43. package/skills/doxum-runtime/references/guide.zh-CN.md +15 -5
  44. package/skills/doxum-runtime/references/invariants.en.md +5 -3
  45. package/skills/doxum-runtime/references/invariants.zh-CN.md +4 -3
  46. package/skills/doxum-runtime/references/projections.en.md +5 -0
  47. package/skills/doxum-runtime/references/projections.zh-CN.md +5 -0
  48. package/dist/access-BeSV5ve-.js +0 -816
  49. package/dist/access-BeSV5ve-.js.map +0 -1
  50. package/dist/access-Bienf28h.cjs +0 -911
  51. package/dist/access-Bienf28h.cjs.map +0 -1
  52. package/dist/advanced-BRL5pN0y.cjs.map +0 -1
  53. package/dist/advanced-COFJtWMT.js.map +0 -1
  54. package/dist/driver-CLYJOGDQ.js.map +0 -1
  55. package/dist/driver-Djr3BVvo.cjs +0 -241
  56. package/dist/driver-Djr3BVvo.cjs.map +0 -1
  57. package/dist/integration-C4Isp8lJ.js +0 -26
  58. package/dist/integration-C4Isp8lJ.js.map +0 -1
  59. package/dist/integration-Z6MsfFI7.cjs +0 -31
  60. package/dist/integration-Z6MsfFI7.cjs.map +0 -1
  61. package/dist/integration.cjs +0 -12
  62. package/dist/integration.d.cts +0 -17
  63. package/dist/integration.d.ts +0 -17
  64. package/dist/integration.js +0 -4
  65. package/dist/issue-DjK1xp5K.cjs +0 -881
  66. package/dist/issue-DjK1xp5K.cjs.map +0 -1
  67. package/dist/issue-W0hT8u8D.js +0 -642
  68. package/dist/issue-W0hT8u8D.js.map +0 -1
  69. package/dist/notification-Bkjau6B6.js +0 -232
  70. package/dist/notification-Bkjau6B6.js.map +0 -1
  71. package/dist/notification-DJfouMEb.cjs +0 -309
  72. package/dist/notification-DJfouMEb.cjs.map +0 -1
package/README.md CHANGED
@@ -60,10 +60,14 @@ Committed observer failures are returned in `observerErrors` without rollback.
60
60
  ## Read And Observe
61
61
 
62
62
  ```ts
63
- import { read, snapshot } from 'doxum';
63
+ import { read, select, snapshot } from 'doxum';
64
64
 
65
65
  const title = read(document, state => state.title);
66
66
  const tasks = read(document, state => snapshot(state.tasks));
67
+ const selectedTitle = select(document, state => state.title);
68
+ const stop = selectedTitle.subscribe(() => {
69
+ console.log(selectedTitle.current());
70
+ });
67
71
  document.subscribe(
68
72
  path => path.tasks.item('b').title,
69
73
  commit => {
@@ -81,6 +85,10 @@ supported types, while classes/functions need application-specific handling.
81
85
  Use ordinary properties for fine-grained reads. Data callbacks read real values;
82
86
  path callbacks describe symbolic schema locations, including missing entries.
83
87
  Subscription paths compile once during registration.
88
+ `select(document, selector, equality?)` returns a standard `Readable`. Core
89
+ tracks exactly the document locations read by the selector, rebinds dependencies
90
+ when selector branches change, and preserves the previous selected reference and
91
+ publication revision when `equality` reports no result change.
84
92
 
85
93
  React integration:
86
94
 
@@ -91,9 +99,10 @@ const title = useDocumentSelector(document, state => state.title);
91
99
  const history = useHistory(document.history);
92
100
  ```
93
101
 
94
- React tracks fields actually read and updates dependencies when the selector
95
- branches. The core has no React dependency. `asReadable(document)` removes write
96
- capabilities while retaining selection, subscription and projection support.
102
+ Document dependency tracking belongs to Core's `select`; the React adapter only
103
+ subscribes to the resulting `Readable`. The core has no React dependency.
104
+ `asReadable(document)` removes write capabilities while retaining selection,
105
+ subscription and projection support.
97
106
 
98
107
  ## Containers And Parsing
99
108
 
@@ -116,6 +125,12 @@ Doxum; it does not detect validator mutation or conversion. `parse(model, unknow
116
125
  validates and copies schema structure while sharing readonly payloads. Strict parsing
117
126
  requires validators for atomic fields; typed in-memory fields can omit them.
118
127
 
128
+ A tree may be empty, but payload presence follows the payload field schema exactly.
129
+ `tree(field<T>())` requires every existing node to own a `value` property;
130
+ `tree(optional(field<T>()))` is the explicit sparse-payload form. This is independent
131
+ from `optional(tree(...))`, which controls whether the whole tree member may be absent.
132
+ Missing and present-`undefined` payloads remain distinct when the payload field is optional.
133
+
119
134
  Ordered table/list drafts accept either one key or a key selection in
120
135
  `move(key | readonly key[], anchor?)`. A selection is moved as one block while
121
136
  preserving its current canonical relative order; the anchor is resolved after the
@@ -277,8 +292,21 @@ runtime.update(overrides, draft => {
277
292
  and eventful external sources. External sources declare `kind: 'value'` or
278
293
  `kind: 'collection'`; collection invalidation remains keyed internally. Schema
279
294
  `map`, `table`, and `list(field, { keyOf })` paths are all observed as keyed
280
- collection projections. A schema `list` uses its `keyOf` identity and publishes
281
- in document order; ordinary array-valued `field(...)` nodes remain scalar values.
295
+ collection projections. Trees expose structural observation without a second
296
+ projection protocol: `path.tree.rootId` is a scalar source,
297
+ `path.tree.nodes` is a keyed collection source, and
298
+ `path.tree.nodes.item(id)` is a single-node value source. A schema `list` uses its
299
+ `keyOf` identity and publishes in document order; ordinary array-valued `field(...)`
300
+ nodes remain scalar values.
301
+
302
+ Document projection sources route committed groups directly to their observed
303
+ targets, merge affected locations for the current projection batch, then combine the
304
+ previously published snapshot with the canonical final value. A touched tree node
305
+ replaces only that node structure and the necessary ancestor containers; unchanged
306
+ tree-node snapshots keep their identity. Whole aggregate tree values still use the
307
+ public `{ rootId?, nodes: Record }` shape, so changing a node may shallow-copy the
308
+ `nodes` record, while native `tree.nodes` observation remains keyed and touches only
309
+ changed nodes.
282
310
 
283
311
  For retained state, reverse indexes and keyed patches, use the isolated advanced
284
312
  entry point. Whole-value processors use `incremental(...)`; keyed collection
@@ -376,7 +404,7 @@ It also reports structural generation advances and distinguishes captured order
376
404
  baselines from final published order copies. Architecture workloads include order
377
405
  round trips and repeated tree edits to expose costs hidden by commit-only benchmarks.
378
406
 
379
- Builds produce root `dist` ESM/CJS/declarations for `doxum`, `doxum/integration`,
407
+ Builds produce root `dist` ESM/CJS/declarations for `doxum`,
380
408
  `doxum/local-sync`, `doxum/react` and `doxum/advanced`. Source ownership is described in
381
409
  [architecture](docs/architecture.md) and [AGENTS.md](AGENTS.md).
382
410
  The runtime shares one transaction lifecycle; complete mutation operations are
@@ -1,4 +1,4 @@
1
- import { J as Infer, L as CollectionId, R as CollectionNode, Z as ObjectNode, _ as Unsubscribe, et as PathValueOf, m as Synchronous, nt as SchemaPath, s as DocumentReadable, tt as ReadonlyValue, v as Readable, x as CollectionImpact, z as CollectionPath } from "./contract-KG5XnQZt.js";
1
+ import { F as CollectionPath, K as ObjectNode, N as CollectionEntry, P as CollectionId, U as Infer, X as ReadonlyValue, Y as PathValueOf, Z as SchemaPath, _ as Unsubscribe, b as CollectionImpact, g as Readable, o as DocumentReadable, p as Synchronous } from "./contract-SYJFP0lM.cjs";
2
2
 
3
3
  //#region core/src/projection/contract.d.ts
4
4
  /** The one processor-facing collection transition protocol. */
@@ -98,7 +98,7 @@ declare function observe<S extends ObjectNode>(document: DocumentReadable<S>): P
98
98
  declare function observe<T>(source: ExternalValueSource<T>): Projection<T>;
99
99
  declare function observe<K extends string, V>(source: ExternalCollectionSource<K, V>): Projection<ReadonlyMap<K, V>, CollectionChange<K, V>>;
100
100
  declare function observe<T>(readable: Readable<T>): Projection<T>;
101
- declare function observe<S extends ObjectNode, P extends CollectionPath>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): Projection<ReadonlyMap<CollectionId<P>, ReadonlyValue<Infer<CollectionNode<P>>>>, CollectionChange<CollectionId<P>, ReadonlyValue<Infer<CollectionNode<P>>>>>;
101
+ declare function observe<S extends ObjectNode, P extends CollectionPath>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): Projection<ReadonlyMap<CollectionId<P>, ReadonlyValue<CollectionEntry<P>>>, CollectionChange<CollectionId<P>, ReadonlyValue<CollectionEntry<P>>>>;
102
102
  declare function observe<S extends ObjectNode, P>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): Projection<PathValueOf<P>>;
103
103
  declare function derive<const D extends readonly Projection<unknown, unknown>[], T>(dependencies: D, compute: (...values: ProjectionValues$1<D>) => Synchronous<T>, equality?: (previous: T, next: T) => boolean): Projection<T>;
104
104
  //#endregion
@@ -173,4 +173,4 @@ declare const incremental: typeof createIncrementalValue & {
173
173
  };
174
174
  //#endregion
175
175
  export { ProjectionError as C, ProjectionDisposedError as S, ExternalCollectionEvent as _, IncrementalGroupDefine as a, ExternalValueEvent as b, IncrementalValueContext as c, Input as d, Projection as f, CollectionChange as g, observe as h, IncrementalGroupContext as i, IncrementalValueProcessor as l, input as m, IncrementalCollectionContext as n, IncrementalGroupOutputTree as o, derive as p, IncrementalCollectionProcessor as r, IncrementalGroupProcessor as s, GroupProjections as t, incremental as u, ExternalCollectionRead as v, ExternalValueSource as x, ExternalCollectionSource as y };
176
- //# sourceMappingURL=advanced-FgdTwu5b.d.ts.map
176
+ //# sourceMappingURL=advanced-CLJCWkHa.d.cts.map