doxum 0.1.9 → 0.1.10

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 (33) hide show
  1. package/README.md +34 -18
  2. package/dist/{contract-BNStLbSE.d.ts → contract-CeAnEPBA.d.ts} +31 -14
  3. package/dist/{contract-CIU5FCC1.d.cts → contract-DtGVSXSK.d.cts} +31 -14
  4. package/dist/index.cjs +2 -2
  5. package/dist/index.d.cts +3 -3
  6. package/dist/index.d.ts +3 -3
  7. package/dist/index.js +2 -2
  8. package/dist/{integration-C87tjRop.cjs → integration-BKgGuodm.cjs} +2 -2
  9. package/dist/{integration-C87tjRop.cjs.map → integration-BKgGuodm.cjs.map} +1 -1
  10. package/dist/{integration-D5XCBLJ8.js → integration-VTZ3ICsO.js} +2 -2
  11. package/dist/{integration-D5XCBLJ8.js.map → integration-VTZ3ICsO.js.map} +1 -1
  12. package/dist/integration.cjs +2 -2
  13. package/dist/integration.d.cts +2 -2
  14. package/dist/integration.d.ts +2 -2
  15. package/dist/integration.js +2 -2
  16. package/dist/local-sync.d.cts +1 -1
  17. package/dist/local-sync.d.ts +1 -1
  18. package/dist/react.cjs +2 -2
  19. package/dist/react.js +2 -2
  20. package/dist/{store-cp5CpfCy.d.ts → store-Bs0C0rNd.d.ts} +2 -2
  21. package/dist/{store-CD0KdGsq.d.cts → store-CJuwJl_K.d.cts} +2 -2
  22. package/dist/{store-D7QH6Rzw.js → store-DHFXfWSz.js} +90 -47
  23. package/dist/store-DHFXfWSz.js.map +1 -0
  24. package/dist/{store-1Uob0Ghk.cjs → store-DU2u-qFH.cjs} +95 -52
  25. package/dist/store-DU2u-qFH.cjs.map +1 -0
  26. package/package.json +1 -1
  27. package/skills/doxum-runtime/SKILL.md +3 -1
  28. package/skills/doxum-runtime/references/guide.en.md +18 -14
  29. package/skills/doxum-runtime/references/guide.zh-CN.md +16 -13
  30. package/skills/doxum-runtime/references/patterns.en.md +6 -6
  31. package/skills/doxum-runtime/references/patterns.zh-CN.md +6 -6
  32. package/dist/store-1Uob0Ghk.cjs.map +0 -1
  33. package/dist/store-D7QH6Rzw.js.map +0 -1
@@ -13,12 +13,12 @@ const document = createDocument({
13
13
  initial: { tasks: { a: { title: 'Write', done: false } } },
14
14
  });
15
15
  document.update(draft => {
16
- const task = draft.tasks.a;
16
+ const task = draft.tasks.get('a');
17
17
  if (task) task.done = !task.done;
18
- draft.tasks.b = { title: 'Review', done: false };
18
+ draft.tasks.put('b', { title: 'Review', done: false });
19
19
  return { warnings: [] };
20
20
  });
21
- const done = select(document, state => state.tasks.a?.done);
21
+ const done = select(document, state => state.tasks.get('a')?.done);
22
22
  const tasks = select(document, state => snapshot(state.tasks));
