@llui/dom 0.0.40 → 0.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.
Files changed (68) hide show
  1. package/README.md +22 -21
  2. package/dist/binding.d.ts +5 -0
  3. package/dist/binding.d.ts.map +1 -1
  4. package/dist/binding.js +1 -0
  5. package/dist/binding.js.map +1 -1
  6. package/dist/combine.d.ts +67 -0
  7. package/dist/combine.d.ts.map +1 -0
  8. package/dist/combine.js +76 -0
  9. package/dist/combine.js.map +1 -0
  10. package/dist/compose.d.ts +27 -21
  11. package/dist/compose.d.ts.map +1 -1
  12. package/dist/compose.js +19 -13
  13. package/dist/compose.js.map +1 -1
  14. package/dist/devtools.d.ts.map +1 -1
  15. package/dist/devtools.js +15 -5
  16. package/dist/devtools.js.map +1 -1
  17. package/dist/el-split.d.ts +1 -1
  18. package/dist/el-split.d.ts.map +1 -1
  19. package/dist/el-split.js +20 -2
  20. package/dist/el-split.js.map +1 -1
  21. package/dist/el-template.d.ts +8 -2
  22. package/dist/el-template.d.ts.map +1 -1
  23. package/dist/el-template.js +2 -1
  24. package/dist/el-template.js.map +1 -1
  25. package/dist/escape-hatch.d.ts +47 -0
  26. package/dist/escape-hatch.d.ts.map +1 -0
  27. package/dist/escape-hatch.js +63 -0
  28. package/dist/escape-hatch.js.map +1 -0
  29. package/dist/hmr.d.ts +2 -1
  30. package/dist/hmr.d.ts.map +1 -1
  31. package/dist/hmr.js +3 -2
  32. package/dist/hmr.js.map +1 -1
  33. package/dist/index.d.ts +3 -4
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2 -3
  36. package/dist/index.js.map +1 -1
  37. package/dist/primitives/branch.d.ts.map +1 -1
  38. package/dist/primitives/branch.js +1 -0
  39. package/dist/primitives/branch.js.map +1 -1
  40. package/dist/primitives/each.d.ts.map +1 -1
  41. package/dist/primitives/each.js +1 -0
  42. package/dist/primitives/each.js.map +1 -1
  43. package/dist/primitives/memo.d.ts +2 -2
  44. package/dist/primitives/memo.d.ts.map +1 -1
  45. package/dist/primitives/memo.js +13 -5
  46. package/dist/primitives/memo.js.map +1 -1
  47. package/dist/primitives/sample.d.ts +2 -2
  48. package/dist/primitives/sample.js +2 -2
  49. package/dist/primitives/sample.js.map +1 -1
  50. package/dist/primitives/unsafe-html.d.ts.map +1 -1
  51. package/dist/primitives/unsafe-html.js +1 -0
  52. package/dist/primitives/unsafe-html.js.map +1 -1
  53. package/dist/primitives/virtual-each.d.ts.map +1 -1
  54. package/dist/primitives/virtual-each.js +7 -4
  55. package/dist/primitives/virtual-each.js.map +1 -1
  56. package/dist/render-context.js +1 -1
  57. package/dist/render-context.js.map +1 -1
  58. package/dist/structural.d.ts +8 -4
  59. package/dist/structural.d.ts.map +1 -1
  60. package/dist/structural.js.map +1 -1
  61. package/dist/types.d.ts +27 -23
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/types.js.map +1 -1
  64. package/dist/update-loop.d.ts +14 -6
  65. package/dist/update-loop.d.ts.map +1 -1
  66. package/dist/update-loop.js +130 -34
  67. package/dist/update-loop.js.map +1 -1
  68. package/package.json +5 -1
package/README.md CHANGED
@@ -70,30 +70,31 @@ Element helpers (`div`, `button`, `span`, etc.) stay as imports — they're stat
70
70
 
71
71
  ### View Primitives
72
72
 
73
- | Primitive | Purpose |
74
- | ---------------------------------- | --------------------------------------------- |
75
- | `text(accessor)` | Reactive text node |
76
- | `show({ when, render })` | Conditional rendering |
77
- | `branch({ on, cases, default? })` | Multi-case switching with optional default |
78
- | `scope({ on, render })` | Keyed subtree rebuild on key change |
79
- | `each({ items, key, render })` | Keyed list rendering |
80
- | `portal({ target, render })` | Render into a different DOM location |
81
- | `child({ def, key, props })` | Full component boundary (Level 2 composition) |
82
- | `memo(accessor)` | Memoized derived value |
83
- | `sample(selector)` | One-shot imperative state read (no binding) |
84
- | `selector(field)` | O(1) one-of-N selection binding |
85
- | `onMount(callback)` | Lifecycle hook (runs once after mount) |
86
- | `errorBoundary(opts)` | Catch render errors |
87
- | `foreign({ create, update })` | Integrate non-LLui libraries |
88
- | `clientOnly({ render, fallback })` | Browser-only subtree (skipped during SSR) |
89
- | `slice(h, selector)` | View over a sub-slice of state |
73
+ | Primitive | Purpose |
74
+ | ---------------------------------- | ------------------------------------------- |
75
+ | `text(accessor)` | Reactive text node |
76
+ | `show({ when, render })` | Conditional rendering |
77
+ | `branch({ on, cases, default? })` | Multi-case switching with optional default |
78
+ | `scope({ on, render })` | Keyed subtree rebuild on key change |
79
+ | `each({ items, key, render })` | Keyed list rendering |
80
+ | `portal({ target, render })` | Render into a different DOM location |
81
+ | `memo(accessor)` | Memoized derived value |
82
+ | `sample(selector)` | One-shot imperative state read (no binding) |
83
+ | `selector(field)` | O(1) one-of-N selection binding |
84
+ | `onMount(callback)` | Lifecycle hook (runs once after mount) |
85
+ | `errorBoundary(opts)` | Catch render errors |
86
+ | `foreign({ create, update })` | Integrate non-LLui libraries |
87
+ | `clientOnly({ render, fallback })` | Browser-only subtree (skipped during SSR) |
88
+ | `slice(h, selector)` | View over a sub-slice of state |
90
89
 
