@llui/dom 0.1.0 → 0.2.1
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/dist/binding-registry.d.ts +10 -0
- package/dist/binding-registry.d.ts.map +1 -0
- package/dist/binding-registry.js +96 -0
- package/dist/binding-registry.js.map +1 -0
- package/dist/binding.d.ts +22 -0
- package/dist/binding.d.ts.map +1 -1
- package/dist/binding.js +56 -5
- package/dist/binding.js.map +1 -1
- package/dist/build-flags.d.ts +25 -0
- package/dist/build-flags.d.ts.map +1 -0
- package/dist/build-flags.js +18 -0
- package/dist/build-flags.js.map +1 -0
- package/dist/compose.d.ts +27 -21
- package/dist/compose.d.ts.map +1 -1
- package/dist/compose.js +19 -13
- package/dist/compose.js.map +1 -1
- package/dist/el-split.d.ts.map +1 -1
- package/dist/el-split.js +8 -4
- package/dist/el-split.js.map +1 -1
- package/dist/el-template.d.ts.map +1 -1
- package/dist/el-template.js +15 -18
- package/dist/el-template.js.map +1 -1
- package/dist/elements.d.ts.map +1 -1
- package/dist/elements.js +12 -4
- package/dist/elements.js.map +1 -1
- package/dist/hmr.js +9 -4
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/test-component-builder.d.ts +21 -0
- package/dist/internal/test-component-builder.d.ts.map +1 -0
- package/dist/internal/test-component-builder.js +65 -0
- package/dist/internal/test-component-builder.js.map +1 -0
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/lifetime.d.ts.map +1 -1
- package/dist/lifetime.js +16 -3
- package/dist/lifetime.js.map +1 -1
- package/dist/mount.d.ts +1 -0
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +32 -22
- package/dist/mount.js.map +1 -1
- package/dist/primitives/branch.d.ts.map +1 -1
- package/dist/primitives/branch.js +29 -16
- package/dist/primitives/branch.js.map +1 -1
- package/dist/primitives/client-only.d.ts +1 -1
- package/dist/primitives/client-only.d.ts.map +1 -1
- package/dist/primitives/client-only.js +3 -3
- package/dist/primitives/client-only.js.map +1 -1
- package/dist/primitives/context.d.ts.map +1 -1
- package/dist/primitives/context.js +6 -3
- package/dist/primitives/context.js.map +1 -1
- package/dist/primitives/each.d.ts.map +1 -1
- package/dist/primitives/each.js +121 -74
- package/dist/primitives/each.js.map +1 -1
- package/dist/primitives/foreign.js +2 -1
- package/dist/primitives/foreign.js.map +1 -1
- package/dist/primitives/lazy.d.ts +1 -1
- package/dist/primitives/lazy.d.ts.map +1 -1
- package/dist/primitives/lazy.js +11 -5
- package/dist/primitives/lazy.js.map +1 -1
- package/dist/primitives/portal.js +2 -1
- package/dist/primitives/portal.js.map +1 -1
- package/dist/primitives/sample.d.ts +2 -2
- package/dist/primitives/sample.d.ts.map +1 -1
- package/dist/primitives/sample.js +24 -18
- package/dist/primitives/sample.js.map +1 -1
- package/dist/primitives/track.d.ts +54 -0
- package/dist/primitives/track.d.ts.map +1 -0
- package/dist/primitives/track.js +54 -0
- package/dist/primitives/track.js.map +1 -0
- package/dist/primitives/virtual-each.js +4 -2
- package/dist/primitives/virtual-each.js.map +1 -1
- package/dist/render-context.d.ts +27 -1
- package/dist/render-context.d.ts.map +1 -1
- package/dist/render-context.js +82 -33
- package/dist/render-context.js.map +1 -1
- package/dist/ssr.d.ts.map +1 -1
- package/dist/ssr.js +5 -3
- package/dist/ssr.js.map +1 -1
- package/dist/types.d.ts +8 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/update-loop.d.ts +1 -0
- package/dist/update-loop.d.ts.map +1 -1
- package/dist/update-loop.js +115 -50
- package/dist/update-loop.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Binding } from './types.js';
|
|
2
|
+
export interface BindingRegistry {
|
|
3
|
+
readonly byPrefix: Map<number, Set<Binding>>;
|
|
4
|
+
readonly subscriptions: WeakMap<Binding, readonly number[]>;
|
|
5
|
+
}
|
|
6
|
+
export declare function createBindingRegistry(): BindingRegistry;
|
|
7
|
+
export declare function registerBinding(reg: BindingRegistry, binding: Binding, prefixIds: readonly number[]): void;
|
|
8
|
+
export declare function unregisterBinding(reg: BindingRegistry, binding: Binding): void;
|
|
9
|
+
export declare function dispatchChanged(reg: BindingRegistry, changed: readonly number[], fire: (binding: Binding) => void): void;
|
|
10
|
+
//# sourceMappingURL=binding-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-registry.d.ts","sourceRoot":"","sources":["../src/binding-registry.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAC5C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC,CAAA;CAC5D;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CAKvD;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,IAAI,CAkBN;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAK9E;AAkBD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAC/B,IAAI,CAgBN"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Binding registry — Option B Phase 1.
|
|
2
|
+
//
|
|
3
|
+
// Replacement model for the Phase 2 flat-binding-array scan in
|
|
4
|
+
// `update-loop.ts`. Bindings register under the compile-time prefix-IDs
|
|
5
|
+
// they read (a list of positions in the host component's `__prefixes`
|
|
6
|
+
// table). On state change, the runtime walks `__prefixes` to identify
|
|
7
|
+
// changed prefix-IDs, then calls `dispatchChanged` to fire the union of
|
|
8
|
+
// subscribers — O(changed-prefixes) instead of O(total-bindings).
|
|
9
|
+
//
|
|
10
|
+
// Phase 1 is a standalone module: data structures + register/unregister/
|
|
11
|
+
// dispatch + unit tests. The runtime still uses the flat-array model;
|
|
12
|
+
// Phase 2 wires this in behind a per-component flag, Phase 3 makes it the
|
|
13
|
+
// only model. See `docs/proposals/v0.5-rebuild/option-b-hybrid-signals.md`.
|
|
14
|
+
//
|
|
15
|
+
// Data model:
|
|
16
|
+
// - `byPrefix: Map<prefixId, Set<Binding>>` — primary lookup. `Set`
|
|
17
|
+
// preserves insertion order (ES2015 spec), so dispatch fires in
|
|
18
|
+
// mount order without an extra array allocation.
|
|
19
|
+
// - `subscriptions: WeakMap<Binding, readonly prefixId[]>` — reverse
|
|
20
|
+
// index. Used by `unregisterBinding` to find which prefix-sets a
|
|
21
|
+
// binding belongs to in O(prefixIds.length) instead of scanning
|
|
22
|
+
// every set. Weak keying so a binding that's eligible for GC
|
|
23
|
+
// doesn't leak via this map.
|
|
24
|
+
//
|
|
25
|
+
// Dispatch dedup: a binding registered under multiple changed prefixes
|
|
26
|
+
// must fire exactly once per dispatch. We collect-then-iterate via a
|
|
27
|
+
// transient `Set<Binding>` rather than firing inside the prefix walk —
|
|
28
|
+
// the allocation cost is bounded by the number of subscribers actually
|
|
29
|
+
// matched, which is the same upper bound as the flat-array model's
|
|
30
|
+
// per-update binding count.
|
|
31
|
+
export function createBindingRegistry() {
|
|
32
|
+
return {
|
|
33
|
+
byPrefix: new Map(),
|
|
34
|
+
subscriptions: new WeakMap(),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function registerBinding(reg, binding, prefixIds) {
|
|
38
|
+
// If the binding was already registered, strip its existing entries
|
|
39
|
+
// first so the prefix-set membership reflects the new declaration.
|
|
40
|
+
// This supports re-registration after a binding's accessor changes
|
|
41
|
+
// (compile-time-uncommon but legal at runtime).
|
|
42
|
+
const existing = reg.subscriptions.get(binding);
|
|
43
|
+
if (existing)
|
|
44
|
+
removeFromPrefixSets(reg, binding, existing);
|
|
45
|
+
reg.subscriptions.set(binding, prefixIds);
|
|
46
|
+
for (let i = 0; i < prefixIds.length; i++) {
|
|
47
|
+
const id = prefixIds[i];
|
|
48
|
+
let set = reg.byPrefix.get(id);
|
|
49
|
+
if (!set) {
|
|
50
|
+
set = new Set();
|
|
51
|
+
reg.byPrefix.set(id, set);
|
|
52
|
+
}
|
|
53
|
+
set.add(binding);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function unregisterBinding(reg, binding) {
|
|
57
|
+
const prefixIds = reg.subscriptions.get(binding);
|
|
58
|
+
if (!prefixIds)
|
|
59
|
+
return; // not registered — idempotent no-op
|
|
60
|
+
removeFromPrefixSets(reg, binding, prefixIds);
|
|
61
|
+
reg.subscriptions.delete(binding);
|
|
62
|
+
}
|
|
63
|
+
function removeFromPrefixSets(reg, binding, prefixIds) {
|
|
64
|
+
for (let i = 0; i < prefixIds.length; i++) {
|
|
65
|
+
const id = prefixIds[i];
|
|
66
|
+
const set = reg.byPrefix.get(id);
|
|
67
|
+
if (!set)
|
|
68
|
+
continue;
|
|
69
|
+
set.delete(binding);
|
|
70
|
+
// Drop empty sets so iteration in dispatch doesn't visit dead
|
|
71
|
+
// entries and the map stays tight as components churn.
|
|
72
|
+
if (set.size === 0)
|
|
73
|
+
reg.byPrefix.delete(id);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function dispatchChanged(reg, changed, fire) {
|
|
77
|
+
if (changed.length === 0)
|
|
78
|
+
return;
|
|
79
|
+
// Collect-then-iterate so a binding registered under multiple changed
|
|
80
|
+
// prefixes fires exactly once. The set's insertion order is the
|
|
81
|
+
// order in which we encounter the binding via the FIRST changed
|
|
82
|
+
// prefix it matches — which preserves mount order when there's a
|
|
83
|
+
// single changed prefix (the common case), and is well-defined
|
|
84
|
+
// (V8/JSC) for the multi-prefix case.
|
|
85
|
+
const toFire = new Set();
|
|
86
|
+
for (let i = 0; i < changed.length; i++) {
|
|
87
|
+
const set = reg.byPrefix.get(changed[i]);
|
|
88
|
+
if (!set)
|
|
89
|
+
continue;
|
|
90
|
+
for (const binding of set)
|
|
91
|
+
toFire.add(binding);
|
|
92
|
+
}
|
|
93
|
+
for (const binding of toFire)
|
|
94
|
+
fire(binding);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=binding-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-registry.js","sourceRoot":"","sources":["../src/binding-registry.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,+DAA+D;AAC/D,wEAAwE;AACxE,sEAAsE;AACtE,sEAAsE;AACtE,wEAAwE;AACxE,kEAAkE;AAClE,EAAE;AACF,yEAAyE;AACzE,sEAAsE;AACtE,0EAA0E;AAC1E,4EAA4E;AAC5E,EAAE;AACF,cAAc;AACd,sEAAsE;AACtE,oEAAoE;AACpE,qDAAqD;AACrD,uEAAuE;AACvE,qEAAqE;AACrE,oEAAoE;AACpE,iEAAiE;AACjE,iCAAiC;AACjC,EAAE;AACF,uEAAuE;AACvE,qEAAqE;AACrE,uEAAuE;AACvE,uEAAuE;AACvE,mEAAmE;AACnE,4BAA4B;AAS5B,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,aAAa,EAAE,IAAI,OAAO,EAAE;KAC7B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,GAAoB,EACpB,OAAgB,EAChB,SAA4B;IAE5B,oEAAoE;IACpE,mEAAmE;IACnE,mEAAmE;IACnE,gDAAgD;IAChD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC/C,IAAI,QAAQ;QAAE,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IAE1D,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAE,CAAA;QACxB,IAAI,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;YACf,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QAC3B,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAoB,EAAE,OAAgB;IACtE,MAAM,SAAS,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAChD,IAAI,CAAC,SAAS;QAAE,OAAM,CAAC,oCAAoC;IAC3D,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;IAC7C,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;AACnC,CAAC;AAED,SAAS,oBAAoB,CAC3B,GAAoB,EACpB,OAAgB,EAChB,SAA4B;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAE,CAAA;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAChC,IAAI,CAAC,GAAG;YAAE,SAAQ;QAClB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACnB,8DAA8D;QAC9D,uDAAuD;QACvD,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,GAAoB,EACpB,OAA0B,EAC1B,IAAgC;IAEhC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAEhC,sEAAsE;IACtE,gEAAgE;IAChE,gEAAgE;IAChE,iEAAiE;IACjE,+DAA+D;IAC/D,sCAAsC;IACtC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAW,CAAA;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAA;QACzC,IAAI,CAAC,GAAG;YAAE,SAAQ;QAClB,KAAK,MAAM,OAAO,IAAI,GAAG;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAChD,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,MAAM;QAAE,IAAI,CAAC,OAAO,CAAC,CAAA;AAC7C,CAAC","sourcesContent":["// Binding registry — Option B Phase 1.\n//\n// Replacement model for the Phase 2 flat-binding-array scan in\n// `update-loop.ts`. Bindings register under the compile-time prefix-IDs\n// they read (a list of positions in the host component's `__prefixes`\n// table). On state change, the runtime walks `__prefixes` to identify\n// changed prefix-IDs, then calls `dispatchChanged` to fire the union of\n// subscribers — O(changed-prefixes) instead of O(total-bindings).\n//\n// Phase 1 is a standalone module: data structures + register/unregister/\n// dispatch + unit tests. The runtime still uses the flat-array model;\n// Phase 2 wires this in behind a per-component flag, Phase 3 makes it the\n// only model. See `docs/proposals/v0.5-rebuild/option-b-hybrid-signals.md`.\n//\n// Data model:\n// - `byPrefix: Map<prefixId, Set<Binding>>` — primary lookup. `Set`\n// preserves insertion order (ES2015 spec), so dispatch fires in\n// mount order without an extra array allocation.\n// - `subscriptions: WeakMap<Binding, readonly prefixId[]>` — reverse\n// index. Used by `unregisterBinding` to find which prefix-sets a\n// binding belongs to in O(prefixIds.length) instead of scanning\n// every set. Weak keying so a binding that's eligible for GC\n// doesn't leak via this map.\n//\n// Dispatch dedup: a binding registered under multiple changed prefixes\n// must fire exactly once per dispatch. We collect-then-iterate via a\n// transient `Set<Binding>` rather than firing inside the prefix walk —\n// the allocation cost is bounded by the number of subscribers actually\n// matched, which is the same upper bound as the flat-array model's\n// per-update binding count.\n\nimport type { Binding } from './types.js'\n\nexport interface BindingRegistry {\n readonly byPrefix: Map<number, Set<Binding>>\n readonly subscriptions: WeakMap<Binding, readonly number[]>\n}\n\nexport function createBindingRegistry(): BindingRegistry {\n return {\n byPrefix: new Map(),\n subscriptions: new WeakMap(),\n }\n}\n\nexport function registerBinding(\n reg: BindingRegistry,\n binding: Binding,\n prefixIds: readonly number[],\n): void {\n // If the binding was already registered, strip its existing entries\n // first so the prefix-set membership reflects the new declaration.\n // This supports re-registration after a binding's accessor changes\n // (compile-time-uncommon but legal at runtime).\n const existing = reg.subscriptions.get(binding)\n if (existing) removeFromPrefixSets(reg, binding, existing)\n\n reg.subscriptions.set(binding, prefixIds)\n for (let i = 0; i < prefixIds.length; i++) {\n const id = prefixIds[i]!\n let set = reg.byPrefix.get(id)\n if (!set) {\n set = new Set()\n reg.byPrefix.set(id, set)\n }\n set.add(binding)\n }\n}\n\nexport function unregisterBinding(reg: BindingRegistry, binding: Binding): void {\n const prefixIds = reg.subscriptions.get(binding)\n if (!prefixIds) return // not registered — idempotent no-op\n removeFromPrefixSets(reg, binding, prefixIds)\n reg.subscriptions.delete(binding)\n}\n\nfunction removeFromPrefixSets(\n reg: BindingRegistry,\n binding: Binding,\n prefixIds: readonly number[],\n): void {\n for (let i = 0; i < prefixIds.length; i++) {\n const id = prefixIds[i]!\n const set = reg.byPrefix.get(id)\n if (!set) continue\n set.delete(binding)\n // Drop empty sets so iteration in dispatch doesn't visit dead\n // entries and the map stays tight as components churn.\n if (set.size === 0) reg.byPrefix.delete(id)\n }\n}\n\nexport function dispatchChanged(\n reg: BindingRegistry,\n changed: readonly number[],\n fire: (binding: Binding) => void,\n): void {\n if (changed.length === 0) return\n\n // Collect-then-iterate so a binding registered under multiple changed\n // prefixes fires exactly once. The set's insertion order is the\n // order in which we encounter the binding via the FIRST changed\n // prefix it matches — which preserves mount order when there's a\n // single changed prefix (the common case), and is well-defined\n // (V8/JSC) for the multi-prefix case.\n const toFire = new Set<Binding>()\n for (let i = 0; i < changed.length; i++) {\n const set = reg.byPrefix.get(changed[i]!)\n if (!set) continue\n for (const binding of set) toFire.add(binding)\n }\n for (const binding of toFire) fire(binding)\n}\n"]}
|
package/dist/binding.d.ts
CHANGED
|
@@ -15,6 +15,28 @@ export interface CreateBindingOpts {
|
|
|
15
15
|
export declare function getFlatBindings(): Binding[] | null;
|
|
16
16
|
export declare function setFlatBindings(arr: Binding[] | null): void;
|
|
17
17
|
export declare function createBinding(scope: Lifetime, opts: CreateBindingOpts): Binding;
|
|
18
|
+
/**
|
|
19
|
+
* Bind a value of uncertain runtime type. Compiler-emitted call site
|
|
20
|
+
* when an element-helper prop value is an unresolvable identifier
|
|
21
|
+
* (function parameter, opaque import) — the compiler can't tell at
|
|
22
|
+
* build time whether the value will be a reactive accessor or a
|
|
23
|
+
* plain primitive, so it defers the dispatch here.
|
|
24
|
+
*
|
|
25
|
+
* If `value` is a function, register as a reactive binding with
|
|
26
|
+
* FULL_MASK gating (the compiler couldn't analyze accessor deps).
|
|
27
|
+
* Otherwise apply it directly as a one-shot prop/attr/class/style set.
|
|
28
|
+
*
|
|
29
|
+
* v0.4 size-cut: this exists to keep `createElement` (the heavyweight
|
|
30
|
+
* runtime fallback in `elements.ts`) from being pulled in by uncertain
|
|
31
|
+
* prop sites. ~1.8 kB minified saved per affected app.
|
|
32
|
+
*
|
|
33
|
+
* Compiler-emit target only — user code should not call this directly.
|
|
34
|
+
* (The runtime is re-exported through index.ts. We deliberately don't
|
|
35
|
+
* mark this as private/internal in the JSDoc because the corresponding
|
|
36
|
+
* stripping setting in tsconfig.build.json would then produce a
|
|
37
|
+
* dangling re-export pointing at a missing member.)
|
|
38
|
+
*/
|
|
39
|
+
export declare function __bindUncertain(el: Node, kind: BindingKind, key: string | undefined, value: unknown): void;
|
|
18
40
|
export declare function applyBinding(target: {
|
|
19
41
|
kind: BindingKind;
|
|
20
42
|
node: Node;
|
package/dist/binding.d.ts.map
CHANGED
|
@@ -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;
|
|
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;AAKhE,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;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,IAAI,EACR,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,KAAK,EAAE,OAAO,GACb,IAAI,CAmBN;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,CAsEN"}
|
package/dist/binding.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { addBinding } from './lifetime.js';
|
|
2
|
+
import { getRenderContext } from './render-context.js';
|
|
3
|
+
import { FULL_MASK } from './update-loop.js';
|
|
2
4
|
let flatBindings = null;
|
|
3
5
|
export function getFlatBindings() {
|
|
4
6
|
return flatBindings;
|
|
@@ -24,6 +26,48 @@ export function createBinding(scope, opts) {
|
|
|
24
26
|
flatBindings.push(binding);
|
|
25
27
|
return binding;
|
|
26
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Bind a value of uncertain runtime type. Compiler-emitted call site
|
|
31
|
+
* when an element-helper prop value is an unresolvable identifier
|
|
32
|
+
* (function parameter, opaque import) — the compiler can't tell at
|
|
33
|
+
* build time whether the value will be a reactive accessor or a
|
|
34
|
+
* plain primitive, so it defers the dispatch here.
|
|
35
|
+
*
|
|
36
|
+
* If `value` is a function, register as a reactive binding with
|
|
37
|
+
* FULL_MASK gating (the compiler couldn't analyze accessor deps).
|
|
38
|
+
* Otherwise apply it directly as a one-shot prop/attr/class/style set.
|
|
39
|
+
*
|
|
40
|
+
* v0.4 size-cut: this exists to keep `createElement` (the heavyweight
|
|
41
|
+
* runtime fallback in `elements.ts`) from being pulled in by uncertain
|
|
42
|
+
* prop sites. ~1.8 kB minified saved per affected app.
|
|
43
|
+
*
|
|
44
|
+
* Compiler-emit target only — user code should not call this directly.
|
|
45
|
+
* (The runtime is re-exported through index.ts. We deliberately don't
|
|
46
|
+
* mark this as private/internal in the JSDoc because the corresponding
|
|
47
|
+
* stripping setting in tsconfig.build.json would then produce a
|
|
48
|
+
* dangling re-export pointing at a missing member.)
|
|
49
|
+
*/
|
|
50
|
+
export function __bindUncertain(el, kind, key, value) {
|
|
51
|
+
if (typeof value === 'function') {
|
|
52
|
+
const ctx = getRenderContext();
|
|
53
|
+
const fn = value;
|
|
54
|
+
const perItem = fn.length === 0;
|
|
55
|
+
const binding = createBinding(ctx.rootLifetime, {
|
|
56
|
+
mask: FULL_MASK,
|
|
57
|
+
accessor: fn,
|
|
58
|
+
kind,
|
|
59
|
+
node: el,
|
|
60
|
+
key,
|
|
61
|
+
perItem,
|
|
62
|
+
});
|
|
63
|
+
const initial = perItem ? fn() : fn(ctx.state);
|
|
64
|
+
binding.lastValue = initial;
|
|
65
|
+
applyBinding({ kind, node: el, key }, initial);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
applyBinding({ kind, node: el, key }, value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
27
71
|
export function applyBinding(target, value) {
|
|
28
72
|
// Defensive guard: if a reactive accessor leaks through as a raw
|
|
29
73
|
// function value, emitting its `.toString()` into the DOM (e.g. as
|
|
@@ -33,11 +77,18 @@ export function applyBinding(target, value) {
|
|
|
33
77
|
// are registered via addEventListener in the element helpers, not
|
|
34
78
|
// via applyBinding.
|
|
35
79
|
if (typeof value === 'function') {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
80
|
+
// Dev-only: surface the offending accessor source + key + kind so
|
|
81
|
+
// the bug is obvious. Production builds throw a brief variant —
|
|
82
|
+
// this guard is a defensive check against compiler bugs / corrupt
|
|
83
|
+
// tuples; app code that hits it has already crashed.
|
|
84
|
+
if (import.meta.env?.DEV) {
|
|
85
|
+
throw new TypeError(`[LLui] applyBinding(${target.kind}${target.key ? `, '${target.key}'` : ''}) received ` +
|
|
86
|
+
`a function as its value. This means an accessor wasn't invoked before ` +
|
|
87
|
+
`reaching the binding layer — usually a bug in a compiled binding tuple or ` +
|
|
88
|
+
`in a helper that forwards props without calling them. The arrow's source ` +
|
|
89
|
+
`would have been serialized into the DOM otherwise. Offender: ${value.toString().slice(0, 120)}`);
|
|
90
|
+
}
|
|
91
|
+
throw new TypeError(`[LLui] applyBinding(${target.kind}) received a function value`);
|
|
41
92
|
}
|
|
42
93
|
switch (target.kind) {
|
|
43
94
|
case 'effect':
|
package/dist/binding.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;
|
|
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'\nimport { getRenderContext } from './render-context.js'\nimport { FULL_MASK } from './update-loop.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\n/**\n * Bind a value of uncertain runtime type. Compiler-emitted call site\n * when an element-helper prop value is an unresolvable identifier\n * (function parameter, opaque import) — the compiler can't tell at\n * build time whether the value will be a reactive accessor or a\n * plain primitive, so it defers the dispatch here.\n *\n * If `value` is a function, register as a reactive binding with\n * FULL_MASK gating (the compiler couldn't analyze accessor deps).\n * Otherwise apply it directly as a one-shot prop/attr/class/style set.\n *\n * v0.4 size-cut: this exists to keep `createElement` (the heavyweight\n * runtime fallback in `elements.ts`) from being pulled in by uncertain\n * prop sites. ~1.8 kB minified saved per affected app.\n *\n * Compiler-emit target only — user code should not call this directly.\n * (The runtime is re-exported through index.ts. We deliberately don't\n * mark this as private/internal in the JSDoc because the corresponding\n * stripping setting in tsconfig.build.json would then produce a\n * dangling re-export pointing at a missing member.)\n */\nexport function __bindUncertain(\n el: Node,\n kind: BindingKind,\n key: string | undefined,\n value: unknown,\n): void {\n if (typeof value === 'function') {\n const ctx = getRenderContext()\n const fn = value as (s: never) => unknown\n const perItem = fn.length === 0\n const binding = createBinding(ctx.rootLifetime, {\n mask: FULL_MASK,\n accessor: fn,\n kind,\n node: el,\n key,\n perItem,\n })\n const initial = perItem ? (fn as unknown as () => unknown)() : fn(ctx.state as never)\n binding.lastValue = initial\n applyBinding({ kind, node: el, key }, initial)\n } else {\n applyBinding({ kind, node: el, key }, value)\n }\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 // Dev-only: surface the offending accessor source + key + kind so\n // the bug is obvious. Production builds throw a brief variant —\n // this guard is a defensive check against compiler bugs / corrupt\n // tuples; app code that hits it has already crashed.\n if (import.meta.env?.DEV) {\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 throw new TypeError(`[LLui] applyBinding(${target.kind}) received a function value`)\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,25 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
/**
|
|
3
|
+
* True when the host adapter (vite-plugin) enables the agent
|
|
4
|
+
* surface. Gates the binding-descriptors registry and related
|
|
5
|
+
* agent-only runtime so non-agent consumers don't ship the code.
|
|
6
|
+
*
|
|
7
|
+
* @see packages/vite-plugin/src/index.ts — sets this via Vite `define`.
|
|
8
|
+
* @see packages/dom/src/binding-descriptors.ts — agent-only module
|
|
9
|
+
* that becomes unreachable when this flag is false.
|
|
10
|
+
*/
|
|
11
|
+
const __LLUI_AGENT__: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* True when any component in the host app uses `each()`'s `enter` /
|
|
14
|
+
* `leave` / `onTransition` options. Gates the per-entry enter/leave
|
|
15
|
+
* helpers in `each.ts` (`removeEntry`, `fireEnter`) and the per-cycle
|
|
16
|
+
* `report` / `leaving` queue. Apps without animations drop ~0.3 kB
|
|
17
|
+
* gz; apps that need them pass `transitions: true` to the vite plugin.
|
|
18
|
+
*
|
|
19
|
+
* @see packages/vite-plugin/src/index.ts — sets this via Vite `define`.
|
|
20
|
+
* @see packages/dom/src/primitives/each.ts — gated branches.
|
|
21
|
+
*/
|
|
22
|
+
const __LLUI_TRANSITIONS__: boolean;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=build-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-flags.d.ts","sourceRoot":"","sources":["../src/build-flags.ts"],"names":[],"mappings":"AAaA,OAAO,CAAC,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,MAAM,cAAc,EAAE,OAAO,CAAA;IAC7B;;;;;;;;;OASG;IACH,MAAM,oBAAoB,EAAE,OAAO,CAAA;CACpC;AAMD,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Build-time feature flags consumed by the runtime.
|
|
2
|
+
//
|
|
3
|
+
// `@llui/vite-plugin`'s `define` config substitutes these literals at
|
|
4
|
+
// build time. When a flag is set to `false`, the bundler's dead-code
|
|
5
|
+
// eliminator drops every `if (FLAG)` branch — and any module that's
|
|
6
|
+
// only reachable through those branches tree-shakes out entirely.
|
|
7
|
+
//
|
|
8
|
+
// Consumers that don't go through `@llui/vite-plugin` (raw tsc/vitest,
|
|
9
|
+
// other bundlers without a `define` for these) see the flags as
|
|
10
|
+
// undefined at runtime — JavaScript `if (undefined)` is falsy, so the
|
|
11
|
+
// gated agent path simply stays off. This matches the safe default
|
|
12
|
+
// (no agent runtime active).
|
|
13
|
+
// `globalThis` fallback for environments that don't process the
|
|
14
|
+
// `define` substitution (raw tsc test runs, third-party tooling).
|
|
15
|
+
// The runtime check is `typeof __LLUI_AGENT__ !== 'undefined' && __LLUI_AGENT__`.
|
|
16
|
+
// Exporting nothing — this is a declaration-only module.
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=build-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-flags.js","sourceRoot":"","sources":["../src/build-flags.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,sEAAsE;AACtE,qEAAqE;AACrE,oEAAoE;AACpE,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,sEAAsE;AACtE,mEAAmE;AACnE,6BAA6B;AA0B7B,gEAAgE;AAChE,kEAAkE;AAClE,kFAAkF;AAClF,yDAAyD;AACzD,OAAO,EAAE,CAAA","sourcesContent":["// Build-time feature flags consumed by the runtime.\n//\n// `@llui/vite-plugin`'s `define` config substitutes these literals at\n// build time. When a flag is set to `false`, the bundler's dead-code\n// eliminator drops every `if (FLAG)` branch — and any module that's\n// only reachable through those branches tree-shakes out entirely.\n//\n// Consumers that don't go through `@llui/vite-plugin` (raw tsc/vitest,\n// other bundlers without a `define` for these) see the flags as\n// undefined at runtime — JavaScript `if (undefined)` is falsy, so the\n// gated agent path simply stays off. This matches the safe default\n// (no agent runtime active).\n\ndeclare global {\n /**\n * True when the host adapter (vite-plugin) enables the agent\n * surface. Gates the binding-descriptors registry and related\n * agent-only runtime so non-agent consumers don't ship the code.\n *\n * @see packages/vite-plugin/src/index.ts — sets this via Vite `define`.\n * @see packages/dom/src/binding-descriptors.ts — agent-only module\n * that becomes unreachable when this flag is false.\n */\n const __LLUI_AGENT__: boolean\n /**\n * True when any component in the host app uses `each()`'s `enter` /\n * `leave` / `onTransition` options. Gates the per-entry enter/leave\n * helpers in `each.ts` (`removeEntry`, `fireEnter`) and the per-cycle\n * `report` / `leaving` queue. Apps without animations drop ~0.3 kB\n * gz; apps that need them pass `transitions: true` to the vite plugin.\n *\n * @see packages/vite-plugin/src/index.ts — sets this via Vite `define`.\n * @see packages/dom/src/primitives/each.ts — gated branches.\n */\n const __LLUI_TRANSITIONS__: boolean\n}\n\n// `globalThis` fallback for environments that don't process the\n// `define` substitution (raw tsc test runs, third-party tooling).\n// The runtime check is `typeof __LLUI_AGENT__ !== 'undefined' && __LLUI_AGENT__`.\n// Exporting nothing — this is a declaration-only module.\nexport {}\n"]}
|
package/dist/compose.d.ts
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Type-level utilities + runtime helper for composing multiple
|
|
3
|
-
*
|
|
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
|
-
*
|
|
7
|
-
* `
|
|
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 {
|
|
11
|
-
* import {
|
|
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
|
|
15
|
+
* const modules = { dialog, sort: sortable } as const
|
|
16
16
|
*
|
|
17
|
-
* type State =
|
|
18
|
-
* type Msg =
|
|
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
|
-
*
|
|
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
|
|
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
|
|
45
|
-
* type
|
|
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
|
|
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
|
|
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
|
|
58
|
-
* type
|
|
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
|
|
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
|
|
71
|
-
*
|
|
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
|
|
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
|
package/dist/compose.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA
|
|
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
|
|
3
|
-
*
|
|
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
|
-
*
|
|
7
|
-
* `
|
|
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 {
|
|
11
|
-
* import {
|
|
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
|
|
15
|
+
* const modules = { dialog, sort: sortable } as const
|
|
16
16
|
*
|
|
17
|
-
* type State =
|
|
18
|
-
* type Msg =
|
|
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
|
-
*
|
|
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
|
|
29
|
-
*
|
|
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
|
|
39
|
+
export function composeModules(modules) {
|
|
34
40
|
const keys = Object.keys(modules);
|
|
35
41
|
return (state, msg) => {
|
|
36
42
|
const m = msg;
|
package/dist/compose.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA
|
|
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"]}
|
package/dist/el-split.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"el-split.d.ts","sourceRoot":"","sources":["../src/el-split.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAM7C,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,EAC5C,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,IAAI,EAO7C,QAAQ,EAAE,KAAK,CACX,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GACxD,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,EAAE,MAAM,CAAC,CACnE,GAAG,IAAI,EAMR,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,GAC3D,WAAW,
|
|
1
|
+
{"version":3,"file":"el-split.d.ts","sourceRoot":"","sources":["../src/el-split.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAM7C,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,EAC5C,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,IAAI,EAO7C,QAAQ,EAAE,KAAK,CACX,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GACxD,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,EAAE,MAAM,CAAC,CACnE,GAAG,IAAI,EAMR,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,GAC3D,WAAW,CA+Fb"}
|
package/dist/el-split.js
CHANGED
|
@@ -29,10 +29,14 @@ children) {
|
|
|
29
29
|
// `send({type:'X'})` calls with `Object.assign(arrow,
|
|
30
30
|
// {__lluiVariants: ['X', …]})`. Register those so the agent
|
|
31
31
|
// layer's `list_actions` reflects the live UI affordances.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
|
|
32
|
+
// Agent-only — gated by `__LLUI_AGENT__`. See elements.ts for
|
|
33
|
+
// the same pattern + rationale.
|
|
34
|
+
if (typeof __LLUI_AGENT__ !== 'undefined' && __LLUI_AGENT__) {
|
|
35
|
+
const variants = handler
|
|
36
|
+
?.__lluiVariants;
|
|
37
|
+
if (variants && variants.length > 0 && ctx.instance) {
|
|
38
|
+
registerBindingVariants(ctx.instance, ctx.rootLifetime, variants);
|
|
39
|
+
}
|
|
36
40
|
}
|
|
37
41
|
el.addEventListener(eventName, handler);
|
|
38
42
|
}
|
package/dist/el-split.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"el-split.js","sourceRoot":"","sources":["../src/el-split.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAElE,MAAM,UAAU,OAAO,CACrB,GAAW,EACX,QAA4C,EAC5C,MAA6C;AAC7C,mEAAmE;AACnE,gEAAgE;AAChE,oEAAoE;AACpE,oEAAoE;AACpE,+DAA+D;AAC/D,iEAAiE;AACjE,QAGQ;AACR,mEAAmE;AACnE,qEAAqE;AACrE,sEAAsE;AACtE,uEAAuE;AACvE,oCAAoC;AACpC,QAA4D;IAE5D,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAA;IAC9B,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAgB,CAAA;IAEpD,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,EAAE,CAAC,CAAA;IACd,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,MAAM,EAAE,CAAC;YAC1C,sDAAsD;YACtD,2DAA2D;YAC3D,uDAAuD;YACvD,sDAAsD;YACtD,4DAA4D;YAC5D,2DAA2D;YAC3D,MAAM,QAAQ,GAAI,OAAqE;
|
|
1
|
+
{"version":3,"file":"el-split.js","sourceRoot":"","sources":["../src/el-split.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BindingKind } from './types.js'\nimport { getRenderContext } from './render-context.js'\nimport { createBinding, applyBinding } from './binding.js'\nimport { addCheckedItemUpdater } from './lifetime.js'\nimport { registerBindingVariants } from './binding-descriptors.js'\n\nexport function elSplit(\n tag: string,\n staticFn: ((el: HTMLElement) => void) | null,\n events: Array<[string, EventListener]> | null,\n // Bindings are 4-tuples for low-word-only access (the common case)\n // or 5-tuples when the binding's accessor reads a prefix at bit\n // position 31..61, in which case the 5th slot carries the high-word\n // mask. Stale compiled bundles emit only 4-tuples; new bundles emit\n // the 5th slot when (and only when) needed, so the on-the-wire\n // representation stays byte-identical for ≤31-prefix components.\n bindings: Array<\n | [number, BindingKind, string, (state: never) => unknown]\n | [number, BindingKind, string, (state: never) => unknown, number]\n > | null,\n // Accepts raw strings too (wrapped in Text nodes at append time so\n // user code like `button([], ['Sign in'])` works without an explicit\n // text() wrapper) and nested arrays (flattened one level to match the\n // raw createElement path — supports patterns like `main([pageSlot()])`\n // where pageSlot() returns Node[]).\n children: Array<Node | string | Array<Node | string>> | null,\n): HTMLElement {\n const ctx = getRenderContext()\n const el = ctx.dom.createElement(tag) as HTMLElement\n\n if (staticFn) {\n staticFn(el)\n }\n\n if (events) {\n for (const [eventName, handler] of events) {\n // Compiler-tagged variants — same protocol as the raw\n // `createElement` path in `elements.ts`. The vite-plugin's\n // tagger wraps event-handler arrows containing literal\n // `send({type:'X'})` calls with `Object.assign(arrow,\n // {__lluiVariants: ['X', …]})`. Register those so the agent\n // layer's `list_actions` reflects the live UI affordances.\n // Agent-only — gated by `__LLUI_AGENT__`. See elements.ts for\n // the same pattern + rationale.\n if (typeof __LLUI_AGENT__ !== 'undefined' && __LLUI_AGENT__) {\n const variants = (handler as { __lluiVariants?: readonly string[] } | null | undefined)\n ?.__lluiVariants\n if (variants && variants.length > 0 && ctx.instance) {\n registerBindingVariants(ctx.instance, ctx.rootLifetime, variants)\n }\n }\n el.addEventListener(eventName, handler)\n }\n }\n\n if (bindings) {\n for (const b of bindings) {\n const mask = b[0]\n const kind = b[1]\n const key = b[2]\n const accessor = b[3]\n // Tuple length 5 carries a high-word mask in slot 4 (when the\n // accessor reads a path at bit position 31..61). Length 4 stays\n // pure low-word — covers both ≤31-prefix components and\n // 32..61-prefix components whose individual bindings only touch\n // low-word paths.\n const maskHi = b.length === 5 ? (b[4] as number) : 0\n const perItem = accessor.length === 0\n if (perItem) {\n const get = accessor as unknown as () => unknown\n const target = { kind, node: el, key }\n const initial = addCheckedItemUpdater(ctx.rootLifetime, get, (v) => applyBinding(target, v))\n applyBinding(target, initial)\n } else {\n const binding = createBinding(ctx.rootLifetime, {\n mask,\n maskHi,\n accessor,\n kind,\n node: el,\n key,\n perItem: false,\n })\n const initialValue = accessor(ctx.state as never)\n binding.lastValue = initialValue\n applyBinding({ kind, node: el, key }, initialValue)\n }\n }\n }\n\n if (children) {\n for (const child of children) {\n // Strings get wrapped in Text nodes — matches createElement's\n // behavior in elements.ts. Without this, user code that passes\n // raw strings as children (e.g. `button([], ['Sign in'])`) crashes\n // in jsdom with \"parameter 1 is not of type 'Node'\" during SSR\n // and throws a TypeError in strict browsers.\n if (typeof child === 'string') {\n el.appendChild(ctx.dom.createTextNode(child))\n } else if (Array.isArray(child)) {\n // Arrays-in-children are flattened one level. This matches\n // the raw createElement path in elements.ts and makes patterns\n // like `main([pageSlot()])` (where pageSlot() returns Node[])\n // work consistently between raw and compiled call paths.\n // Without this flattening, tests run via vitest pass (raw path\n // flattens) but SSR via the compiler transform crashes with\n // \"appendChild parameter is not of type Node\".\n for (const node of child) {\n if (typeof node === 'string') {\n el.appendChild(ctx.dom.createTextNode(node))\n } else {\n el.appendChild(node)\n }\n }\n } else {\n el.appendChild(child)\n }\n }\n }\n\n return el\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"el-template.d.ts","sourceRoot":"","sources":["../src/el-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAmB1C;;;;;;6BAM6B;AAC7B,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,OAAO,EAC/B,MAAM,CAAC,EAAE,MAAM,KACZ,IAAI,CAAA;AAET;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,GAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"el-template.d.ts","sourceRoot":"","sources":["../src/el-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAmB1C;;;;;;6BAM6B;AAC7B,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,OAAO,EAC/B,MAAM,CAAC,EAAE,MAAM,KACZ,IAAI,CAAA;AAET;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,GAC9D,OAAO,CAqCT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CASxD"}
|