@llui/dom 0.0.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/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/addressed.d.ts +16 -0
- package/dist/addressed.d.ts.map +1 -0
- package/dist/addressed.js +40 -0
- package/dist/addressed.js.map +1 -0
- package/dist/binding.d.ts +18 -0
- package/dist/binding.d.ts.map +1 -0
- package/dist/binding.js +62 -0
- package/dist/binding.js.map +1 -0
- package/dist/chain-update.d.ts +7 -0
- package/dist/chain-update.d.ts.map +1 -0
- package/dist/chain-update.js +16 -0
- package/dist/chain-update.js.map +1 -0
- package/dist/component.d.ts +3 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +4 -0
- package/dist/component.js.map +1 -0
- package/dist/devtools.d.ts +113 -0
- package/dist/devtools.d.ts.map +1 -0
- package/dist/devtools.js +390 -0
- package/dist/devtools.js.map +1 -0
- package/dist/el-split.d.ts +3 -0
- package/dist/el-split.d.ts.map +1 -0
- package/dist/el-split.js +54 -0
- package/dist/el-split.js.map +1 -0
- package/dist/el-template.d.ts +17 -0
- package/dist/el-template.d.ts.map +1 -0
- package/dist/el-template.js +64 -0
- package/dist/el-template.js.map +1 -0
- package/dist/elements.d.ts +80 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +234 -0
- package/dist/elements.js.map +1 -0
- package/dist/form.d.ts +30 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +12 -0
- package/dist/form.js.map +1 -0
- package/dist/hmr.d.ts +20 -0
- package/dist/hmr.d.ts.map +1 -0
- package/dist/hmr.js +98 -0
- package/dist/hmr.js.map +1 -0
- package/dist/hydrate.d.ts +29 -0
- package/dist/hydrate.d.ts.map +1 -0
- package/dist/hydrate.js +96 -0
- package/dist/hydrate.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/merge-handlers.d.ts +7 -0
- package/dist/merge-handlers.d.ts.map +1 -0
- package/dist/merge-handlers.js +16 -0
- package/dist/merge-handlers.js.map +1 -0
- package/dist/mount.d.ts +14 -0
- package/dist/mount.d.ts.map +1 -0
- package/dist/mount.js +182 -0
- package/dist/mount.js.map +1 -0
- package/dist/primitives/branch.d.ts +3 -0
- package/dist/primitives/branch.d.ts.map +1 -0
- package/dist/primitives/branch.js +94 -0
- package/dist/primitives/branch.js.map +1 -0
- package/dist/primitives/child.d.ts +3 -0
- package/dist/primitives/child.d.ts.map +1 -0
- package/dist/primitives/child.js +77 -0
- package/dist/primitives/child.js.map +1 -0
- package/dist/primitives/context.d.ts +45 -0
- package/dist/primitives/context.d.ts.map +1 -0
- package/dist/primitives/context.js +87 -0
- package/dist/primitives/context.js.map +1 -0
- package/dist/primitives/each.d.ts +3 -0
- package/dist/primitives/each.d.ts.map +1 -0
- package/dist/primitives/each.js +515 -0
- package/dist/primitives/each.js.map +1 -0
- package/dist/primitives/error-boundary.d.ts +6 -0
- package/dist/primitives/error-boundary.d.ts.map +1 -0
- package/dist/primitives/error-boundary.js +32 -0
- package/dist/primitives/error-boundary.js.map +1 -0
- package/dist/primitives/foreign.d.ts +3 -0
- package/dist/primitives/foreign.d.ts.map +1 -0
- package/dist/primitives/foreign.js +80 -0
- package/dist/primitives/foreign.js.map +1 -0
- package/dist/primitives/memo.d.ts +3 -0
- package/dist/primitives/memo.d.ts.map +1 -0
- package/dist/primitives/memo.js +30 -0
- package/dist/primitives/memo.js.map +1 -0
- package/dist/primitives/on-mount.d.ts +2 -0
- package/dist/primitives/on-mount.d.ts.map +1 -0
- package/dist/primitives/on-mount.js +23 -0
- package/dist/primitives/on-mount.js.map +1 -0
- package/dist/primitives/portal.d.ts +3 -0
- package/dist/primitives/portal.d.ts.map +1 -0
- package/dist/primitives/portal.js +31 -0
- package/dist/primitives/portal.js.map +1 -0
- package/dist/primitives/selector.d.ts +22 -0
- package/dist/primitives/selector.d.ts.map +1 -0
- package/dist/primitives/selector.js +104 -0
- package/dist/primitives/selector.js.map +1 -0
- package/dist/primitives/show.d.ts +3 -0
- package/dist/primitives/show.d.ts.map +1 -0
- package/dist/primitives/show.js +12 -0
- package/dist/primitives/show.js.map +1 -0
- package/dist/primitives/slice.d.ts +23 -0
- package/dist/primitives/slice.d.ts.map +1 -0
- package/dist/primitives/slice.js +57 -0
- package/dist/primitives/slice.js.map +1 -0
- package/dist/primitives/text.d.ts +2 -0
- package/dist/primitives/text.d.ts.map +1 -0
- package/dist/primitives/text.js +35 -0
- package/dist/primitives/text.js.map +1 -0
- package/dist/render-context.d.ts +14 -0
- package/dist/render-context.d.ts.map +1 -0
- package/dist/render-context.js +14 -0
- package/dist/render-context.js.map +1 -0
- package/dist/runtime.d.ts +4 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +14 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scope.d.ts +24 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +102 -0
- package/dist/scope.js.map +1 -0
- package/dist/slice-handler.d.ts +31 -0
- package/dist/slice-handler.d.ts.map +1 -0
- package/dist/slice-handler.js +34 -0
- package/dist/slice-handler.js.map +1 -0
- package/dist/ssr-dom.d.ts +12 -0
- package/dist/ssr-dom.d.ts.map +1 -0
- package/dist/ssr-dom.js +36 -0
- package/dist/ssr-dom.js.map +1 -0
- package/dist/ssr.d.ts +11 -0
- package/dist/ssr.d.ts.map +1 -0
- package/dist/ssr.js +127 -0
- package/dist/ssr.js.map +1 -0
- package/dist/structural.d.ts +4 -0
- package/dist/structural.d.ts.map +1 -0
- package/dist/structural.js +2 -0
- package/dist/structural.js.map +1 -0
- package/dist/types.d.ts +145 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/update-loop.d.ts +31 -0
- package/dist/update-loop.d.ts.map +1 -0
- package/dist/update-loop.js +236 -0
- package/dist/update-loop.js.map +1 -0
- package/dist/view-helpers.d.ts +44 -0
- package/dist/view-helpers.d.ts.map +1 -0
- package/dist/view-helpers.js +24 -0
- package/dist/view-helpers.js.map +1 -0
- package/package.json +56 -0
package/dist/scope.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
let nextId = 1;
|
|
2
|
+
// Shared empty arrays — avoid allocating per scope when unused
|
|
3
|
+
const EMPTY_SCOPES = [];
|
|
4
|
+
const EMPTY_DISPOSERS = [];
|
|
5
|
+
const EMPTY_BINDINGS = [];
|
|
6
|
+
const EMPTY_UPDATERS = [];
|
|
7
|
+
export function createScope(parent) {
|
|
8
|
+
const scope = {
|
|
9
|
+
id: nextId++,
|
|
10
|
+
parent,
|
|
11
|
+
children: EMPTY_SCOPES,
|
|
12
|
+
disposers: EMPTY_DISPOSERS,
|
|
13
|
+
bindings: EMPTY_BINDINGS,
|
|
14
|
+
eachItemStable: false,
|
|
15
|
+
itemUpdaters: EMPTY_UPDATERS,
|
|
16
|
+
};
|
|
17
|
+
if (parent) {
|
|
18
|
+
if (parent.children === EMPTY_SCOPES)
|
|
19
|
+
parent.children = [];
|
|
20
|
+
parent.children.push(scope);
|
|
21
|
+
}
|
|
22
|
+
return scope;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Dispose a scope and all its children. By default, detaches the scope
|
|
26
|
+
* from its parent's `children` array via `indexOf + splice` — O(N) per
|
|
27
|
+
* call, which becomes O(N²) when disposing many sibling scopes in bulk
|
|
28
|
+
* (e.g. `each` clearing 1000 rows).
|
|
29
|
+
*
|
|
30
|
+
* Pass `skipParentRemoval = true` when the caller will batch-remove
|
|
31
|
+
* children afterwards (see `removeOrphanedFromParent`). The scope's
|
|
32
|
+
* `parent` pointer is still set to `null` so the caller can identify
|
|
33
|
+
* orphaned entries.
|
|
34
|
+
*/
|
|
35
|
+
export function disposeScope(scope, skipParentRemoval = false) {
|
|
36
|
+
if (scope.disposers.length === 0 && scope.children.length === 0 && scope.bindings.length === 0) {
|
|
37
|
+
if (!skipParentRemoval)
|
|
38
|
+
removeFromParent(scope);
|
|
39
|
+
scope.parent = null;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const children = scope.children.slice();
|
|
43
|
+
for (const child of children) {
|
|
44
|
+
disposeScope(child);
|
|
45
|
+
}
|
|
46
|
+
for (const disposer of scope.disposers) {
|
|
47
|
+
disposer();
|
|
48
|
+
}
|
|
49
|
+
// Mark bindings as dead and break closure/DOM retention
|
|
50
|
+
for (const binding of scope.bindings) {
|
|
51
|
+
binding.dead = true;
|
|
52
|
+
binding.accessor = null;
|
|
53
|
+
binding.node = null;
|
|
54
|
+
binding.lastValue = undefined;
|
|
55
|
+
}
|
|
56
|
+
scope.disposers.length = 0;
|
|
57
|
+
scope.bindings.length = 0;
|
|
58
|
+
scope.children.length = 0;
|
|
59
|
+
scope.itemUpdaters.length = 0;
|
|
60
|
+
if (!skipParentRemoval)
|
|
61
|
+
removeFromParent(scope);
|
|
62
|
+
scope.parent = null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Batch-remove children with `parent === null` from `parent.children`.
|
|
66
|
+
* Called after a bulk `disposeScope(child, true)` pass to collapse the
|
|
67
|
+
* individual O(N) splice operations into one O(N) scan.
|
|
68
|
+
*/
|
|
69
|
+
export function removeOrphanedChildren(parent) {
|
|
70
|
+
const children = parent.children;
|
|
71
|
+
let w = 0;
|
|
72
|
+
for (let r = 0; r < children.length; r++) {
|
|
73
|
+
if (children[r].parent !== null)
|
|
74
|
+
children[w++] = children[r];
|
|
75
|
+
}
|
|
76
|
+
children.length = w;
|
|
77
|
+
}
|
|
78
|
+
export function addBinding(scope, binding) {
|
|
79
|
+
binding.ownerScope = scope;
|
|
80
|
+
if (scope.bindings === EMPTY_BINDINGS)
|
|
81
|
+
scope.bindings = [];
|
|
82
|
+
scope.bindings.push(binding);
|
|
83
|
+
}
|
|
84
|
+
export function addItemUpdater(scope, updater) {
|
|
85
|
+
if (scope.itemUpdaters === EMPTY_UPDATERS)
|
|
86
|
+
scope.itemUpdaters = [];
|
|
87
|
+
scope.itemUpdaters.push(updater);
|
|
88
|
+
}
|
|
89
|
+
export function addDisposer(scope, disposer) {
|
|
90
|
+
if (scope.disposers === EMPTY_DISPOSERS)
|
|
91
|
+
scope.disposers = [];
|
|
92
|
+
scope.disposers.push(disposer);
|
|
93
|
+
}
|
|
94
|
+
function removeFromParent(scope) {
|
|
95
|
+
if (scope.parent) {
|
|
96
|
+
const idx = scope.parent.children.indexOf(scope);
|
|
97
|
+
if (idx !== -1) {
|
|
98
|
+
scope.parent.children.splice(idx, 1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lens-style adapter that lifts a sub-component's `update` into a handler that
|
|
3
|
+
* operates on a parent's full state and message type. Pairs with
|
|
4
|
+
* `mergeHandlers` to compose sub-components into a parent component's reducer.
|
|
5
|
+
*
|
|
6
|
+
* - `get` / `set` isolate the sub-component's state slice within the parent state.
|
|
7
|
+
* - `narrow` takes the parent message and returns the sub-message if this slice
|
|
8
|
+
* handles it, or `null` to pass through.
|
|
9
|
+
* - `sub` is the sub-component's pure reducer (operates on its own state + msg).
|
|
10
|
+
*
|
|
11
|
+
* Example — embedding `dialog.update` into a parent reducer:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* const update = mergeHandlers<State, Msg, Effect>(
|
|
15
|
+
* sliceHandler({
|
|
16
|
+
* get: (s) => s.confirm,
|
|
17
|
+
* set: (s, v) => ({ ...s, confirm: v }),
|
|
18
|
+
* narrow: (m) => m.type === 'confirm' ? m.msg : null,
|
|
19
|
+
* sub: dialog.update,
|
|
20
|
+
* }),
|
|
21
|
+
* appUpdate,
|
|
22
|
+
* )
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function sliceHandler<S, M, E, SubS, SubM>(opts: {
|
|
26
|
+
get: (state: S) => SubS;
|
|
27
|
+
set: (state: S, slice: SubS) => S;
|
|
28
|
+
narrow: (msg: M) => SubM | null;
|
|
29
|
+
sub: (slice: SubS, msg: SubM) => [SubS, E[]];
|
|
30
|
+
}): (state: S, msg: M) => [S, E[]] | null;
|
|
31
|
+
//# sourceMappingURL=slice-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slice-handler.d.ts","sourceRoot":"","sources":["../src/slice-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;IACtD,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;IACvB,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,CAAA;IACjC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI,CAAA;IAC/B,GAAG,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;CAC7C,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAOxC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lens-style adapter that lifts a sub-component's `update` into a handler that
|
|
3
|
+
* operates on a parent's full state and message type. Pairs with
|
|
4
|
+
* `mergeHandlers` to compose sub-components into a parent component's reducer.
|
|
5
|
+
*
|
|
6
|
+
* - `get` / `set` isolate the sub-component's state slice within the parent state.
|
|
7
|
+
* - `narrow` takes the parent message and returns the sub-message if this slice
|
|
8
|
+
* handles it, or `null` to pass through.
|
|
9
|
+
* - `sub` is the sub-component's pure reducer (operates on its own state + msg).
|
|
10
|
+
*
|
|
11
|
+
* Example — embedding `dialog.update` into a parent reducer:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* const update = mergeHandlers<State, Msg, Effect>(
|
|
15
|
+
* sliceHandler({
|
|
16
|
+
* get: (s) => s.confirm,
|
|
17
|
+
* set: (s, v) => ({ ...s, confirm: v }),
|
|
18
|
+
* narrow: (m) => m.type === 'confirm' ? m.msg : null,
|
|
19
|
+
* sub: dialog.update,
|
|
20
|
+
* }),
|
|
21
|
+
* appUpdate,
|
|
22
|
+
* )
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function sliceHandler(opts) {
|
|
26
|
+
return (state, msg) => {
|
|
27
|
+
const subMsg = opts.narrow(msg);
|
|
28
|
+
if (subMsg === null)
|
|
29
|
+
return null;
|
|
30
|
+
const [nextSlice, effects] = opts.sub(opts.get(state), subMsg);
|
|
31
|
+
return [opts.set(state, nextSlice), effects];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=slice-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slice-handler.js","sourceRoot":"","sources":["../src/slice-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,YAAY,CAAsB,IAKjD;IACC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAChC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;QAC9D,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAA;IAC9C,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set up a minimal DOM environment for server-side rendering.
|
|
3
|
+
* Must be called (and awaited) once before renderToString on the server.
|
|
4
|
+
* Uses jsdom — the calling package must have jsdom as a dependency.
|
|
5
|
+
*
|
|
6
|
+
* Import this from '@llui/dom/ssr' in server entry points only.
|
|
7
|
+
* Never import in client code — jsdom is a server-only dependency.
|
|
8
|
+
*
|
|
9
|
+
* No-op if `document` is already defined.
|
|
10
|
+
*/
|
|
11
|
+
export declare function initSsrDom(): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=ssr-dom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-dom.d.ts","sourceRoot":"","sources":["../src/ssr-dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBhD"}
|
package/dist/ssr-dom.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set up a minimal DOM environment for server-side rendering.
|
|
3
|
+
* Must be called (and awaited) once before renderToString on the server.
|
|
4
|
+
* Uses jsdom — the calling package must have jsdom as a dependency.
|
|
5
|
+
*
|
|
6
|
+
* Import this from '@llui/dom/ssr' in server entry points only.
|
|
7
|
+
* Never import in client code — jsdom is a server-only dependency.
|
|
8
|
+
*
|
|
9
|
+
* No-op if `document` is already defined.
|
|
10
|
+
*/
|
|
11
|
+
export async function initSsrDom() {
|
|
12
|
+
if (typeof document !== 'undefined')
|
|
13
|
+
return;
|
|
14
|
+
// @ts-expect-error — jsdom is an optional peer dependency, not typed
|
|
15
|
+
const jsdomMod = await import('jsdom');
|
|
16
|
+
const jsdom = jsdomMod;
|
|
17
|
+
const dom = new jsdom.JSDOM('<!DOCTYPE html><html><body></body></html>');
|
|
18
|
+
const g = globalThis;
|
|
19
|
+
const win = dom.window;
|
|
20
|
+
for (const key of [
|
|
21
|
+
'document',
|
|
22
|
+
'HTMLElement',
|
|
23
|
+
'Element',
|
|
24
|
+
'Node',
|
|
25
|
+
'Text',
|
|
26
|
+
'Comment',
|
|
27
|
+
'MouseEvent',
|
|
28
|
+
'ShadowRoot',
|
|
29
|
+
'DocumentFragment',
|
|
30
|
+
'HTMLTemplateElement',
|
|
31
|
+
]) {
|
|
32
|
+
if (win[key] !== undefined)
|
|
33
|
+
g[key] = win[key];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=ssr-dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-dom.js","sourceRoot":"","sources":["../src/ssr-dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAM;IAE3C,qEAAqE;IACrE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,QAAgF,CAAA;IAC9F,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;IACxE,MAAM,CAAC,GAAG,UAAqC,CAAA;IAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAA;IACtB,KAAK,MAAM,GAAG,IAAI;QAChB,UAAU;QACV,aAAa;QACb,SAAS;QACT,MAAM;QACN,MAAM;QACN,SAAS;QACT,YAAY;QACZ,YAAY;QACZ,kBAAkB;QAClB,qBAAqB;KACtB,EAAE,CAAC;QACF,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IAC/C,CAAC;AACH,CAAC"}
|
package/dist/ssr.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentDef } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Render a component to an HTML string for SSR.
|
|
4
|
+
* Evaluates view() against the initial state (or provided data),
|
|
5
|
+
* serializes the DOM to HTML, and adds data-llui-hydrate markers
|
|
6
|
+
* on nodes with reactive bindings.
|
|
7
|
+
*
|
|
8
|
+
* Call initSsrDom() once before using this on the server.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderToString<S, M, E>(def: ComponentDef<S, M, E>, initialState?: S): string;
|
|
11
|
+
//# sourceMappingURL=ssr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr.d.ts","sourceRoot":"","sources":["../src/ssr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAM3C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,MAAM,CAoC5F"}
|
package/dist/ssr.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createComponentInstance } from './update-loop';
|
|
2
|
+
import { setRenderContext, clearRenderContext } from './render-context';
|
|
3
|
+
import { setFlatBindings } from './binding';
|
|
4
|
+
import { createView } from './view-helpers';
|
|
5
|
+
/**
|
|
6
|
+
* Render a component to an HTML string for SSR.
|
|
7
|
+
* Evaluates view() against the initial state (or provided data),
|
|
8
|
+
* serializes the DOM to HTML, and adds data-llui-hydrate markers
|
|
9
|
+
* on nodes with reactive bindings.
|
|
10
|
+
*
|
|
11
|
+
* Call initSsrDom() once before using this on the server.
|
|
12
|
+
*/
|
|
13
|
+
export function renderToString(def, initialState) {
|
|
14
|
+
const inst = createComponentInstance(def);
|
|
15
|
+
if (initialState !== undefined) {
|
|
16
|
+
inst.state = initialState;
|
|
17
|
+
}
|
|
18
|
+
setFlatBindings(inst.allBindings);
|
|
19
|
+
setRenderContext({ ...inst, send: inst.send });
|
|
20
|
+
const nodes = def.view(createView(inst.send));
|
|
21
|
+
clearRenderContext();
|
|
22
|
+
setFlatBindings(null);
|
|
23
|
+
// Serialize nodes to HTML
|
|
24
|
+
let html = '';
|
|
25
|
+
for (const node of nodes) {
|
|
26
|
+
html += nodeToString(node);
|
|
27
|
+
}
|
|
28
|
+
// Collect elements that need hydrate markers (bindings on them or their text children)
|
|
29
|
+
const hydrateElements = new Set();
|
|
30
|
+
for (const binding of inst.allBindings) {
|
|
31
|
+
const node = binding.node;
|
|
32
|
+
if (node.nodeType === 1) {
|
|
33
|
+
hydrateElements.add(node);
|
|
34
|
+
}
|
|
35
|
+
else if (node.parentNode && node.parentNode.nodeType === 1) {
|
|
36
|
+
hydrateElements.add(node.parentNode);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Re-serialize with markers
|
|
40
|
+
html = '';
|
|
41
|
+
for (const node of nodes) {
|
|
42
|
+
html += nodeToStringWithMarkers(node, hydrateElements);
|
|
43
|
+
}
|
|
44
|
+
return html;
|
|
45
|
+
}
|
|
46
|
+
function nodeToString(node) {
|
|
47
|
+
if (node.nodeType === 3) {
|
|
48
|
+
return escapeHtml(node.textContent ?? '');
|
|
49
|
+
}
|
|
50
|
+
if (node.nodeType === 8) {
|
|
51
|
+
return `<!--${node.textContent ?? ''}-->`;
|
|
52
|
+
}
|
|
53
|
+
if (node.nodeType === 1) {
|
|
54
|
+
const el = node;
|
|
55
|
+
return elementToString(el, false, new Set());
|
|
56
|
+
}
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
function nodeToStringWithMarkers(node, bindingNodes) {
|
|
60
|
+
if (node.nodeType === 3) {
|
|
61
|
+
return escapeHtml(node.textContent ?? '');
|
|
62
|
+
}
|
|
63
|
+
if (node.nodeType === 8) {
|
|
64
|
+
return `<!--${node.textContent ?? ''}-->`;
|
|
65
|
+
}
|
|
66
|
+
if (node.nodeType === 1) {
|
|
67
|
+
const el = node;
|
|
68
|
+
return elementToString(el, true, bindingNodes);
|
|
69
|
+
}
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
function elementToString(el, withMarkers, bindingNodes) {
|
|
73
|
+
const tag = el.tagName.toLowerCase();
|
|
74
|
+
let attrs = '';
|
|
75
|
+
for (let i = 0; i < el.attributes.length; i++) {
|
|
76
|
+
const attr = el.attributes[i];
|
|
77
|
+
// Skip event handler attributes
|
|
78
|
+
if (attr.name.startsWith('on'))
|
|
79
|
+
continue;
|
|
80
|
+
attrs += ` ${attr.name}="${escapeAttr(attr.value)}"`;
|
|
81
|
+
}
|
|
82
|
+
// Add hydrate marker if this element or any of its text children have bindings
|
|
83
|
+
if (withMarkers && bindingNodes.has(el)) {
|
|
84
|
+
attrs += ' data-llui-hydrate';
|
|
85
|
+
}
|
|
86
|
+
// Void elements
|
|
87
|
+
if (isVoidElement(tag)) {
|
|
88
|
+
return `<${tag}${attrs} />`;
|
|
89
|
+
}
|
|
90
|
+
let children = '';
|
|
91
|
+
for (let i = 0; i < el.childNodes.length; i++) {
|
|
92
|
+
const child = el.childNodes[i];
|
|
93
|
+
if (withMarkers) {
|
|
94
|
+
children += nodeToStringWithMarkers(child, bindingNodes);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
children += nodeToString(child);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return `<${tag}${attrs}>${children}</${tag}>`;
|
|
101
|
+
}
|
|
102
|
+
function escapeHtml(s) {
|
|
103
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
104
|
+
}
|
|
105
|
+
function escapeAttr(s) {
|
|
106
|
+
return s.replace(/&/g, '&').replace(/"/g, '"');
|
|
107
|
+
}
|
|
108
|
+
const VOID_ELEMENTS = new Set([
|
|
109
|
+
'area',
|
|
110
|
+
'base',
|
|
111
|
+
'br',
|
|
112
|
+
'col',
|
|
113
|
+
'embed',
|
|
114
|
+
'hr',
|
|
115
|
+
'img',
|
|
116
|
+
'input',
|
|
117
|
+
'link',
|
|
118
|
+
'meta',
|
|
119
|
+
'param',
|
|
120
|
+
'source',
|
|
121
|
+
'track',
|
|
122
|
+
'wbr',
|
|
123
|
+
]);
|
|
124
|
+
function isVoidElement(tag) {
|
|
125
|
+
return VOID_ELEMENTS.has(tag);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=ssr.js.map
|
package/dist/ssr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr.js","sourceRoot":"","sources":["../src/ssr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../src/structural.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural.js","sourceRoot":"","sources":["../src/structural.ts"],"names":[],"mappings":""}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { View } from './view-helpers';
|
|
2
|
+
export interface ComponentDef<S, M, E = never, D = void> {
|
|
3
|
+
name: string;
|
|
4
|
+
init: (data: D) => [S, E[]];
|
|
5
|
+
update: (state: S, msg: M) => [S, E[]];
|
|
6
|
+
view: (h: View<S, M>) => Node[];
|
|
7
|
+
onEffect?: (ctx: {
|
|
8
|
+
effect: E;
|
|
9
|
+
send: Send<M>;
|
|
10
|
+
signal: AbortSignal;
|
|
11
|
+
}) => void;
|
|
12
|
+
propsMsg?: (props: Record<string, unknown>) => M;
|
|
13
|
+
receives?: Record<string, (params: unknown) => M>;
|
|
14
|
+
}
|
|
15
|
+
export type Send<M> = (msg: M) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Maps a value shape to a reactive-props shape: every field becomes an accessor
|
|
18
|
+
* `(s: S) => V`. Use for Level-1 view function signatures.
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* type ToolbarData = { tools: Tool[]; theme: 'light' | 'dark' }
|
|
22
|
+
*
|
|
23
|
+
* export function toolbar<S>(props: Props<ToolbarData, S>, send: Send<Msg>) {
|
|
24
|
+
* return [div({ class: props.theme }, [each({ items: props.tools, ... })])]
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* // Caller — TypeScript enforces per-field accessors; passing a raw value errors:
|
|
28
|
+
* toolbar({ tools: (s: State) => s.tools, theme: (s) => s.theme }, send)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export type Props<T, S> = {
|
|
32
|
+
[K in keyof T]: (s: S) => T[K];
|
|
33
|
+
};
|
|
34
|
+
export interface AppHandle {
|
|
35
|
+
dispose(): void;
|
|
36
|
+
flush(): void;
|
|
37
|
+
}
|
|
38
|
+
export interface Scope {
|
|
39
|
+
id: number;
|
|
40
|
+
parent: Scope | null;
|
|
41
|
+
children: Scope[];
|
|
42
|
+
disposers: Array<() => void>;
|
|
43
|
+
bindings: Binding[];
|
|
44
|
+
eachItemStable: boolean;
|
|
45
|
+
/** Per-item updaters — called directly by each() when item changes, bypassing Phase 2 */
|
|
46
|
+
itemUpdaters: Array<() => void>;
|
|
47
|
+
}
|
|
48
|
+
export type BindingKind = 'text' | 'prop' | 'attr' | 'class' | 'style';
|
|
49
|
+
export interface Binding {
|
|
50
|
+
mask: number;
|
|
51
|
+
accessor: (state: unknown) => unknown;
|
|
52
|
+
lastValue: unknown;
|
|
53
|
+
kind: BindingKind;
|
|
54
|
+
node: Node;
|
|
55
|
+
key?: string;
|
|
56
|
+
ownerScope: Scope;
|
|
57
|
+
perItem: boolean;
|
|
58
|
+
dead: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface TransitionOptions {
|
|
61
|
+
enter?: (nodes: Node[]) => void | Promise<void>;
|
|
62
|
+
leave?: (nodes: Node[]) => void | Promise<void>;
|
|
63
|
+
onTransition?: (ctx: {
|
|
64
|
+
entering: Node[];
|
|
65
|
+
leaving: Node[];
|
|
66
|
+
parent: Node;
|
|
67
|
+
}) => void | Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
export interface BranchOptions<S, M = unknown> extends TransitionOptions {
|
|
70
|
+
on: (s: S) => string | number | boolean;
|
|
71
|
+
cases: Record<string | number, (send: Send<M>) => Node[]>;
|
|
72
|
+
}
|
|
73
|
+
export interface ShowOptions<S, M = unknown> extends TransitionOptions {
|
|
74
|
+
when: (s: S) => boolean;
|
|
75
|
+
render: (send: Send<M>) => Node[];
|
|
76
|
+
fallback?: (send: Send<M>) => Node[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Options for `each()`. The inherited `enter` / `leave` callbacks fire **per item**:
|
|
80
|
+
* `enter(nodes)` runs after an item's DOM is inserted (including initial mount);
|
|
81
|
+
* `leave(nodes)` runs before an item's DOM is removed and may return a Promise
|
|
82
|
+
* to hold the DOM until the animation resolves. Setting `leave` disables the
|
|
83
|
+
* bulk-clear / full-replace fast paths.
|
|
84
|
+
*/
|
|
85
|
+
/**
|
|
86
|
+
* Per-item accessor. Two access forms:
|
|
87
|
+
* - `item.field` — shorthand, returns accessor for `item.current[field]`
|
|
88
|
+
* - `item(t => t.expr)` — computed expressions
|
|
89
|
+
*
|
|
90
|
+
* In both cases the returned value is a `() => V` accessor.
|
|
91
|
+
* Invoke it (`item.field()`) to read the current value imperatively.
|
|
92
|
+
*/
|
|
93
|
+
export type ItemAccessor<T> = {
|
|
94
|
+
<R>(selector: (t: T) => R): () => R;
|
|
95
|
+
} & {
|
|
96
|
+
[K in keyof T]-?: () => T[K];
|
|
97
|
+
};
|
|
98
|
+
export interface EachOptions<S, T, M = unknown> extends TransitionOptions {
|
|
99
|
+
items: (s: S) => T[];
|
|
100
|
+
key: (item: T) => string | number;
|
|
101
|
+
render: (opts: {
|
|
102
|
+
send: Send<M>;
|
|
103
|
+
item: ItemAccessor<T>;
|
|
104
|
+
/**
|
|
105
|
+
* Plain (non-Proxy) accessor factory. Compiler-output path; avoid in user code
|
|
106
|
+
* (use `item.field` / `item(fn)` — more ergonomic and bypasses Proxy when compiled).
|
|
107
|
+
*/
|
|
108
|
+
acc: <R>(selector: (t: T) => R) => () => R;
|
|
109
|
+
index: () => number;
|
|
110
|
+
}) => Node[];
|
|
111
|
+
}
|
|
112
|
+
export interface PortalOptions {
|
|
113
|
+
target: HTMLElement | string;
|
|
114
|
+
render: () => Node[];
|
|
115
|
+
}
|
|
116
|
+
export interface ForeignOptions<S, M, T extends Record<string, unknown>, Instance> {
|
|
117
|
+
mount: (ctx: {
|
|
118
|
+
container: HTMLElement;
|
|
119
|
+
send: Send<M>;
|
|
120
|
+
}) => Instance;
|
|
121
|
+
props: (s: S) => T;
|
|
122
|
+
sync: ((ctx: {
|
|
123
|
+
instance: Instance;
|
|
124
|
+
props: T;
|
|
125
|
+
prev: T | undefined;
|
|
126
|
+
}) => void) | {
|
|
127
|
+
[K in keyof T]?: (ctx: {
|
|
128
|
+
instance: Instance;
|
|
129
|
+
value: T[K];
|
|
130
|
+
prev: T[K] | undefined;
|
|
131
|
+
}) => void;
|
|
132
|
+
};
|
|
133
|
+
destroy: (instance: Instance) => void;
|
|
134
|
+
container?: {
|
|
135
|
+
tag?: string;
|
|
136
|
+
attrs?: Record<string, string>;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export interface ChildOptions<S, ChildM> {
|
|
140
|
+
def: ComponentDef<unknown, ChildM, unknown>;
|
|
141
|
+
key: string | number;
|
|
142
|
+
props: (s: S) => Record<string, unknown>;
|
|
143
|
+
onMsg?: (msg: ChildM) => unknown | null;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,qEAAqE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ComponentDef, Scope, Binding } from './types';
|
|
2
|
+
import type { StructuralBlock } from './structural';
|
|
3
|
+
export declare const FULL_MASK: number;
|
|
4
|
+
export declare function setAddressedDispatcher(fn: (eff: {
|
|
5
|
+
__targetKey: string | number;
|
|
6
|
+
__msg: unknown;
|
|
7
|
+
}) => void): void;
|
|
8
|
+
export interface ComponentInstance<S = unknown, M = unknown, E = unknown> {
|
|
9
|
+
def: ComponentDef<S, M, E>;
|
|
10
|
+
state: S;
|
|
11
|
+
initialEffects: E[];
|
|
12
|
+
rootScope: Scope;
|
|
13
|
+
allBindings: Binding[];
|
|
14
|
+
structuralBlocks: StructuralBlock[];
|
|
15
|
+
queue: M[];
|
|
16
|
+
microtaskScheduled: boolean;
|
|
17
|
+
lastDirtyMask: number;
|
|
18
|
+
lastEffects: E[];
|
|
19
|
+
send: (msg: M) => void;
|
|
20
|
+
signal: AbortSignal;
|
|
21
|
+
abortController: AbortController;
|
|
22
|
+
}
|
|
23
|
+
export declare function createComponentInstance<S, M, E>(def: ComponentDef<S, M, E>, data?: unknown): ComponentInstance<S, M, E>;
|
|
24
|
+
export declare function flushInstance<S, M, E>(inst: ComponentInstance<S, M, E>): void;
|
|
25
|
+
/**
|
|
26
|
+
* Dev-only: overwrite instance state and re-run both phases with FULL_MASK
|
|
27
|
+
* so every binding re-evaluates. Bypasses update() — use for devtools
|
|
28
|
+
* snapshot/restore, not in app code.
|
|
29
|
+
*/
|
|
30
|
+
export declare function _forceState<S, M, E>(inst: ComponentInstance<S, M, E>, newState: S): void;
|
|
31
|
+
//# sourceMappingURL=update-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-loop.d.ts","sourceRoot":"","sources":["../src/update-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAKnD,eAAO,MAAM,SAAS,QAAiB,CAAA;AAMvC,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,CAAC,GAAG,EAAE;IAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,IAAI,GAClE,IAAI,CAEN;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACtE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1B,KAAK,EAAE,CAAC,CAAA;IACR,cAAc,EAAE,CAAC,EAAE,CAAA;IACnB,SAAS,EAAE,KAAK,CAAA;IAChB,WAAW,EAAE,OAAO,EAAE,CAAA;IACtB,gBAAgB,EAAE,eAAe,EAAE,CAAA;IACnC,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,kBAAkB,EAAE,OAAO,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,CAAC,EAAE,CAAA;IAChB,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAA;IACtB,MAAM,EAAE,WAAW,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;CACjC;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7C,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,OAAO,GACb,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAgC5B;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAI7E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,CAiCxF"}
|