91
90
  ### Composition
92
91
 
93
- | Export | Purpose |
94
- | ----------------------------------------- | -------------------------------- |
95
- | `mergeHandlers(...handlers)` | Combine multiple update handlers |
96
- | `sliceHandler({ get, set, narrow, sub })` | Route messages to a state slice |
92
+ | Export | Purpose |
93
+ | ------------------------------------------- | ----------------------------------------------------------------------- |
94
+ | `combine({ slice: reducer, ... }, top?)` | Compose slice reducers by `${slice}/${action}` message-prefix routing |
95
+ | `mergeHandlers(...handlers)` | Combine multiple update handlers |
96
+ | `sliceHandler({ get, set, narrow, sub })` | Route messages to a state slice |
97
+ | `subApp({ reason, def, data?, onHandle? })` | Embed an isolated TEA loop (escape hatch — requires non-empty `reason`) |
97
98
 
98
99
  ### Context
99
100
 
package/dist/binding.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import type { Lifetime, Binding, BindingKind } from './types.js';
2
2
  export interface CreateBindingOpts {
3
3
  mask: number;
4
+ /**
5
+ * High-word bits 31..61. Optional; defaults to 0. Compiler-emitted
6
+ * only when the accessor reads a prefix past bit 30.
7
+ */
8
+ maskHi?: number;
4
9
  accessor: (state: never) => unknown;
5
10
  kind: BindingKind;
6
11
  node: Node;
@@ -1 +1 @@
1
- {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGhE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;IACnC,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,IAAI,CAAA;IACV,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB;AAID,wBAAgB,eAAe,IAAI,OAAO,EAAE,GAAG,IAAI,CAElD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAiB/E;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EACvD,KAAK,EAAE,OAAO,GACb,IAAI,CA+DN"}
1
+ {"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGhE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAA;IACnC,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,IAAI,CAAA;IACV,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB;AAID,wBAAgB,eAAe,IAAI,OAAO,EAAE,GAAG,IAAI,CAElD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAkB/E;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EACvD,KAAK,EAAE,OAAO,GACb,IAAI,CA+DN"}
package/dist/binding.js CHANGED
@@ -9,6 +9,7 @@ export function setFlatBindings(arr) {
9
9
  export function createBinding(scope, opts) {
10
10
  const binding = {
11
11
  mask: opts.mask,
12
+ maskHi: opts.maskHi ?? 0,
12
13
  accessor: opts.accessor,
13
14
  lastValue: undefined,
14
15
  kind: opts.kind,
@@ -1 +1 @@
1
- {"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Lifetime, Binding, BindingKind } from './types.js'\nimport { addBinding } from './lifetime.js'\n\nexport interface CreateBindingOpts {\n mask: number\n accessor: (state: never) => unknown\n kind: BindingKind\n node: Node\n key?: string\n perItem: boolean\n}\n\nlet flatBindings: Binding[] | null = null\n\nexport function getFlatBindings(): Binding[] | null {\n return flatBindings\n}\n\nexport function setFlatBindings(arr: Binding[] | null): void {\n flatBindings = arr\n}\n\nexport function createBinding(scope: Lifetime, opts: CreateBindingOpts): Binding {\n const binding: Binding = {\n mask: opts.mask,\n accessor: opts.accessor as (state: unknown) => unknown,\n lastValue: undefined,\n kind: opts.kind,\n node: opts.node,\n key: opts.key,\n ownerLifetime: scope,\n perItem: opts.perItem,\n dead: false,\n }\n\n addBinding(scope, binding)\n if (flatBindings) flatBindings.push(binding)\n\n return binding\n}\n\nexport function applyBinding(\n target: { kind: BindingKind; node: Node; key?: string },\n value: unknown,\n): void {\n // Defensive guard: if a reactive accessor leaks through as a raw\n // function value, emitting its `.toString()` into the DOM (e.g. as\n // an attribute) would be a silent correctness bug that only surfaces\n // on server-rendered pages. Throw loudly so the callsite is obvious.\n // Event handlers (onXxx → 'prop' kind) are NOT handled here; events\n // are registered via addEventListener in the element helpers, not\n // via applyBinding.\n if (typeof value === 'function') {\n throw new TypeError(\n `[LLui] applyBinding(${target.kind}${target.key ? `, '${target.key}'` : ''}) received ` +\n `a function as its value. This means an accessor wasn't invoked before ` +\n `reaching the binding layer — usually a bug in a compiled binding tuple or ` +\n `in a helper that forwards props without calling them. The arrow's source ` +\n `would have been serialized into the DOM otherwise. Offender: ${value.toString().slice(0, 120)}`,\n )\n }\n\n switch (target.kind) {\n case 'effect':\n // Side-effect-only binding — the accessor already ran for its\n // side effects in Phase 2. We keep `applyBinding` callable for\n // type-uniform call sites, but there is no DOM write to perform.\n break\n\n case 'text':\n target.node.nodeValue = String(value)\n break\n\n case 'prop': {\n const el = target.node as HTMLElement\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ;(el as any)[target.key!] = value\n break\n }\n\n case 'attr':\n if (value == null) {\n ;(target.node as Element).removeAttribute(target.key!)\n } else if (value === false) {\n // ARIA attributes need explicit \"false\"; others are removed\n if (target.key!.startsWith('aria-')) {\n ;(target.node as Element).setAttribute(target.key!, 'false')\n } else {\n ;(target.node as Element).removeAttribute(target.key!)\n }\n } else {\n ;(target.node as Element).setAttribute(target.key!, String(value))\n }\n break\n\n case 'class':\n ;(target.node as Element).setAttribute('class', value as string)\n break\n\n case 'style':\n if (value == null) {\n ;(target.node as HTMLElement).style.removeProperty(target.key!)\n } else {\n ;(target.node as HTMLElement).style.setProperty(target.key!, value as string)\n }\n break\n }\n}\n"]}
1
+ {"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Lifetime, Binding, BindingKind } from './types.js'\nimport { addBinding } from './lifetime.js'\n\nexport interface CreateBindingOpts {\n mask: number\n /**\n * High-word bits 31..61. Optional; defaults to 0. Compiler-emitted\n * only when the accessor reads a prefix past bit 30.\n */\n maskHi?: number\n accessor: (state: never) => unknown\n kind: BindingKind\n node: Node\n key?: string\n perItem: boolean\n}\n\nlet flatBindings: Binding[] | null = null\n\nexport function getFlatBindings(): Binding[] | null {\n return flatBindings\n}\n\nexport function setFlatBindings(arr: Binding[] | null): void {\n flatBindings = arr\n}\n\nexport function createBinding(scope: Lifetime, opts: CreateBindingOpts): Binding {\n const binding: Binding = {\n mask: opts.mask,\n maskHi: opts.maskHi ?? 0,\n accessor: opts.accessor as (state: unknown) => unknown,\n lastValue: undefined,\n kind: opts.kind,\n node: opts.node,\n key: opts.key,\n ownerLifetime: scope,\n perItem: opts.perItem,\n dead: false,\n }\n\n addBinding(scope, binding)\n if (flatBindings) flatBindings.push(binding)\n\n return binding\n}\n\nexport function applyBinding(\n target: { kind: BindingKind; node: Node; key?: string },\n value: unknown,\n): void {\n // Defensive guard: if a reactive accessor leaks through as a raw\n // function value, emitting its `.toString()` into the DOM (e.g. as\n // an attribute) would be a silent correctness bug that only surfaces\n // on server-rendered pages. Throw loudly so the callsite is obvious.\n // Event handlers (onXxx → 'prop' kind) are NOT handled here; events\n // are registered via addEventListener in the element helpers, not\n // via applyBinding.\n if (typeof value === 'function') {\n throw new TypeError(\n `[LLui] applyBinding(${target.kind}${target.key ? `, '${target.key}'` : ''}) received ` +\n `a function as its value. This means an accessor wasn't invoked before ` +\n `reaching the binding layer — usually a bug in a compiled binding tuple or ` +\n `in a helper that forwards props without calling them. The arrow's source ` +\n `would have been serialized into the DOM otherwise. Offender: ${value.toString().slice(0, 120)}`,\n )\n }\n\n switch (target.kind) {\n case 'effect':\n // Side-effect-only binding — the accessor already ran for its\n // side effects in Phase 2. We keep `applyBinding` callable for\n // type-uniform call sites, but there is no DOM write to perform.\n break\n\n case 'text':\n target.node.nodeValue = String(value)\n break\n\n case 'prop': {\n const el = target.node as HTMLElement\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ;(el as any)[target.key!] = value\n break\n }\n\n case 'attr':\n if (value == null) {\n ;(target.node as Element).removeAttribute(target.key!)\n } else if (value === false) {\n // ARIA attributes need explicit \"false\"; others are removed\n if (target.key!.startsWith('aria-')) {\n ;(target.node as Element).setAttribute(target.key!, 'false')\n } else {\n ;(target.node as Element).removeAttribute(target.key!)\n }\n } else {\n ;(target.node as Element).setAttribute(target.key!, String(value))\n }\n break\n\n case 'class':\n ;(target.node as Element).setAttribute('class', value as string)\n break\n\n case 'style':\n if (value == null) {\n ;(target.node as HTMLElement).style.removeProperty(target.key!)\n } else {\n ;(target.node as HTMLElement).style.setProperty(target.key!, value as string)\n }\n break\n }\n}\n"]}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * A slice reducer — operates on a sub-tree of host state plus its own
3
+ * message variants, returns the next sub-tree and effects to dispatch.
4
+ * Effects from slice reducers bubble up to the top-level effect handler
5
+ * unchanged.
6
+ */
7
+ export type SliceReducer<Slice, Msg, Effect> = (state: Slice, msg: Msg) => [Slice, Effect[]];
8
+ /**
9
+ * Map of slice name → its reducer. The slice name is BOTH:
10
+ * - The top-level state key the slice lives under (`s[name]`)
11
+ * - The message-namespace prefix that routes to this slice
12
+ * (`{type: 'name/action'}` → routes to slice `name`)
13
+ *
14
+ * The matching state shape's top-level keys must therefore be the same
15
+ * set as the routing prefixes — TypeScript enforces this via the `S`
16
+ * generic. Messages whose `type` doesn't start with `${name}/` (or
17
+ * doesn't contain `/` at all) fall through to the optional `_top`
18
+ * reducer below.
19
+ */
20
+ export type SliceMap<S, _M, E> = {
21
+ [K in keyof S]?: SliceReducer<S[K], any, E>;
22
+ };
23
+ /**
24
+ * Optional top-level reducer for messages that don't match any slice
25
+ * prefix. Use for cross-cutting messages (e.g. `{type: 'reset'}`) or
26
+ * messages that operate on multiple slices at once.
27
+ */
28
+ export type TopReducer<S, M, E> = (state: S, msg: M) => [S, E[]];
29
+ /**
30
+ * Compose slice reducers into a single top-level reducer.
31
+ *
32
+ * ```ts
33
+ * type AppState = { matrix: MatrixState; ui: UiState }
34
+ * type AppMsg =
35
+ * | { type: 'matrix/setName'; v: string }
36
+ * | { type: 'ui/toggleSidebar' }
37
+ * | { type: 'reset' }
38
+ *
39
+ * const update = combine<AppState, AppMsg, AppEffect>({
40
+ * matrix: matrixUpdate,
41
+ * ui: uiUpdate,
42
+ * }, (s, msg) => {
43
+ * if (msg.type === 'reset') return [initialState(), []]
44
+ * return [s, []]
45
+ * })
46
+ * ```
47
+ *
48
+ * Routing:
49
+ * - `{type: 'matrix/setName'}` → `matrixUpdate(s.matrix, msg)`. The slice
50
+ * reducer sees the FULL message (including the `matrix/` prefix); the
51
+ * slice's own update body matches on `.type`. This is intentional: it
52
+ * keeps slice reducers usable standalone in unit tests.
53
+ * - `{type: 'reset'}` → routes to the optional top reducer (the second
54
+ * argument). If `_top` is absent, the message is a no-op (state
55
+ * unchanged, no effects).
56
+ *
57
+ * Effects bubble: slice reducers and the top reducer can both return
58
+ * effects; combine concatenates them into the returned array in
59
+ * source order.
60
+ *
61
+ * @param slices Map of slice name → reducer
62
+ * @param _top Optional cross-cutting reducer for unprefixed messages
63
+ */
64
+ export declare function combine<S, M extends {
65
+ type: string;
66
+ }, E>(slices: SliceMap<S, M, E>, _top?: TopReducer<S, M, E>): (state: S, msg: M) => [S, E[]];
67
+ //# sourceMappingURL=combine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;AAE5F;;;;;;;;;;;GAWG;AAIH,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI;KAE9B,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;CAC5C,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,EACtD,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACzB,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GACzB,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAsBhC"}
@@ -0,0 +1,76 @@
1
+ // Reducer composition for slice-based decomposition.
2
+ //
3
+ // `combine()` is the canonical way to compose multiple sub-reducers into
4
+ // a single top-level reducer. Each slice owns a sub-tree of state and an
5
+ // independent `(slice, msg) → [slice, effects]` reducer; the host's
6
+ // state shape nests these slices as top-level keys; messages are routed
7
+ // to slices by namespace (`{type: 'slice/action', ...}` → `slice`'s
8
+ // reducer).
9
+ //
10
+ // This is the load-bearing piece of the unified-composition-model: it
11
+ // replaces the per-component `update()` machinery that `child()` /
12
+ // `component()` previously gave you. A slice is just a module exporting
13
+ // `update` + (optionally) `view` functions. Hosts wire them together
14
+ // with `combine()`.
15
+ //
16
+ // See `docs/proposals/unified-composition-model.md`.
17
+ /**
18
+ * Compose slice reducers into a single top-level reducer.
19
+ *
20
+ * ```ts
21
+ * type AppState = { matrix: MatrixState; ui: UiState }
22
+ * type AppMsg =
23
+ * | { type: 'matrix/setName'; v: string }
24
+ * | { type: 'ui/toggleSidebar' }
25
+ * | { type: 'reset' }
26
+ *
27
+ * const update = combine<AppState, AppMsg, AppEffect>({
28
+ * matrix: matrixUpdate,
29
+ * ui: uiUpdate,
30
+ * }, (s, msg) => {
31
+ * if (msg.type === 'reset') return [initialState(), []]
32
+ * return [s, []]
33
+ * })
34
+ * ```
35
+ *
36
+ * Routing:
37
+ * - `{type: 'matrix/setName'}` → `matrixUpdate(s.matrix, msg)`. The slice
38
+ * reducer sees the FULL message (including the `matrix/` prefix); the
39
+ * slice's own update body matches on `.type`. This is intentional: it
40
+ * keeps slice reducers usable standalone in unit tests.
41
+ * - `{type: 'reset'}` → routes to the optional top reducer (the second
42
+ * argument). If `_top` is absent, the message is a no-op (state
43
+ * unchanged, no effects).
44
+ *
45
+ * Effects bubble: slice reducers and the top reducer can both return
46
+ * effects; combine concatenates them into the returned array in
47
+ * source order.
48
+ *
49
+ * @param slices Map of slice name → reducer
50
+ * @param _top Optional cross-cutting reducer for unprefixed messages
51
+ */
52
+ export function combine(slices, _top) {
53
+ return (state, msg) => {
54
+ // Find the slice this message routes to. Convention: msg.type is
55
+ // `${slice}/${action}`. Anything else falls through to _top.
56
+ const slashIdx = msg.type.indexOf('/');
57
+ if (slashIdx > 0) {
58
+ const sliceName = msg.type.slice(0, slashIdx);
59
+ const reducer = slices[sliceName];
60
+ if (reducer !== undefined) {
61
+ const slice = state[sliceName];
62
+ const [nextSlice, effects] = reducer(slice, msg);
63
+ if (Object.is(nextSlice, slice)) {
64
+ // No state change — preserve top-level reference too.
65
+ return [state, effects];
66
+ }
67
+ return [{ ...state, [sliceName]: nextSlice }, effects];
68
+ }
69
+ // Slice name didn't match — fall through to top.
70
+ }
71
+ if (_top)
72
+ return _top(state, msg);
73
+ return [state, []];
74
+ };
75
+ }
76
+ //# sourceMappingURL=combine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combine.js","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,oEAAoE;AACpE,wEAAwE;AACxE,oEAAoE;AACpE,YAAY;AACZ,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,wEAAwE;AACxE,qEAAqE;AACrE,oBAAoB;AACpB,EAAE;AACF,qDAAqD;AAqCrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,OAAO,CACrB,MAAyB,EACzB,IAA0B;IAE1B,OAAO,CAAC,KAAQ,EAAE,GAAM,EAAY,EAAE;QACpC,iEAAiE;QACjE,6DAA6D;QAC7D,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAY,CAAA;YACxD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;YACjC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;gBAC9B,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;gBAChD,IAAI,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;oBAChC,sDAAsD;oBACtD,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;gBACzB,CAAC;gBACD,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,CAAA;YACxD,CAAC;YACD,iDAAiD;QACnD,CAAC;QACD,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QACjC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACpB,CAAC,CAAA;AACH,CAAC","sourcesContent":["// Reducer composition for slice-based decomposition.\n//\n// `combine()` is the canonical way to compose multiple sub-reducers into\n// a single top-level reducer. Each slice owns a sub-tree of state and an\n// independent `(slice, msg) → [slice, effects]` reducer; the host's\n// state shape nests these slices as top-level keys; messages are routed\n// to slices by namespace (`{type: 'slice/action', ...}` → `slice`'s\n// reducer).\n//\n// This is the load-bearing piece of the unified-composition-model: it\n// replaces the per-component `update()` machinery that `child()` /\n// `component()` previously gave you. A slice is just a module exporting\n// `update` + (optionally) `view` functions. Hosts wire them together\n// with `combine()`.\n//\n// See `docs/proposals/unified-composition-model.md`.\n\n/**\n * A slice reducer — operates on a sub-tree of host state plus its own\n * message variants, returns the next sub-tree and effects to dispatch.\n * Effects from slice reducers bubble up to the top-level effect handler\n * unchanged.\n */\nexport type SliceReducer<Slice, Msg, Effect> = (state: Slice, msg: Msg) => [Slice, Effect[]]\n\n/**\n * Map of slice name → its reducer. The slice name is BOTH:\n * - The top-level state key the slice lives under (`s[name]`)\n * - The message-namespace prefix that routes to this slice\n * (`{type: 'name/action'}` → routes to slice `name`)\n *\n * The matching state shape's top-level keys must therefore be the same\n * set as the routing prefixes — TypeScript enforces this via the `S`\n * generic. Messages whose `type` doesn't start with `${name}/` (or\n * doesn't contain `/` at all) fall through to the optional `_top`\n * reducer below.\n */\n// The Msg generic isn't used directly here — slice reducers carry their\n// own Msg variants. The host's `M` union enforces routing correctness\n// at the `combine()` call site (the returned reducer is typed `(S, M)`).\nexport type SliceMap<S, _M, E> = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [K in keyof S]?: SliceReducer<S[K], any, E>\n}\n\n/**\n * Optional top-level reducer for messages that don't match any slice\n * prefix. Use for cross-cutting messages (e.g. `{type: 'reset'}`) or\n * messages that operate on multiple slices at once.\n */\nexport type TopReducer<S, M, E> = (state: S, msg: M) => [S, E[]]\n\n/**\n * Compose slice reducers into a single top-level reducer.\n *\n * ```ts\n * type AppState = { matrix: MatrixState; ui: UiState }\n * type AppMsg =\n * | { type: 'matrix/setName'; v: string }\n * | { type: 'ui/toggleSidebar' }\n * | { type: 'reset' }\n *\n * const update = combine<AppState, AppMsg, AppEffect>({\n * matrix: matrixUpdate,\n * ui: uiUpdate,\n * }, (s, msg) => {\n * if (msg.type === 'reset') return [initialState(), []]\n * return [s, []]\n * })\n * ```\n *\n * Routing:\n * - `{type: 'matrix/setName'}` → `matrixUpdate(s.matrix, msg)`. The slice\n * reducer sees the FULL message (including the `matrix/` prefix); the\n * slice's own update body matches on `.type`. This is intentional: it\n * keeps slice reducers usable standalone in unit tests.\n * - `{type: 'reset'}` → routes to the optional top reducer (the second\n * argument). If `_top` is absent, the message is a no-op (state\n * unchanged, no effects).\n *\n * Effects bubble: slice reducers and the top reducer can both return\n * effects; combine concatenates them into the returned array in\n * source order.\n *\n * @param slices Map of slice name → reducer\n * @param _top Optional cross-cutting reducer for unprefixed messages\n */\nexport function combine<S, M extends { type: string }, E>(\n slices: SliceMap<S, M, E>,\n _top?: TopReducer<S, M, E>,\n): (state: S, msg: M) => [S, E[]] {\n return (state: S, msg: M): [S, E[]] => {\n // Find the slice this message routes to. Convention: msg.type is\n // `${slice}/${action}`. Anything else falls through to _top.\n const slashIdx = msg.type.indexOf('/')\n if (slashIdx > 0) {\n const sliceName = msg.type.slice(0, slashIdx) as keyof S\n const reducer = slices[sliceName]\n if (reducer !== undefined) {\n const slice = state[sliceName]\n const [nextSlice, effects] = reducer(slice, msg)\n if (Object.is(nextSlice, slice)) {\n // No state change — preserve top-level reference too.\n return [state, effects]\n }\n return [{ ...state, [sliceName]: nextSlice }, effects]\n }\n // Slice name didn't match — fall through to top.\n }\n if (_top) return _top(state, msg)\n return [state, []]\n }\n}\n"]}
package/dist/compose.d.ts CHANGED
@@ -1,27 +1,33 @@
1
1
  /**
2
- * Type-level utilities + runtime helper for composing multiple child
3
- * component modules into a parent's State and Msg types.
2
+ * Type-level utilities + runtime helper for composing multiple sub-module
3
+ * reducers into a parent's State and Msg types.
4
4
  *
5
5
  * Eliminates the manual State/Msg union declarations for each embedded
6
- * sub-component. The developer declares the children map once, and
7
- * `ChildState` / `ChildMsg` derive the wrapper types.
6
+ * module. The developer declares the modules map once, and
7
+ * `ModulesState` / `ModulesMsg` derive the wrapper types.
8
8
  *
9
9
  * ```ts
10
- * import type { ChildState, ChildMsg } from '@llui/dom'
11
- * import { childHandlers } from '@llui/dom'
10
+ * import type { ModulesState, ModulesMsg } from '@llui/dom'
11
+ * import { composeModules } from '@llui/dom'
12
12
  * import { dialog } from '@llui/components/dialog'
13
13
  * import { sortable } from '@llui/components/sortable'
14
14
  *
15
- * const children = { dialog, sort: sortable } as const
15
+ * const modules = { dialog, sort: sortable } as const
16
16
  *
17
- * type State = ChildState<typeof children> & { items: string[] }
18
- * type Msg = ChildMsg<typeof children> | { type: 'addItem'; text: string }
17
+ * type State = ModulesState<typeof modules> & { items: string[] }
18
+ * type Msg = ModulesMsg<typeof modules> | { type: 'addItem'; text: string }
19
19
  *
20
20
  * const update = mergeHandlers<State, Msg, never>(
21
- * childHandlers(children),
21
+ * composeModules(modules),
22
22
  * appUpdate,
23
23
  * )
24
24
  * ```
25
+ *
26
+ * Pairs with `mergeHandlers` (this stack) when embedded modules emit
27
+ * bare messages — typically components from `@llui/components` or
28
+ * third-party packages whose `update` shape you don't control. When you
29
+ * own the slice's message shape, prefer `combine()` with slash-routing
30
+ * (`{type: 'slice/action'}`) instead.
25
31
  */
26
32
  /**
27
33
  * Extract the state type from a component module's update function.
@@ -37,29 +43,29 @@ export type ModuleMsg<T> = T extends {
37
43
  update: (state: infer _S, msg: infer M) => [infer _S2, infer _E];
38
44
  } ? M : never;
39
45
  /**
40
- * Given a record of component modules, derive the combined child state.
46
+ * Given a record of component modules, derive the combined sub-state.
41
47
  * Each key maps to its module's state type.
42
48
  *
43
49
  * ```ts
44
- * const children = { dialog, sort: sortable } as const
45
- * type CS = ChildState<typeof children>
50
+ * const modules = { dialog, sort: sortable } as const
51
+ * type S = ModulesState<typeof modules>
46
52
  * // → { dialog: DialogState; sort: SortableState }
47
53
  * ```
48
54
  */
49
- export type ChildState<T extends Record<string, unknown>> = {
55
+ export type ModulesState<T extends Record<string, unknown>> = {
50
56
  [K in keyof T]: ModuleState<T[K]>;
51
57
  };
52
58
  /**
53
- * Given a record of component modules, derive the combined child message
59
+ * Given a record of component modules, derive the combined message
54
60
  * union. Each module's messages are wrapped in `{ type: key; msg: SubMsg }`.
55
61
  *
56
62
  * ```ts
57
- * const children = { dialog, sort: sortable } as const
58
- * type CM = ChildMsg<typeof children>
63
+ * const modules = { dialog, sort: sortable } as const
64
+ * type M = ModulesMsg<typeof modules>
59
65
  * // → { type: 'dialog'; msg: DialogMsg } | { type: 'sort'; msg: SortableMsg }
60
66
  * ```
61
67
  */
62
- export type ChildMsg<T extends Record<string, unknown>> = {
68
+ export type ModulesMsg<T extends Record<string, unknown>> = {
63
69
  [K in keyof T]: {
64
70
  type: K;
65
71
  msg: ModuleMsg<T[K]>;
@@ -67,12 +73,12 @@ export type ChildMsg<T extends Record<string, unknown>> = {
67
73
  }[keyof T];
68
74
  /**
69
75
  * Create a merged handler from a map of component modules. Each module's
70
- * update is wired via `sliceHandler(key, module.update)` convention:
71
- * state[key] holds the sub-state, messages match `{ type: key; msg: SubMsg }`.
76
+ * update is wired via the convention: state[key] holds the sub-state,
77
+ * messages match `{ type: key; msg: SubMsg }`.
72
78
  *
73
79
  * Returns a handler compatible with `mergeHandlers`.
74
80
  */
75
- export declare function childHandlers<S, M, E>(modules: Record<string, {
81
+ export declare function composeModules<S, M, E>(modules: Record<string, {
76
82
  update: (state: never, msg: never) => [unknown, unknown[]];
77
83
  }>): (state: S, msg: M) => [S, E[]] | null;
78
84
  //# sourceMappingURL=compose.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS;IACrC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;CACjE,GACG,CAAC,GACD,KAAK,CAAA;AAET;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS;IACnC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;CACjE,GACG,CAAC,GACD,KAAK,CAAA;AAET;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACvD,CAAC,IAAI,MAAM,CAAC,GAAG;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE;CAClD,CAAC,MAAM,CAAC,CAAC,CAAA;AAEV;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAAC,GACtF,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAWvC"}
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS;IACrC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;CACjE,GACG,CAAC,GACD,KAAK,CAAA;AAET;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS;IACnC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;CACjE,GACG,CAAC,GACD,KAAK,CAAA;AAET;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KAC3D,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;KACzD,CAAC,IAAI,MAAM,CAAC,GAAG;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE;CAClD,CAAC,MAAM,CAAC,CAAC,CAAA;AAEV;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAAC,GACtF,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAWvC"}
package/dist/compose.js CHANGED
@@ -1,36 +1,42 @@
1
1
  /**
2
- * Type-level utilities + runtime helper for composing multiple child
3
- * component modules into a parent's State and Msg types.
2
+ * Type-level utilities + runtime helper for composing multiple sub-module
3
+ * reducers into a parent's State and Msg types.
4
4
  *
5
5
  * Eliminates the manual State/Msg union declarations for each embedded
6
- * sub-component. The developer declares the children map once, and
7
- * `ChildState` / `ChildMsg` derive the wrapper types.
6
+ * module. The developer declares the modules map once, and
7
+ * `ModulesState` / `ModulesMsg` derive the wrapper types.
8
8
  *
9
9
  * ```ts
10
- * import type { ChildState, ChildMsg } from '@llui/dom'
11
- * import { childHandlers } from '@llui/dom'
10
+ * import type { ModulesState, ModulesMsg } from '@llui/dom'
11
+ * import { composeModules } from '@llui/dom'
12
12
  * import { dialog } from '@llui/components/dialog'
13
13
  * import { sortable } from '@llui/components/sortable'
14
14
  *
15
- * const children = { dialog, sort: sortable } as const
15
+ * const modules = { dialog, sort: sortable } as const
16
16
  *
17
- * type State = ChildState<typeof children> & { items: string[] }
18
- * type Msg = ChildMsg<typeof children> | { type: 'addItem'; text: string }
17
+ * type State = ModulesState<typeof modules> & { items: string[] }
18
+ * type Msg = ModulesMsg<typeof modules> | { type: 'addItem'; text: string }
19
19
  *
20
20
  * const update = mergeHandlers<State, Msg, never>(
21
- * childHandlers(children),
21
+ * composeModules(modules),
22
22
  * appUpdate,
23
23
  * )
24
24
  * ```
25
+ *
26
+ * Pairs with `mergeHandlers` (this stack) when embedded modules emit
27
+ * bare messages — typically components from `@llui/components` or
28
+ * third-party packages whose `update` shape you don't control. When you
29
+ * own the slice's message shape, prefer `combine()` with slash-routing
30
+ * (`{type: 'slice/action'}`) instead.
25
31
  */
26
32
  /**
27
33
  * Create a merged handler from a map of component modules. Each module's
28
- * update is wired via `sliceHandler(key, module.update)` convention:
29
- * state[key] holds the sub-state, messages match `{ type: key; msg: SubMsg }`.
34
+ * update is wired via the convention: state[key] holds the sub-state,
35
+ * messages match `{ type: key; msg: SubMsg }`.
30
36
  *
31
37
  * Returns a handler compatible with `mergeHandlers`.
32
38
  */
33
- export function childHandlers(modules) {
39
+ export function composeModules(modules) {
34
40
  const keys = Object.keys(modules);
35
41
  return (state, msg) => {
36
42
  const m = msg;
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAiDH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAuF;IAEvF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,CAAC,GAAG,GAAsC,CAAA;QAChD,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAE,CAAA;QAC5B,MAAM,KAAK,GAAI,KAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACxD,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAc,EAAE,CAAC,CAAC,GAAY,CAAC,CAAA;QACvE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,EAAO,EAAE,OAAc,CAAC,CAAA;IACjE,CAAC,CAAA;AACH,CAAC","sourcesContent":["/**\n * Type-level utilities + runtime helper for composing multiple child\n * component modules into a parent's State and Msg types.\n *\n * Eliminates the manual State/Msg union declarations for each embedded\n * sub-component. The developer declares the children map once, and\n * `ChildState` / `ChildMsg` derive the wrapper types.\n *\n * ```ts\n * import type { ChildState, ChildMsg } from '@llui/dom'\n * import { childHandlers } from '@llui/dom'\n * import { dialog } from '@llui/components/dialog'\n * import { sortable } from '@llui/components/sortable'\n *\n * const children = { dialog, sort: sortable } as const\n *\n * type State = ChildState<typeof children> & { items: string[] }\n * type Msg = ChildMsg<typeof children> | { type: 'addItem'; text: string }\n *\n * const update = mergeHandlers<State, Msg, never>(\n * childHandlers(children),\n * appUpdate,\n * )\n * ```\n */\n\n/**\n * Extract the state type from a component module's update function.\n * Works with both property and method syntax.\n */\nexport type ModuleState<T> = T extends {\n update: (state: infer S, msg: infer _M) => [infer _S2, infer _E]\n}\n ? S\n : never\n\n/**\n * Extract the message type from a component module's update function.\n */\nexport type ModuleMsg<T> = T extends {\n update: (state: infer _S, msg: infer M) => [infer _S2, infer _E]\n}\n ? M\n : never\n\n/**\n * Given a record of component modules, derive the combined child state.\n * Each key maps to its module's state type.\n *\n * ```ts\n * const children = { dialog, sort: sortable } as const\n * type CS = ChildState<typeof children>\n * // → { dialog: DialogState; sort: SortableState }\n * ```\n */\nexport type ChildState<T extends Record<string, unknown>> = {\n [K in keyof T]: ModuleState<T[K]>\n}\n\n/**\n * Given a record of component modules, derive the combined child message\n * union. Each module's messages are wrapped in `{ type: key; msg: SubMsg }`.\n *\n * ```ts\n * const children = { dialog, sort: sortable } as const\n * type CM = ChildMsg<typeof children>\n * // → { type: 'dialog'; msg: DialogMsg } | { type: 'sort'; msg: SortableMsg }\n * ```\n */\nexport type ChildMsg<T extends Record<string, unknown>> = {\n [K in keyof T]: { type: K; msg: ModuleMsg<T[K]> }\n}[keyof T]\n\n/**\n * Create a merged handler from a map of component modules. Each module's\n * update is wired via `sliceHandler(key, module.update)` convention:\n * state[key] holds the sub-state, messages match `{ type: key; msg: SubMsg }`.\n *\n * Returns a handler compatible with `mergeHandlers`.\n */\nexport function childHandlers<S, M, E>(\n modules: Record<string, { update: (state: never, msg: never) => [unknown, unknown[]] }>,\n): (state: S, msg: M) => [S, E[]] | null {\n const keys = Object.keys(modules)\n return (state, msg) => {\n const m = msg as { type: string; msg?: unknown }\n if (!m.type || !('msg' in m)) return null\n if (!keys.includes(m.type)) return null\n const mod = modules[m.type]!\n const slice = (state as Record<string, unknown>)[m.type]\n const [nextSlice, effects] = mod.update(slice as never, m.msg as never)\n return [{ ...state, [m.type]: nextSlice } as S, effects as E[]]\n }\n}\n"]}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAiDH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAuF;IAEvF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,CAAC,GAAG,GAAsC,CAAA;QAChD,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAE,CAAA;QAC5B,MAAM,KAAK,GAAI,KAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACxD,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAc,EAAE,CAAC,CAAC,GAAY,CAAC,CAAA;QACvE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,EAAO,EAAE,OAAc,CAAC,CAAA;IACjE,CAAC,CAAA;AACH,CAAC","sourcesContent":["/**\n * Type-level utilities + runtime helper for composing multiple sub-module\n * reducers into a parent's State and Msg types.\n *\n * Eliminates the manual State/Msg union declarations for each embedded\n * module. The developer declares the modules map once, and\n * `ModulesState` / `ModulesMsg` derive the wrapper types.\n *\n * ```ts\n * import type { ModulesState, ModulesMsg } from '@llui/dom'\n * import { composeModules } from '@llui/dom'\n * import { dialog } from '@llui/components/dialog'\n * import { sortable } from '@llui/components/sortable'\n *\n * const modules = { dialog, sort: sortable } as const\n *\n * type State = ModulesState<typeof modules> & { items: string[] }\n * type Msg = ModulesMsg<typeof modules> | { type: 'addItem'; text: string }\n *\n * const update = mergeHandlers<State, Msg, never>(\n * composeModules(modules),\n * appUpdate,\n * )\n * ```\n *\n * Pairs with `mergeHandlers` (this stack) when embedded modules emit\n * bare messages — typically components from `@llui/components` or\n * third-party packages whose `update` shape you don't control. When you\n * own the slice's message shape, prefer `combine()` with slash-routing\n * (`{type: 'slice/action'}`) instead.\n */\n\n/**\n * Extract the state type from a component module's update function.\n * Works with both property and method syntax.\n */\nexport type ModuleState<T> = T extends {\n update: (state: infer S, msg: infer _M) => [infer _S2, infer _E]\n}\n ? S\n : never\n\n/**\n * Extract the message type from a component module's update function.\n */\nexport type ModuleMsg<T> = T extends {\n update: (state: infer _S, msg: infer M) => [infer _S2, infer _E]\n}\n ? M\n : never\n\n/**\n * Given a record of component modules, derive the combined sub-state.\n * Each key maps to its module's state type.\n *\n * ```ts\n * const modules = { dialog, sort: sortable } as const\n * type S = ModulesState<typeof modules>\n * // → { dialog: DialogState; sort: SortableState }\n * ```\n */\nexport type ModulesState<T extends Record<string, unknown>> = {\n [K in keyof T]: ModuleState<T[K]>\n}\n\n/**\n * Given a record of component modules, derive the combined message\n * union. Each module's messages are wrapped in `{ type: key; msg: SubMsg }`.\n *\n * ```ts\n * const modules = { dialog, sort: sortable } as const\n * type M = ModulesMsg<typeof modules>\n * // → { type: 'dialog'; msg: DialogMsg } | { type: 'sort'; msg: SortableMsg }\n * ```\n */\nexport type ModulesMsg<T extends Record<string, unknown>> = {\n [K in keyof T]: { type: K; msg: ModuleMsg<T[K]> }\n}[keyof T]\n\n/**\n * Create a merged handler from a map of component modules. Each module's\n * update is wired via the convention: state[key] holds the sub-state,\n * messages match `{ type: key; msg: SubMsg }`.\n *\n * Returns a handler compatible with `mergeHandlers`.\n */\nexport function composeModules<S, M, E>(\n modules: Record<string, { update: (state: never, msg: never) => [unknown, unknown[]] }>,\n): (state: S, msg: M) => [S, E[]] | null {\n const keys = Object.keys(modules)\n return (state, msg) => {\n const m = msg as { type: string; msg?: unknown }\n if (!m.type || !('msg' in m)) return null\n if (!keys.includes(m.type)) return null\n const mod = modules[m.type]!\n const slice = (state as Record<string, unknown>)[m.type]\n const [nextSlice, effects] = mod.update(slice as never, m.msg as never)\n return [{ ...state, [m.type]: nextSlice } as S, effects as E[]]\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"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"}
package/dist/devtools.js CHANGED
@@ -1,4 +1,4 @@
1
- import { flushInstance, _forceState } from './update-loop.js';
1
+ import { flushInstance, _forceState, computeDirtyFromPrefixes, } from './update-loop.js';
2
2
  import { _setDevToolsInstall } from './mount.js';
3
3
  import { _markDisposerLogInstalled } from './lifetime.js';
4
4
  import { applyBinding } from './binding.js';
@@ -898,10 +898,20 @@ export function installDevTools(inst) {
898
898
  const originalUpdate = ci.def.update;
899
899
  ci.def.update = ((state, msg) => {
900
900
  const [newState, effects] = originalUpdate(state, msg);
901
- const dirty = ci.def.__dirty
902
- ? ci.def.__dirty(state, newState)
903
- : -1;
904
- lastDirtyMask = typeof dirty === 'number' ? dirty : -1;
901
+ // Compute the dirty mask from `__prefixes` (the supported reactivity
902
+ // path). Devtools recording only surfaces the LOW word here for the
903
+ // existing MessageRecord shape; high-word changes contribute to the
904
+ // mask via the runtime's full two-word computation but are folded
905
+ // into the `dirtyMask` field's display via FULL_MASK fallback when
906
+ // they alone fire. A future devtools schema upgrade can surface both
907
+ // words separately if needed.
908
+ const prefixes = ci.def.__prefixes;
909
+ let dirty = -1;
910
+ if (prefixes) {
911
+ const computed = computeDirtyFromPrefixes(prefixes, state, newState);
912
+ dirty = typeof computed === 'number' ? computed : computed[0] | computed[1];
913
+ }
914
+ lastDirtyMask = dirty;
905
915
  const record = {
906
916
  index: idx,
907
917
  timestamp: Date.now(),