23
23
  document.subscribe(
24
24
  path => path.tasks.item('a').done,
@@ -43,20 +43,24 @@ returns its original readonly reference. Published data is not frozen. Field cop
43
43
  are not supported; mutable exports and serialization belong to application boundaries.
44
44
 
45
45
  Infer preserves optional properties and flat variant unions. Read/Draft contain
46
- collection tools; assign(scope, key, inferValue) handles plain replacements containing
47
- nested table/list/tree data.
46
+ collection tools. Maps use explicit methods; table/list/tree overload replace for
47
+ member and whole-container replacement. `replace(parent, key, inferValue)` handles
48
+ plain replacement of object or variant members that contain collection data.
48
49
 
49
50
  ## Containers And Validation
50
51
 
51
- | Definition | Data | Draft methods |
52
- | -------------------------------- | ------------- | ------------------------------------------------------------- |
53
- | map(valueSchema, { key }?) | record | indexing, assignment, delete |
54
- | table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move |
55
- | list(field, { keyOf }) | array | get/has/ids/insert/set/remove/move/replace |
56
- | tree(field) | rootId?/nodes | get/has/rootId/parent/children/insert/set/remove/move/replace |
52
+ | Definition | Data | Draft methods |
53
+ | -------------------------------- | ------------- | --------------------------------------------------------- |
54
+ | map(valueSchema, { key }?) | record | get/has/ids/put/remove/replace |
55
+ | table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move/replace |
56
+ | list(field, { keyOf }) | array | get/has/ids/insert/remove/move/replace |
57
+ | tree(field) | rootId?/nodes | get/has/rootId/parent/children/insert/remove/move/replace |
57
58
 
58
- Read scopes expose only read methods. Map supports field/object/variant values.
59
- List replacement retains the addressed key. Simple arrays and strokes can be one
59
+ Read scopes expose only read methods. Map supports field/object/variant values;
60
+ put is an upsert and removing a missing key is a no-op. `replace(id, value)` is
61
+ existing-only for table/list/tree, preserves table/list order, and changes only a
62
+ tree payload. `replace(value)` replaces a whole collection. List member replacement
63
+ retains the addressed key. Simple arrays and strokes can be one
60
64
  atomic field. Optional supports field/variant/map/list/tree. Absent differs from
61
65
  present undefined. Variant tags are readonly; change branch by whole replacement.
62
66
 
@@ -64,7 +68,7 @@ Pure synchronous functions and Standard Schema v1 validators receive original in
64
68
  They must not mutate it; successful output is ignored, with no copy or deep conversion
65
69
  check. Transform values before entering Doxum. parse(model, unknown) copies validated
66
70
  structure and shares readonly payloads; strict parse requires atomic validators.
67
- Branded map/table keys flow through access, symbolic paths and impact.
71
+ Branded map/table keys flow through methods, symbolic paths and impact.
68
72
  Path callbacks describe locations, including absent entries, and compile at registration.
69
73
  React useDocumentSelector tracks actual reads and changes dependencies when branching.
70
74
 
@@ -13,12 +13,12 @@ const document = createDocument({
13
13
  initial: { tasks: { a: { title: 'Write', done: false } } },
14
14
  });
15
15
  document.update(draft => {
16
- const task = draft.tasks.a;
16
+ const task = draft.tasks.get('a');
17
17
  if (task) task.done = !task.done;
18
- draft.tasks.b = { title: 'Review', done: false };
18
+ draft.tasks.put('b', { title: 'Review', done: false });
19
19
  return { warnings: [] };
20
20
  });
21
- const done = select(document, state => state.tasks.a?.done);
21
+ const done = select(document, state => state.tasks.get('a')?.done);
22
22
  const tasks = select(document, state => snapshot(state.tasks));
23
23
  document.subscribe(
24
24
  path => path.tasks.item('a').done,
@@ -37,25 +37,28 @@ object/variant 结构只接受 schema 声明的自身属性及 variant 判别字
37
37
  snapshot 只复制 schema 结构;snapshot(rawPayload) 返回原始只读引用。
38
38
  发布数据不做运行时冻结,不再支持字段 copier。需要可修改副本或序列化时由应用边界显式处理。
39
39
 
40
- Infer 保留 optional 属性和扁平 variant 联合。Read/Draft 带集合方法;
41
- 含 table/list/tree 数据的整体替换使用 assign(scope, key, inferValue)。
40
+ Infer 保留 optional 属性和扁平 variant 联合。Read/Draft 带集合方法。map 使用显式方法;
41
+ table/list/tree 的 replace 同时支持成员和整体替换。含集合数据的 object/variant 成员
42
+ 使用 `replace(parent, key, inferValue)` 传入普通 Infer 数据。
42
43
 
43
44
  ## 容器与校验
44
45
 
45
- | 声明 | 数据 | Draft 方法 |
46
- | -------------------------------- | ------------- | ------------------------------------------------------------- |
47
- | map(valueSchema, { key }?) | record | 索引、赋值、delete |
48
- | table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move |
49
- | list(field, { keyOf }) | 普通数组 | get/has/ids/insert/set/remove/move/replace |
50
- | tree(field) | rootId?/nodes | get/has/rootId/parent/children/insert/set/remove/move/replace |
46
+ | 声明 | 数据 | Draft 方法 |
47
+ | -------------------------------- | ------------- | --------------------------------------------------------- |
48
+ | map(valueSchema, { key }?) | record | get/has/ids/put/remove/replace |
49
+ | table(objectOrVariant, { key }?) | ids/byId | get/has/ids/create/remove/move/replace |
50
+ | list(field, { keyOf }) | 普通数组 | get/has/ids/insert/remove/move/replace |
51
+ | tree(field) | rootId?/nodes | get/has/rootId/parent/children/insert/remove/move/replace |
51
52
 
52
- Read 只暴露读取方法。map 支持 field/object/variant。list 替换项必须保持寻址键。
53
+ Read 只暴露读取方法。map 支持 field/object/variant;put 是 upsert,remove 缺失键是 no-op。
54
+ table/list/tree 的 `replace(id, value)` 只替换已存在成员,保持 table/list 顺序,且 tree
55
+ 只改变 payload;`replace(value)` 替换整个集合。list 替换项必须保持寻址键。
53
56
  简单数组与笔画可作为一个原子 field。optional 支持 field/variant/map/list/tree,
54
57
  缺失与存在的 undefined 不同。variant tag 只读,通过整体替换切换分支。
55
58
 
56
59
  校验器是纯同步函数或 Standard Schema v1,直接接收原始引用且不得修改它。
57
60
  成功返回值被忽略,不复制输入,也不深度检查转换;数据转换在进入 Doxum 前完成。
58
- parse(model, unknown) 复制校验后的结构并共享只读 payload;严格解析要求原子字段具备校验器。品牌键贯穿 map/table 访问、
61
+ parse(model, unknown) 复制校验后的结构并共享只读 payload;严格解析要求原子字段具备校验器。品牌键贯穿 map/table 方法、
59
62
  符号路径和 impact。路径回调描述地址,包括缺失键,订阅注册时解析。
60
63
  React useDocumentSelector 追踪实际读取,并在选择分支改变时更新依赖。
61
64
 
@@ -11,7 +11,7 @@ const model = object({
11
11
  });
12
12
  ```
13
13
 
14
- Edit position.x, replace stroke whole, use rows.set(key, value) for keyed item edits.
14
+ Edit position.x, replace stroke whole, and use rows.replace(key, value) for keyed item edits.
15
15
 
16
16
  ## Complex Replacement
17
17
 
@@ -21,13 +21,13 @@ const model = object({
21
21
  });
22
22
  const document = createDocument({ schema: model, initial: { entries: {} } });
23
23
  document.update(draft => {
24
- assign(draft.entries, 'a', { rows: { ids: ['x'], byId: { x: { title: 'First' } } } });
25
- draft.entries.a!.rows.get('x')!.title = 'Updated';
24
+ draft.entries.put('a', { rows: { ids: ['x'], byId: { x: { title: 'First' } } } });
25
+ draft.entries.get('a')!.rows.get('x')!.title = 'Updated';
26
26
  });
27
27
  ```
28
28
 
29
- TypeScript cannot express different read/write types for mapped properties.
30
- assign checks Infer replacement data and uses the same mutation session.
29
+ Map entries use put. Use top-level replace for object/variant members whose Draft
30
+ type contains collection tools; collection replace(next) handles whole containers.
31
31
 
32
32
  ## Domain Keys
33
33
 
@@ -45,7 +45,7 @@ const model = object({ people: map(object({ name: field(text) }), { key: personI
45
45
  const initial = parse(model, { people: { 'person:1': { name: 'Ada' } } });
46
46
  ```
47
47
 
48
- Brands flow through indexed access, table methods, symbolic paths and collection impact.
48
+ Brands flow through map/table methods, symbolic paths and collection impact.
49
49
 
50
50
  ## Ordered Edits, History And Replay
51
51
 
@@ -11,7 +11,7 @@ const model = object({
11
11
  });
12
12
  ```
13
13
 
14
- position.x 细粒度赋值;stroke 整体替换;rows.set(key, value) 按稳定键替换项。
14
+ position.x 细粒度赋值;stroke 整体替换;rows.replace(key, value) 按稳定键替换项。
15
15
 
16
16
  ## 含集合的整体替换
17
17
 
@@ -21,13 +21,13 @@ const model = object({
21
21
  });
22
22
  const document = createDocument({ schema: model, initial: { entries: {} } });
23
23
  document.update(draft => {
24
- assign(draft.entries, 'a', { rows: { ids: ['x'], byId: { x: { title: 'First' } } } });
25
- draft.entries.a!.rows.get('x')!.title = 'Updated';
24
+ draft.entries.put('a', { rows: { ids: ['x'], byId: { x: { title: 'First' } } } });
25
+ draft.entries.get('a')!.rows.get('x')!.title = 'Updated';
26
26
  });
27
27
  ```
28
28
 
29
- TypeScript 映射属性不能分别指定读写类型。assign 校验对应 Infer 数据,
30
- 经同一 mutation session 修改。
29
+ map 条目使用 put。Draft 类型含集合方法的 object/variant 成员使用顶层 replace;
30
+ 集合整体替换使用集合自身的 replace(next),并经同一 mutation session 修改。
31
31
 
32
32
  ## 领域键
33
33
 
@@ -45,7 +45,7 @@ const model = object({ people: map(object({ name: field(text) }), { key: personI
45
45
  const initial = parse(model, { people: { 'person:1': { name: 'Ada' } } });
46
46
  ```
47
47
 
48
- 品牌类型贯穿索引、table 方法、符号路径和 collection impact。
48
+ 品牌类型贯穿 map/table 方法、符号路径和 collection impact。
49
49
 
50
50
  ## 顺序、History 与重放
51
51