@llui/dom 0.0.15 → 0.0.17
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/el-split.d.ts +1 -1
- package/dist/el-split.d.ts.map +1 -1
- package/dist/el-split.js +22 -3
- package/dist/el-split.js.map +1 -1
- package/dist/hmr.d.ts.map +1 -1
- package/dist/hmr.js +4 -0
- package/dist/hmr.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +22 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +21 -0
- package/dist/internal.js.map +1 -0
- package/dist/mount.d.ts +16 -3
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +18 -5
- package/dist/mount.js.map +1 -1
- package/dist/primitives/context.d.ts +45 -0
- package/dist/primitives/context.d.ts.map +1 -1
- package/dist/primitives/context.js +52 -0
- package/dist/primitives/context.js.map +1 -1
- package/dist/ssr.d.ts +32 -1
- package/dist/ssr.d.ts.map +1 -1
- package/dist/ssr.js +44 -38
- package/dist/ssr.js.map +1 -1
- package/dist/types.d.ts +66 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/update-loop.d.ts +1 -1
- package/dist/update-loop.d.ts.map +1 -1
- package/dist/update-loop.js +8 -2
- package/dist/update-loop.js.map +1 -1
- package/package.json +5 -1
package/dist/el-split.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { BindingKind } from './types.js';
|
|
2
|
-
export declare function elSplit(tag: string, staticFn: ((el: HTMLElement) => void) | null, events: Array<[string, EventListener]> | null, bindings: Array<[number, BindingKind, string, (state: never) => unknown]> | null, children: Array<Node | string
|
|
2
|
+
export declare function elSplit(tag: string, staticFn: ((el: HTMLElement) => void) | null, events: Array<[string, EventListener]> | null, bindings: Array<[number, BindingKind, string, (state: never) => unknown]> | null, children: Array<Node | string | Array<Node | string>> | null): HTMLElement;
|
|
3
3
|
//# sourceMappingURL=el-split.d.ts.map
|
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;AAK7C,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,EAC7C,QAAQ,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,
|
|
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;AAK7C,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,EAC7C,QAAQ,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,EAMhF,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,GAC3D,WAAW,CAsEb"}
|
package/dist/el-split.js
CHANGED
|
@@ -2,9 +2,11 @@ import { getRenderContext } from './render-context.js';
|
|
|
2
2
|
import { createBinding, applyBinding } from './binding.js';
|
|
3
3
|
import { addCheckedItemUpdater } from './scope.js';
|
|
4
4
|
export function elSplit(tag, staticFn, events, bindings,
|
|
5
|
-
// Accepts raw strings too
|
|
6
|
-
// user code like `button([], ['Sign in'])` works without
|
|
7
|
-
//
|
|
5
|
+
// Accepts raw strings too (wrapped in Text nodes at append time so
|
|
6
|
+
// user code like `button([], ['Sign in'])` works without an explicit
|
|
7
|
+
// text() wrapper) and nested arrays (flattened one level to match the
|
|
8
|
+
// raw createElement path — supports patterns like `main([pageSlot()])`
|
|
9
|
+
// where pageSlot() returns Node[]).
|
|
8
10
|
children) {
|
|
9
11
|
const el = document.createElement(tag);
|
|
10
12
|
if (staticFn) {
|
|
@@ -50,6 +52,23 @@ children) {
|
|
|
50
52
|
if (typeof child === 'string') {
|
|
51
53
|
el.appendChild(document.createTextNode(child));
|
|
52
54
|
}
|
|
55
|
+
else if (Array.isArray(child)) {
|
|
56
|
+
// Arrays-in-children are flattened one level. This matches
|
|
57
|
+
// the raw createElement path in elements.ts and makes patterns
|
|
58
|
+
// like `main([pageSlot()])` (where pageSlot() returns Node[])
|
|
59
|
+
// work consistently between raw and compiled call paths.
|
|
60
|
+
// Without this flattening, tests run via vitest pass (raw path
|
|
61
|
+
// flattens) but SSR via the compiler transform crashes with
|
|
62
|
+
// "appendChild parameter is not of type Node".
|
|
63
|
+
for (const node of child) {
|
|
64
|
+
if (typeof node === 'string') {
|
|
65
|
+
el.appendChild(document.createTextNode(node));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
el.appendChild(node);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
53
72
|
else {
|
|
54
73
|
el.appendChild(child);
|
|
55
74
|
}
|
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,YAAY,CAAA;AAElD,MAAM,UAAU,OAAO,CACrB,GAAW,EACX,QAA4C,EAC5C,MAA6C,EAC7C,QAAgF;AAChF,
|
|
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 './scope.js'\n\nexport function elSplit(\n tag: string,\n staticFn: ((el: HTMLElement) => void) | null,\n events: Array<[string, EventListener]> | null,\n bindings: Array<[number, BindingKind, string, (state: never) => unknown]> | 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 el = document.createElement(tag)\n\n if (staticFn) {\n staticFn(el)\n }\n\n if (events) {\n for (const [eventName, handler] of events) {\n el.addEventListener(eventName, handler)\n }\n }\n\n const ctx = getRenderContext()\n\n if (bindings) {\n for (const [mask, kind, key, accessor] of bindings) {\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.rootScope, get, (v) => applyBinding(target, v))\n applyBinding(target, initial)\n } else {\n const binding = createBinding(ctx.rootScope, {\n mask,\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(document.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(document.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"]}
|
package/dist/hmr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAUzD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAWD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,IAAI,CAIvF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACtC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC5B,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAUzD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAWD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,IAAI,CAIvF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACtC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC5B,SAAS,GAAG,IAAI,CAsElB"}
|
package/dist/hmr.js
CHANGED
package/dist/hmr.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport { flushInstance } from './update-loop.js'\nimport { createScope, disposeScope } from './scope.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { unregisterInstance } from './runtime.js'\nimport { _setHmrModule } from './mount.js'\nimport { createView } from './view-helpers.js'\n\n/**\n * Enable HMR state preservation. Called by compiler-generated dev code.\n * Importing this module registers it with mountApp for hot-swapping.\n */\nexport function enableHmr(): void {\n _setHmrModule({ enableHmr, registerForHmr, unregisterForHmr, replaceComponent })\n}\n\n// ── HMR Registry ─────────────────────────────────────────────────\n\ninterface HmrEntry {\n inst: ComponentInstance\n container: HTMLElement\n}\n\nconst hmrRegistry = new Map<string, HmrEntry[]>()\n\nexport function registerForHmr(name: string, inst: object, container: HTMLElement): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ inst: inst as ComponentInstance, container })\n hmrRegistry.set(name, entries)\n}\n\nexport function unregisterForHmr(name: string, inst: object): void {\n const entries = hmrRegistry.get(name)\n if (!entries) return\n const idx = entries.findIndex((e) => e.inst === inst)\n if (idx !== -1) entries.splice(idx, 1)\n if (entries.length === 0) hmrRegistry.delete(name)\n}\n\n/**\n * Hot-swap a component definition on all live instances.\n *\n * Preserves the current state. Replaces update, view, onEffect, and __dirty.\n * Disposes the old scope tree (removing old DOM and bindings),\n * re-runs view(currentState, send) to rebuild fresh DOM.\n *\n * Returns an AppHandle for the first instance (for mountApp compatibility),\n * or null if no instances are registered (first mount).\n */\nexport function replaceComponent<S, M, E>(\n name: string,\n newDef: ComponentDef<S, M, E>,\n): AppHandle | null {\n const entries = hmrRegistry.get(name)\n if (!entries || entries.length === 0) return null\n\n let handle: AppHandle | null = null\n\n for (const { inst, container } of entries) {\n const typedInst = inst as ComponentInstance<S, M, E>\n\n // Replace functions on the live definition\n typedInst.def = {\n ...typedInst.def,\n update: newDef.update,\n view: newDef.view,\n onEffect: newDef.onEffect,\n __dirty: newDef.__dirty,\n __update: newDef.__update,\n __handlers: newDef.__handlers,\n }\n\n // Dispose old scope tree — removes all old DOM nodes and bindings\n disposeScope(typedInst.rootScope)\n container.textContent = ''\n\n // Create fresh scope tree\n typedInst.rootScope = createScope(null)\n typedInst.allBindings = []\n typedInst.structuralBlocks = []\n\n // Re-run view with current state\n setFlatBindings(typedInst.allBindings)\n setRenderContext({\n rootScope: typedInst.rootScope,\n state: typedInst.state,\n allBindings: typedInst.allBindings,\n structuralBlocks: typedInst.structuralBlocks,\n container,\n send: typedInst.send as (msg: unknown) => void,\n })\n const nodes = typedInst.def.view(createView<S, M>(typedInst.send))\n clearRenderContext()\n setFlatBindings(null)\n\n for (const node of nodes) {\n container.appendChild(node)\n }\n\n // Return AppHandle for the first instance\n if (!handle) {\n handle = {\n dispose() {\n unregisterForHmr(name, inst)\n inst.abortController.abort()\n unregisterInstance(inst)\n disposeScope(typedInst.rootScope)\n container.textContent = ''\n },\n flush() {\n flushInstance(inst)\n },\n }\n }\n }\n\n console.log(`[LLui HMR] ${name} updated — state preserved`)\n\n return handle\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport { flushInstance } from './update-loop.js'\nimport { createScope, disposeScope } from './scope.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { unregisterInstance } from './runtime.js'\nimport { _setHmrModule } from './mount.js'\nimport { createView } from './view-helpers.js'\n\n/**\n * Enable HMR state preservation. Called by compiler-generated dev code.\n * Importing this module registers it with mountApp for hot-swapping.\n */\nexport function enableHmr(): void {\n _setHmrModule({ enableHmr, registerForHmr, unregisterForHmr, replaceComponent })\n}\n\n// ── HMR Registry ─────────────────────────────────────────────────\n\ninterface HmrEntry {\n inst: ComponentInstance\n container: HTMLElement\n}\n\nconst hmrRegistry = new Map<string, HmrEntry[]>()\n\nexport function registerForHmr(name: string, inst: object, container: HTMLElement): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ inst: inst as ComponentInstance, container })\n hmrRegistry.set(name, entries)\n}\n\nexport function unregisterForHmr(name: string, inst: object): void {\n const entries = hmrRegistry.get(name)\n if (!entries) return\n const idx = entries.findIndex((e) => e.inst === inst)\n if (idx !== -1) entries.splice(idx, 1)\n if (entries.length === 0) hmrRegistry.delete(name)\n}\n\n/**\n * Hot-swap a component definition on all live instances.\n *\n * Preserves the current state. Replaces update, view, onEffect, and __dirty.\n * Disposes the old scope tree (removing old DOM and bindings),\n * re-runs view(currentState, send) to rebuild fresh DOM.\n *\n * Returns an AppHandle for the first instance (for mountApp compatibility),\n * or null if no instances are registered (first mount).\n */\nexport function replaceComponent<S, M, E>(\n name: string,\n newDef: ComponentDef<S, M, E>,\n): AppHandle | null {\n const entries = hmrRegistry.get(name)\n if (!entries || entries.length === 0) return null\n\n let handle: AppHandle | null = null\n\n for (const { inst, container } of entries) {\n const typedInst = inst as ComponentInstance<S, M, E>\n\n // Replace functions on the live definition\n typedInst.def = {\n ...typedInst.def,\n update: newDef.update,\n view: newDef.view,\n onEffect: newDef.onEffect,\n __dirty: newDef.__dirty,\n __update: newDef.__update,\n __handlers: newDef.__handlers,\n }\n\n // Dispose old scope tree — removes all old DOM nodes and bindings\n disposeScope(typedInst.rootScope)\n container.textContent = ''\n\n // Create fresh scope tree\n typedInst.rootScope = createScope(null)\n typedInst.allBindings = []\n typedInst.structuralBlocks = []\n\n // Re-run view with current state\n setFlatBindings(typedInst.allBindings)\n setRenderContext({\n rootScope: typedInst.rootScope,\n state: typedInst.state,\n allBindings: typedInst.allBindings,\n structuralBlocks: typedInst.structuralBlocks,\n container,\n send: typedInst.send as (msg: unknown) => void,\n })\n const nodes = typedInst.def.view(createView<S, M>(typedInst.send))\n clearRenderContext()\n setFlatBindings(null)\n\n for (const node of nodes) {\n container.appendChild(node)\n }\n\n // Return AppHandle for the first instance\n if (!handle) {\n handle = {\n dispose() {\n unregisterForHmr(name, inst)\n inst.abortController.abort()\n unregisterInstance(inst)\n disposeScope(typedInst.rootScope)\n container.textContent = ''\n },\n flush() {\n flushInstance(inst)\n },\n send(msg: unknown) {\n ;(typedInst.send as (m: unknown) => void)(msg)\n },\n }\n }\n }\n\n console.log(`[LLui HMR] ${name} updated — state preserved`)\n\n return handle\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,9 @@ export { mountApp, hydrateApp, type MountOptions } from './mount.js';
|
|
|
5
5
|
export type { LluiDebugAPI } from './devtools.js';
|
|
6
6
|
export { flush } from './runtime.js';
|
|
7
7
|
export { addressOf } from './addressed.js';
|
|
8
|
-
export { renderToString } from './ssr.js';
|
|
8
|
+
export { renderToString, renderNodes, serializeNodes } from './ssr.js';
|
|
9
9
|
export { mergeHandlers } from './merge-handlers.js';
|
|
10
|
-
export { createContext, provide, useContext, type Context } from './primitives/context.js';
|
|
10
|
+
export { createContext, provide, provideValue, useContext, useContextValue, type Context, } from './primitives/context.js';
|
|
11
11
|
export { sliceHandler } from './slice-handler.js';
|
|
12
12
|
export { childHandlers, type ChildState, type ChildMsg, type ModuleState, type ModuleMsg, } from './compose.js';
|
|
13
13
|
export { text } from './primitives/text.js';
|
|
@@ -20,7 +20,7 @@ export { portal } from './primitives/portal.js';
|
|
|
20
20
|
export { foreign } from './primitives/foreign.js';
|
|
21
21
|
export { child } from './primitives/child.js';
|
|
22
22
|
export { lazy, type LazyOptions } from './primitives/lazy.js';
|
|
23
|
-
export type { LazyDef } from './types.js';
|
|
23
|
+
export type { LazyDef, AnyComponentDef } from './types.js';
|
|
24
24
|
export { memo } from './primitives/memo.js';
|
|
25
25
|
export { selector } from './primitives/selector.js';
|
|
26
26
|
export { onMount } from './primitives/on-mount.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,SAAS,EACT,KAAK,EACL,OAAO,EACP,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,GACb,MAAM,YAAY,CAAA;AAInB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAIzD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAGpE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAIjD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7,9 +7,9 @@ export { mountApp, hydrateApp } from './mount.js';
|
|
|
7
7
|
// ── Runtime ───────────────────────────────────────────────────────
|
|
8
8
|
export { flush } from './runtime.js';
|
|
9
9
|
export { addressOf } from './addressed.js';
|
|
10
|
-
export { renderToString } from './ssr.js';
|
|
10
|
+
export { renderToString, renderNodes, serializeNodes } from './ssr.js';
|
|
11
11
|
export { mergeHandlers } from './merge-handlers.js';
|
|
12
|
-
export { createContext, provide, useContext } from './primitives/context.js';
|
|
12
|
+
export { createContext, provide, provideValue, useContext, useContextValue, } from './primitives/context.js';
|
|
13
13
|
export { sliceHandler } from './slice-handler.js';
|
|
14
14
|
export { childHandlers, } from './compose.js';
|
|
15
15
|
// ── View Primitives ───────────────────────────────────────────────
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAoBrE,qEAAqE;AAErE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAa,MAAM,mBAAmB,CAAA;AAEzD,qEAAqE;AAErE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAqB,MAAM,YAAY,CAAA;AAKpE,qEAAqE;AAErE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// ── Types ─────────────────────────────────────────────────────────\n\nexport type {\n ComponentDef,\n Send,\n Props,\n AppHandle,\n Scope,\n Binding,\n BindingKind,\n TransitionOptions,\n BranchOptions,\n ShowOptions,\n EachOptions,\n ItemAccessor,\n PortalOptions,\n ForeignOptions,\n ChildOptions,\n} from './types.js'\n\n// ── Component ─────────────────────────────────────────────────────\n\nexport { component } from './component.js'\nexport { createView, type View } from './view-helpers.js'\n\n// ── Mount ─────────────────────────────────────────────────────────\n\nexport { mountApp, hydrateApp, type MountOptions } from './mount.js'\n// installDevTools is NOT re-exported here to keep it out of production bundles.\n// Import directly: import { installDevTools } from '@llui/dom/devtools'\nexport type { LluiDebugAPI } from './devtools.js'\n\n// ── Runtime ───────────────────────────────────────────────────────\n\nexport { flush } from './runtime.js'\nexport { addressOf } from './addressed.js'\nexport { renderToString, renderNodes, serializeNodes } from './ssr.js'\nexport { mergeHandlers } from './merge-handlers.js'\nexport {\n createContext,\n provide,\n provideValue,\n useContext,\n useContextValue,\n type Context,\n} from './primitives/context.js'\nexport { sliceHandler } from './slice-handler.js'\nexport {\n childHandlers,\n type ChildState,\n type ChildMsg,\n type ModuleState,\n type ModuleMsg,\n} from './compose.js'\n\n// ── View Primitives ───────────────────────────────────────────────\n\nexport { text } from './primitives/text.js'\nexport { branch } from './primitives/branch.js'\nexport { each } from './primitives/each.js'\nexport { virtualEach, type VirtualEachOptions } from './primitives/virtual-each.js'\nexport { show } from './primitives/show.js'\nexport { slice } from './primitives/slice.js'\nexport { portal } from './primitives/portal.js'\nexport { foreign } from './primitives/foreign.js'\nexport { child } from './primitives/child.js'\nexport { lazy, type LazyOptions } from './primitives/lazy.js'\nexport type { LazyDef, AnyComponentDef } from './types.js'\nexport { memo } from './primitives/memo.js'\nexport { selector } from './primitives/selector.js'\nexport { onMount } from './primitives/on-mount.js'\nexport { errorBoundary } from './primitives/error-boundary.js'\n\n// ── Element Helpers ───────────────────────────────────────────────\n\nexport {\n a,\n abbr,\n article,\n aside,\n b,\n blockquote,\n br,\n button,\n canvas,\n code,\n dd,\n details,\n dialog,\n div,\n dl,\n dt,\n em,\n fieldset,\n figcaption,\n figure,\n footer,\n form,\n h1,\n h2,\n h3,\n h4,\n h5,\n h6,\n header,\n hr,\n i,\n iframe,\n img,\n input,\n label,\n legend,\n li,\n main,\n mark,\n nav,\n ol,\n optgroup,\n option,\n output,\n p,\n pre,\n progress,\n section,\n select,\n small,\n span,\n strong,\n sub,\n summary,\n sup,\n table,\n tbody,\n td,\n textarea,\n tfoot,\n th,\n thead,\n time,\n tr,\n ul,\n video,\n} from './elements.js'\n\n// ── SVG Elements ─────────────────────────────────────────────────\n\nexport {\n svg,\n g,\n defs,\n symbol,\n use,\n circle,\n ellipse,\n line,\n path,\n polygon,\n polyline,\n rect,\n text as svgText,\n tspan,\n textPath,\n clipPath,\n linearGradient,\n radialGradient,\n stop,\n mask,\n pattern,\n marker,\n filter,\n feBlend,\n feColorMatrix,\n feComponentTransfer,\n feComposite,\n feConvolveMatrix,\n feDiffuseLighting,\n feDisplacementMap,\n feDropShadow,\n feFlood,\n feGaussianBlur,\n feImage,\n feMerge,\n feMergeNode,\n feMorphology,\n feOffset,\n feSpecularLighting,\n feTile,\n feTurbulence,\n fePointLight,\n feSpotLight,\n feDistantLight,\n feFuncR,\n feFuncG,\n feFuncB,\n feFuncA,\n image,\n foreignObject,\n animate,\n animateMotion,\n animateTransform,\n set,\n mpath,\n desc,\n title as svgTitle,\n metadata,\n} from './svg-elements.js'\n\n// ── MathML Elements ──────────────────────────────────────────────\n\nexport {\n math,\n mi,\n mn,\n mo,\n ms,\n mtext,\n mrow,\n mfrac,\n msqrt,\n mroot,\n msup,\n msub,\n msubsup,\n munder,\n mover,\n munderover,\n mmultiscripts,\n mprescripts,\n mnone,\n mtable,\n mtr,\n mtd,\n mspace,\n mpadded,\n mphantom,\n menclose,\n merror,\n maction,\n semantics,\n annotation,\n annotationXml,\n} from './mathml-elements.js'\n\n// ── Form Utilities ────────────────────────────────────────────────\n\nexport { applyField, type FieldMsg } from './form.js'\n\n// ── Compiler Target ───────────────────────────────────────────────\n\nexport { elSplit } from './el-split.js'\nexport { elTemplate } from './el-template.js'\nexport { _runPhase2 as __runPhase2, _handleMsg as __handleMsg } from './update-loop.js'\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal primitives surface — exported for framework-adapter packages
|
|
3
|
+
* (`@llui/vike`, `@llui/router`, `@llui/transitions`) that need to build
|
|
4
|
+
* their own structural primitives on top of LLui's scope + render-context
|
|
5
|
+
* machinery.
|
|
6
|
+
*
|
|
7
|
+
* **Not part of the public API.** App authors should not import from
|
|
8
|
+
* `@llui/dom/internal`. The shapes here are free to change without a
|
|
9
|
+
* major version bump — the stability contract applies only to the public
|
|
10
|
+
* barrel at `@llui/dom`. Reach for this subpath when you're writing a
|
|
11
|
+
* primitive like `pageSlot()` (from `@llui/vike`) that has to participate
|
|
12
|
+
* in the scope tree, not when you're writing application views.
|
|
13
|
+
*
|
|
14
|
+
* Added in 0.0.16 to support `@llui/vike`'s persistent-layout feature.
|
|
15
|
+
* Any future adapter-level primitive that needs render-context / scope
|
|
16
|
+
* access should re-export from this file rather than duplicating the
|
|
17
|
+
* low-level glue.
|
|
18
|
+
*/
|
|
19
|
+
export { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js';
|
|
20
|
+
export type { RenderContext } from './render-context.js';
|
|
21
|
+
export { createScope, disposeScope, addDisposer } from './scope.js';
|
|
22
|
+
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC5F,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/internal.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal primitives surface — exported for framework-adapter packages
|
|
3
|
+
* (`@llui/vike`, `@llui/router`, `@llui/transitions`) that need to build
|
|
4
|
+
* their own structural primitives on top of LLui's scope + render-context
|
|
5
|
+
* machinery.
|
|
6
|
+
*
|
|
7
|
+
* **Not part of the public API.** App authors should not import from
|
|
8
|
+
* `@llui/dom/internal`. The shapes here are free to change without a
|
|
9
|
+
* major version bump — the stability contract applies only to the public
|
|
10
|
+
* barrel at `@llui/dom`. Reach for this subpath when you're writing a
|
|
11
|
+
* primitive like `pageSlot()` (from `@llui/vike`) that has to participate
|
|
12
|
+
* in the scope tree, not when you're writing application views.
|
|
13
|
+
*
|
|
14
|
+
* Added in 0.0.16 to support `@llui/vike`'s persistent-layout feature.
|
|
15
|
+
* Any future adapter-level primitive that needs render-context / scope
|
|
16
|
+
* access should re-export from this file rather than duplicating the
|
|
17
|
+
* low-level glue.
|
|
18
|
+
*/
|
|
19
|
+
export { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js';
|
|
20
|
+
export { createScope, disposeScope, addDisposer } from './scope.js';
|
|
21
|
+
//# sourceMappingURL=internal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE5F,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA","sourcesContent":["/**\n * Internal primitives surface — exported for framework-adapter packages\n * (`@llui/vike`, `@llui/router`, `@llui/transitions`) that need to build\n * their own structural primitives on top of LLui's scope + render-context\n * machinery.\n *\n * **Not part of the public API.** App authors should not import from\n * `@llui/dom/internal`. The shapes here are free to change without a\n * major version bump — the stability contract applies only to the public\n * barrel at `@llui/dom`. Reach for this subpath when you're writing a\n * primitive like `pageSlot()` (from `@llui/vike`) that has to participate\n * in the scope tree, not when you're writing application views.\n *\n * Added in 0.0.16 to support `@llui/vike`'s persistent-layout feature.\n * Any future adapter-level primitive that needs render-context / scope\n * access should re-export from this file rather than duplicating the\n * low-level glue.\n */\n\nexport { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js'\nexport type { RenderContext } from './render-context.js'\nexport { createScope, disposeScope, addDisposer } from './scope.js'\n"]}
|
package/dist/mount.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComponentDef, AppHandle } from './types.js';
|
|
1
|
+
import type { ComponentDef, AppHandle, Scope } from './types.js';
|
|
2
2
|
declare global {
|
|
3
3
|
interface ImportMeta {
|
|
4
4
|
env?: {
|
|
@@ -8,7 +8,20 @@ declare global {
|
|
|
8
8
|
}
|
|
9
9
|
export interface MountOptions {
|
|
10
10
|
devTools?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Parent scope for the mounted component's rootScope. When provided,
|
|
13
|
+
* the rootScope is created as a child of this scope — context lookups
|
|
14
|
+
* from within the component walk up through the parent's scope tree,
|
|
15
|
+
* and disposing the parent scope cascades into this instance's scope.
|
|
16
|
+
* Used by `@llui/vike`'s persistent-layout machinery to mount a page
|
|
17
|
+
* as a true scope-tree child of its enclosing layout, so layout-
|
|
18
|
+
* provided contexts flow naturally into pages via `useContext`.
|
|
19
|
+
*
|
|
20
|
+
* When omitted (the default), the rootScope is detached — same as
|
|
21
|
+
* every `mountApp` call before persistent layouts existed.
|
|
22
|
+
*/
|
|
23
|
+
parentScope?: Scope;
|
|
11
24
|
}
|
|
12
|
-
export declare function mountApp<S, M, E>(container: HTMLElement, def: ComponentDef<S, M, E>, data?: unknown,
|
|
13
|
-
export declare function hydrateApp<S, M, E>(container: HTMLElement, def: ComponentDef<S, M, E>, serverState: S): AppHandle;
|
|
25
|
+
export declare function mountApp<S, M, E>(container: HTMLElement, def: ComponentDef<S, M, E>, data?: unknown, options?: MountOptions): AppHandle;
|
|
26
|
+
export declare function hydrateApp<S, M, E>(container: HTMLElement, def: ComponentDef<S, M, E>, serverState: S, options?: MountOptions): AppHandle;
|
|
14
27
|
//# sourceMappingURL=mount.d.ts.map
|
package/dist/mount.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAUhE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB,GAAG,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KACxB;CACF;AAsBD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,KAAK,CAAA;CACpB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC9B,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,CAAC,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CAqFX;AA6DD,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAChC,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC1B,WAAW,EAAE,CAAC,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,SAAS,CA6DX"}
|
package/dist/mount.js
CHANGED
|
@@ -19,15 +19,18 @@ let devToolsInstall = null;
|
|
|
19
19
|
export function _setDevToolsInstall(fn) {
|
|
20
20
|
devToolsInstall = fn;
|
|
21
21
|
}
|
|
22
|
-
export function mountApp(container, def, data,
|
|
22
|
+
export function mountApp(container, def, data, options) {
|
|
23
23
|
// HMR: if this component is already mounted (module re-execution
|
|
24
24
|
// during hot update), swap the definition instead of creating a new instance.
|
|
25
|
-
|
|
25
|
+
// HMR swap bypasses parentScope — HMR re-mounts the outermost app handle,
|
|
26
|
+
// which in a layout setup means the layout re-mounts at the root and the
|
|
27
|
+
// rest of the chain is re-established via the normal mount path.
|
|
28
|
+
if (hmrModule && def.name && !options?.parentScope) {
|
|
26
29
|
const swapped = hmrModule.replaceComponent(def.name, def);
|
|
27
30
|
if (swapped)
|
|
28
31
|
return swapped;
|
|
29
32
|
}
|
|
30
|
-
const inst = createComponentInstance(def, data);
|
|
33
|
+
const inst = createComponentInstance(def, data, options?.parentScope ?? null);
|
|
31
34
|
// Dev-only: auto-install devtools if enabled via '@llui/dom/devtools' import
|
|
32
35
|
if (devToolsInstall)
|
|
33
36
|
devToolsInstall(inst);
|
|
@@ -91,6 +94,11 @@ export function mountApp(container, def, data, _options) {
|
|
|
91
94
|
return;
|
|
92
95
|
flushInstance(inst);
|
|
93
96
|
},
|
|
97
|
+
send(msg) {
|
|
98
|
+
if (disposed)
|
|
99
|
+
return;
|
|
100
|
+
inst.send(msg);
|
|
101
|
+
},
|
|
94
102
|
};
|
|
95
103
|
}
|
|
96
104
|
// Walks an object graph looking for non-JSON-serializable values. Returns the
|
|
@@ -153,7 +161,7 @@ function dispatchInitialEffects(inst) {
|
|
|
153
161
|
}
|
|
154
162
|
inst.initialEffects = [];
|
|
155
163
|
}
|
|
156
|
-
export function hydrateApp(container, def, serverState) {
|
|
164
|
+
export function hydrateApp(container, def, serverState, options) {
|
|
157
165
|
// Run the original init once to capture its effects. The state it
|
|
158
166
|
// returns is discarded — we use `serverState` (what the server
|
|
159
167
|
// rendered with) instead. The effects are preserved and dispatched
|
|
@@ -167,7 +175,7 @@ export function hydrateApp(container, def, serverState) {
|
|
|
167
175
|
...def,
|
|
168
176
|
init: () => [serverState, originalEffects],
|
|
169
177
|
};
|
|
170
|
-
const inst = createComponentInstance(hydrateDef);
|
|
178
|
+
const inst = createComponentInstance(hydrateDef, undefined, options?.parentScope ?? null);
|
|
171
179
|
// Build the component DOM and swap atomically with server HTML.
|
|
172
180
|
// Server HTML remains visible until JS finishes — no flash.
|
|
173
181
|
// onMount callbacks are collected in a queue and flushed synchronously
|
|
@@ -203,6 +211,11 @@ export function hydrateApp(container, def, serverState) {
|
|
|
203
211
|
return;
|
|
204
212
|
flushInstance(inst);
|
|
205
213
|
},
|
|
214
|
+
send(msg) {
|
|
215
|
+
if (disposed)
|
|
216
|
+
return;
|
|
217
|
+
inst.send(msg);
|
|
218
|
+
},
|
|
206
219
|
};
|
|
207
220
|
}
|
|
208
221
|
//# sourceMappingURL=mount.js.map
|
package/dist/mount.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AASzF,mEAAmE;AACnE,0EAA0E;AAE1E,IAAI,SAAS,GAAkC,IAAI,CAAA;AAEnD,sDAAsD;AACtD,MAAM,UAAU,aAAa,CAAC,CAAyB;IACrD,SAAS,GAAG,CAAC,CAAA;AACf,CAAC;AAED,mEAAmE;AACnE,oFAAoF;AAEpF,IAAI,eAAe,GAAoC,IAAI,CAAA;AAE3D,gEAAgE;AAChE,MAAM,UAAU,mBAAmB,CAAC,EAAmC;IACrE,eAAe,GAAG,EAAE,CAAA;AACtB,CAAC;AAMD,MAAM,UAAU,QAAQ,CACtB,SAAsB,EACtB,GAA0B,EAC1B,IAAc,EACd,QAAuB;IAEvB,iEAAiE;IACjE,8EAA8E;IAC9E,IAAI,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QACzD,IAAI,OAAO;YAAE,OAAO,OAAO,CAAA;IAC7B,CAAC;IAED,MAAM,IAAI,GAAG,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAE/C,6EAA6E;IAC7E,IAAI,eAAe;QAAE,eAAe,CAAC,IAAI,CAAC,CAAA;IAE1C,oEAAoE;IACpE,oFAAoF;IACpF,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChD,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACV,WAAW,GAAG,CAAC,IAAI,yDAAyD,QAAQ,CAAC,IAAI,IAAI,EAC7F,QAAQ,CAAC,KAAK,EACd,yEAAyE;gBACvE,wEAAwE;gBACxE,2FAA2F,CAC9F,CAAA;QACH,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,sEAAsE;IACtE,oEAAoE;IACpE,yDAAyD;IACzD,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAAA;IACtE,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACjC,gBAAgB,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAA8B,EAAE,CAAC,CAAA;IACnF,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IACnD,kBAAkB,EAAE,CAAA;IACpB,eAAe,CAAC,IAAI,CAAC,CAAA;IACrB,aAAa,CAAC,cAAc,CAAC,CAAA;IAE7B,wEAAwE;IACxE,yEAAyE;IACzE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAA;QAC9C,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QAChD,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;IAC7B,CAAC;SAAM,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAA;IAClC,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,iEAAiE;IACjE,8BAA8B;IAC9B,eAAe,CAAC,YAAY,CAAC,CAAA;IAE7B,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC1B,SAAS,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;IACrD,CAAC;IACD,sBAAsB,CAAC,IAAI,CAAC,CAAA;IAC5B,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,OAAO;QACL,OAAO;YACL,IAAI,QAAQ;gBAAE,OAAM;YACpB,QAAQ,GAAG,IAAI,CAAA;YACf,IAAI,SAAS,IAAI,GAAG,CAAC,IAAI;gBAAE,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACrE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;YAC5B,kBAAkB,CAAC,IAAI,CAAC,CAAA;YACxB,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC5B,SAAS,CAAC,WAAW,GAAG,EAAE,CAAA;QAC5B,CAAC;QACD,KAAK;YACH,IAAI,QAAQ;gBAAE,OAAM;YACpB,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;KACF,CAAA;AACH,CAAC;AAED,8EAA8E;AAC9E,8EAA8E;AAC9E,kDAAkD;AAClD,SAAS,mBAAmB,CAC1B,CAAU,EACV,IAAI,GAAG,OAAO,EACd,KAAK,GAAG,CAAC,EACT,OAAO,IAAI,OAAO,EAAU;IAE5B,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAC1B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAC9C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAA;IAClB,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACpE,IAAI,CAAC,KAAK,UAAU;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAC/C,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAC/D,IAAI,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAC/B,MAAM,GAAG,GAAG,CAAW,CAAA;IACvB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACb,IAAI,GAAG,YAAY,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IACpE,IAAI,GAAG,YAAY,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAClE,IAAI,GAAG,YAAY,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAClE,IAAI,GAAG,YAAY,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IACxE,IAAI,GAAG,YAAY,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IAC1E,gFAAgF;IAChF,8BAA8B;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;IACxC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC,SAAS,EAAE,CAAC;QAC9E,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,KAAK,KAAK,EAAE,WAAW,EAAE,IAAI,IAAI,gBAAgB,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IACxF,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAA;YACrE,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,mBAAmB,CAC1B,GAA+B,CAAC,CAAC,CAAC,EACnC,GAAG,IAAI,IAAI,CAAC,EAAE,EACd,KAAK,GAAG,CAAC,EACT,IAAI,CACL,CAAA;QACD,IAAI,CAAC;YAAE,OAAO,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAyD;IAEzD,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ;QAAE,OAAM;IAClE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACrE,CAAC;IACD,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,SAAsB,EACtB,GAA0B,EAC1B,WAAc;IAEd,kEAAkE;IAClE,+DAA+D;IAC/D,mEAAmE;IACnE,mEAAmE;IACnE,oEAAoE;IACpE,iEAAiE;IACjE,oEAAoE;IACpE,mDAAmD;IACnD,MAAM,CAAC,EAAE,eAAe,CAAC,GAAI,GAAG,CAAC,IAAoC,CAAC,SAAS,CAAC,CAAA;IAEhF,MAAM,UAAU,GAA0B;QACxC,GAAG,GAAG;QACN,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC;KAC3C,CAAA;IAED,MAAM,IAAI,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAA;IAEhD,gEAAgE;IAChE,4DAA4D;IAC5D,uEAAuE;IACvE,gDAAgD;IAChD,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAAA;IACtE,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IACjC,gBAAgB,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAA8B,EAAE,CAAC,CAAA;IACnF,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,CAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1D,kBAAkB,EAAE,CAAA;IACpB,eAAe,CAAC,IAAI,CAAC,CAAA;IACrB,aAAa,CAAC,cAAc,CAAC,CAAA;IAE7B,sEAAsE;IACtE,SAAS,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC,CAAA;IAEnC,sEAAsE;IACtE,eAAe,CAAC,YAAY,CAAC,CAAA;IAE7B,kEAAkE;IAClE,qDAAqD;IACrD,sBAAsB,CAAC,IAAI,CAAC,CAAA;IAE5B,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,OAAO;QACL,OAAO;YACL,IAAI,QAAQ;gBAAE,OAAM;YACpB,QAAQ,GAAG,IAAI,CAAA;YACf,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;YAC5B,kBAAkB,CAAC,IAAI,CAAC,CAAA;YACxB,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC5B,SAAS,CAAC,WAAW,GAAG,EAAE,CAAA;QAC5B,CAAC;QACD,KAAK;YACH,IAAI,QAAQ;gBAAE,OAAM;YACpB,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport { createComponentInstance, flushInstance } from './update-loop.js'\nimport { disposeScope } from './scope.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { registerInstance, unregisterInstance } from './runtime.js'\nimport { createView } from './view-helpers.js'\nimport { pushMountQueue, popMountQueue, flushMountQueue } from './primitives/on-mount.js'\n\n// Vite injects import.meta.env.DEV — declare the shape for TypeScript\ndeclare global {\n interface ImportMeta {\n env?: { DEV?: boolean }\n }\n}\n\n// ── HMR (dev only) ──────────────────────────────────────────────\n// Set by enableHmr() from '@llui/dom/hmr' — never imported in production.\n\nlet hmrModule: typeof import('./hmr') | null = null\n\n/** @internal Called by enableHmr in the hmr module */\nexport function _setHmrModule(m: typeof import('./hmr')): void {\n hmrModule = m\n}\n\n// ── DevTools auto-install (dev only) ────────────────────────────\n// Set by enableDevTools() from '@llui/dom/devtools' — never imported in production.\n\nlet devToolsInstall: ((inst: object) => void) | null = null\n\n/** @internal Called by enableDevTools in the devtools module */\nexport function _setDevToolsInstall(fn: ((inst: object) => void) | null): void {\n devToolsInstall = fn\n}\n\nexport interface MountOptions {\n devTools?: boolean\n}\n\nexport function mountApp<S, M, E>(\n container: HTMLElement,\n def: ComponentDef<S, M, E>,\n data?: unknown,\n _options?: MountOptions,\n): AppHandle {\n // HMR: if this component is already mounted (module re-execution\n // during hot update), swap the definition instead of creating a new instance.\n if (hmrModule && def.name) {\n const swapped = hmrModule.replaceComponent(def.name, def)\n if (swapped) return swapped\n }\n\n const inst = createComponentInstance(def, data)\n\n // Dev-only: auto-install devtools if enabled via '@llui/dom/devtools' import\n if (devToolsInstall) devToolsInstall(inst)\n\n // Dev-only: warn if initial state contains non-serializable values.\n // Silent bug-bomb: Date/Map/Set/class instances break SSR, hydration, replay tools.\n if (import.meta.env?.DEV) {\n const offender = findNonSerializable(inst.state)\n if (offender) {\n console.warn(\n `[LLui] <${def.name}> initial state contains a non-serializable value at \"${offender.path}\":`,\n offender.value,\n '\\nState must be plain JSON (no Date/Map/Set/class instances/functions).' +\n '\\nThis will break SSR hydration, state replay, and devtools snapshots.' +\n '\\nhint: Convert to a serializable representation (e.g., Date → ISO string, Map → Record).',\n )\n }\n }\n\n // Run view() within a render context so primitives can register bindings.\n // Also collect onMount callbacks in a queue we'll flush synchronously\n // after node insertion — prevents the race where a user event fires\n // between mount and the queueMicrotask callback running.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({ ...inst, container, send: inst.send as (msg: unknown) => void })\n const nodes = def.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Batch-insert via DocumentFragment — one layout-invalidating operation\n // instead of N individual appendChild calls on a live container element.\n if (nodes.length > 1) {\n const frag = document.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n container.appendChild(frag)\n } else if (nodes.length === 1) {\n container.appendChild(nodes[0]!)\n }\n\n // Flush onMount callbacks SYNCHRONOUSLY now that the DOM is in place.\n // Any listeners they attach are ready before this function returns,\n // so a synchronous dispatchEvent in the caller's next line fires\n // against a fully-wired tree.\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForHmr(def.name, inst, container)\n }\n dispatchInitialEffects(inst)\n let disposed = false\n\n return {\n dispose() {\n if (disposed) return\n disposed = true\n if (hmrModule && def.name) hmrModule.unregisterForHmr(def.name, inst)\n inst.abortController.abort()\n unregisterInstance(inst)\n disposeScope(inst.rootScope)\n container.textContent = ''\n },\n flush() {\n if (disposed) return\n flushInstance(inst)\n },\n }\n}\n\n// Walks an object graph looking for non-JSON-serializable values. Returns the\n// first offender found (depth-first), or null if everything is fine. Stops at\n// depth 6 to bound runtime cost for large states.\nfunction findNonSerializable(\n v: unknown,\n path = 'state',\n depth = 0,\n seen = new WeakSet<object>(),\n): { path: string; value: unknown } | null {\n if (depth > 6) return null\n if (v === null || v === undefined) return null\n const t = typeof v\n if (t === 'string' || t === 'number' || t === 'boolean') return null\n if (t === 'function') return { path, value: v }\n if (t === 'symbol' || t === 'bigint') return { path, value: v }\n if (t !== 'object') return null\n const obj = v as object\n if (seen.has(obj)) return null\n seen.add(obj)\n if (obj instanceof Date) return { path: `${path} (Date)`, value: v }\n if (obj instanceof Map) return { path: `${path} (Map)`, value: v }\n if (obj instanceof Set) return { path: `${path} (Set)`, value: v }\n if (obj instanceof RegExp) return { path: `${path} (RegExp)`, value: v }\n if (obj instanceof Promise) return { path: `${path} (Promise)`, value: v }\n // Plain objects/arrays have Object.prototype / Array.prototype. Class instances\n // have a different prototype.\n const proto = Object.getPrototypeOf(obj)\n if (proto !== null && proto !== Object.prototype && proto !== Array.prototype) {\n return { path: `${path} (${proto?.constructor?.name ?? 'class instance'})`, value: v }\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const r = findNonSerializable(v[i], `${path}[${i}]`, depth + 1, seen)\n if (r) return r\n }\n return null\n }\n for (const k of Object.keys(obj)) {\n const r = findNonSerializable(\n (obj as Record<string, unknown>)[k],\n `${path}.${k}`,\n depth + 1,\n seen,\n )\n if (r) return r\n }\n return null\n}\n\nfunction dispatchInitialEffects<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n): void {\n if (inst.initialEffects.length === 0 || !inst.def.onEffect) return\n for (const effect of inst.initialEffects) {\n inst.def.onEffect({ effect, send: inst.send, signal: inst.signal })\n }\n inst.initialEffects = []\n}\n\nexport function hydrateApp<S, M, E>(\n container: HTMLElement,\n def: ComponentDef<S, M, E>,\n serverState: S,\n): AppHandle {\n // Run the original init once to capture its effects. The state it\n // returns is discarded — we use `serverState` (what the server\n // rendered with) instead. The effects are preserved and dispatched\n // after the DOM is in place, so components that rely on \"load data\n // or wire subscriptions on mount\" behave consistently between fresh\n // mount and SSR+hydrate. If the original init has already-loaded\n // data for the hydration case, gate the effect emission inside init\n // itself (e.g. based on a `loaded` flag in state).\n const [, originalEffects] = (def.init as (data: unknown) => [S, E[]])(undefined)\n\n const hydrateDef: ComponentDef<S, M, E> = {\n ...def,\n init: () => [serverState, originalEffects],\n }\n\n const inst = createComponentInstance(hydrateDef)\n\n // Build the component DOM and swap atomically with server HTML.\n // Server HTML remains visible until JS finishes — no flash.\n // onMount callbacks are collected in a queue and flushed synchronously\n // after the swap, matching mountApp's ordering.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({ ...inst, container, send: inst.send as (msg: unknown) => void })\n const nodes = hydrateDef.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Atomic swap — replaces server HTML with client DOM in one operation\n container.replaceChildren(...nodes)\n\n // Flush onMount callbacks synchronously now that the DOM is in place.\n flushMountQueue(onMountQueue)\n\n // Fire the original init's effects post-swap, matching mountApp's\n // lifecycle. Previously these were silently dropped.\n dispatchInitialEffects(inst)\n\n registerInstance(inst)\n let disposed = false\n\n return {\n dispose() {\n if (disposed) return\n disposed = true\n inst.abortController.abort()\n unregisterInstance(inst)\n disposeScope(inst.rootScope)\n container.textContent = ''\n },\n flush() {\n if (disposed) return\n flushInstance(inst)\n },\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle, Scope } from './types.js'\nimport { createComponentInstance, flushInstance } from './update-loop.js'\nimport { disposeScope } from './scope.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { registerInstance, unregisterInstance } from './runtime.js'\nimport { createView } from './view-helpers.js'\nimport { pushMountQueue, popMountQueue, flushMountQueue } from './primitives/on-mount.js'\n\n// Vite injects import.meta.env.DEV — declare the shape for TypeScript\ndeclare global {\n interface ImportMeta {\n env?: { DEV?: boolean }\n }\n}\n\n// ── HMR (dev only) ──────────────────────────────────────────────\n// Set by enableHmr() from '@llui/dom/hmr' — never imported in production.\n\nlet hmrModule: typeof import('./hmr') | null = null\n\n/** @internal Called by enableHmr in the hmr module */\nexport function _setHmrModule(m: typeof import('./hmr')): void {\n hmrModule = m\n}\n\n// ── DevTools auto-install (dev only) ────────────────────────────\n// Set by enableDevTools() from '@llui/dom/devtools' — never imported in production.\n\nlet devToolsInstall: ((inst: object) => void) | null = null\n\n/** @internal Called by enableDevTools in the devtools module */\nexport function _setDevToolsInstall(fn: ((inst: object) => void) | null): void {\n devToolsInstall = fn\n}\n\nexport interface MountOptions {\n devTools?: boolean\n /**\n * Parent scope for the mounted component's rootScope. When provided,\n * the rootScope is created as a child of this scope — context lookups\n * from within the component walk up through the parent's scope tree,\n * and disposing the parent scope cascades into this instance's scope.\n * Used by `@llui/vike`'s persistent-layout machinery to mount a page\n * as a true scope-tree child of its enclosing layout, so layout-\n * provided contexts flow naturally into pages via `useContext`.\n *\n * When omitted (the default), the rootScope is detached — same as\n * every `mountApp` call before persistent layouts existed.\n */\n parentScope?: Scope\n}\n\nexport function mountApp<S, M, E>(\n container: HTMLElement,\n def: ComponentDef<S, M, E>,\n data?: unknown,\n options?: MountOptions,\n): AppHandle {\n // HMR: if this component is already mounted (module re-execution\n // during hot update), swap the definition instead of creating a new instance.\n // HMR swap bypasses parentScope — HMR re-mounts the outermost app handle,\n // which in a layout setup means the layout re-mounts at the root and the\n // rest of the chain is re-established via the normal mount path.\n if (hmrModule && def.name && !options?.parentScope) {\n const swapped = hmrModule.replaceComponent(def.name, def)\n if (swapped) return swapped\n }\n\n const inst = createComponentInstance(def, data, options?.parentScope ?? null)\n\n // Dev-only: auto-install devtools if enabled via '@llui/dom/devtools' import\n if (devToolsInstall) devToolsInstall(inst)\n\n // Dev-only: warn if initial state contains non-serializable values.\n // Silent bug-bomb: Date/Map/Set/class instances break SSR, hydration, replay tools.\n if (import.meta.env?.DEV) {\n const offender = findNonSerializable(inst.state)\n if (offender) {\n console.warn(\n `[LLui] <${def.name}> initial state contains a non-serializable value at \"${offender.path}\":`,\n offender.value,\n '\\nState must be plain JSON (no Date/Map/Set/class instances/functions).' +\n '\\nThis will break SSR hydration, state replay, and devtools snapshots.' +\n '\\nhint: Convert to a serializable representation (e.g., Date → ISO string, Map → Record).',\n )\n }\n }\n\n // Run view() within a render context so primitives can register bindings.\n // Also collect onMount callbacks in a queue we'll flush synchronously\n // after node insertion — prevents the race where a user event fires\n // between mount and the queueMicrotask callback running.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({ ...inst, container, send: inst.send as (msg: unknown) => void })\n const nodes = def.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Batch-insert via DocumentFragment — one layout-invalidating operation\n // instead of N individual appendChild calls on a live container element.\n if (nodes.length > 1) {\n const frag = document.createDocumentFragment()\n for (const node of nodes) frag.appendChild(node)\n container.appendChild(frag)\n } else if (nodes.length === 1) {\n container.appendChild(nodes[0]!)\n }\n\n // Flush onMount callbacks SYNCHRONOUSLY now that the DOM is in place.\n // Any listeners they attach are ready before this function returns,\n // so a synchronous dispatchEvent in the caller's next line fires\n // against a fully-wired tree.\n flushMountQueue(onMountQueue)\n\n registerInstance(inst)\n if (hmrModule && def.name) {\n hmrModule.registerForHmr(def.name, inst, container)\n }\n dispatchInitialEffects(inst)\n let disposed = false\n\n return {\n dispose() {\n if (disposed) return\n disposed = true\n if (hmrModule && def.name) hmrModule.unregisterForHmr(def.name, inst)\n inst.abortController.abort()\n unregisterInstance(inst)\n disposeScope(inst.rootScope)\n container.textContent = ''\n },\n flush() {\n if (disposed) return\n flushInstance(inst)\n },\n send(msg: unknown) {\n if (disposed) return\n ;(inst.send as (m: unknown) => void)(msg)\n },\n }\n}\n\n// Walks an object graph looking for non-JSON-serializable values. Returns the\n// first offender found (depth-first), or null if everything is fine. Stops at\n// depth 6 to bound runtime cost for large states.\nfunction findNonSerializable(\n v: unknown,\n path = 'state',\n depth = 0,\n seen = new WeakSet<object>(),\n): { path: string; value: unknown } | null {\n if (depth > 6) return null\n if (v === null || v === undefined) return null\n const t = typeof v\n if (t === 'string' || t === 'number' || t === 'boolean') return null\n if (t === 'function') return { path, value: v }\n if (t === 'symbol' || t === 'bigint') return { path, value: v }\n if (t !== 'object') return null\n const obj = v as object\n if (seen.has(obj)) return null\n seen.add(obj)\n if (obj instanceof Date) return { path: `${path} (Date)`, value: v }\n if (obj instanceof Map) return { path: `${path} (Map)`, value: v }\n if (obj instanceof Set) return { path: `${path} (Set)`, value: v }\n if (obj instanceof RegExp) return { path: `${path} (RegExp)`, value: v }\n if (obj instanceof Promise) return { path: `${path} (Promise)`, value: v }\n // Plain objects/arrays have Object.prototype / Array.prototype. Class instances\n // have a different prototype.\n const proto = Object.getPrototypeOf(obj)\n if (proto !== null && proto !== Object.prototype && proto !== Array.prototype) {\n return { path: `${path} (${proto?.constructor?.name ?? 'class instance'})`, value: v }\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const r = findNonSerializable(v[i], `${path}[${i}]`, depth + 1, seen)\n if (r) return r\n }\n return null\n }\n for (const k of Object.keys(obj)) {\n const r = findNonSerializable(\n (obj as Record<string, unknown>)[k],\n `${path}.${k}`,\n depth + 1,\n seen,\n )\n if (r) return r\n }\n return null\n}\n\nfunction dispatchInitialEffects<S, M, E>(\n inst: ReturnType<typeof createComponentInstance<S, M, E>>,\n): void {\n if (inst.initialEffects.length === 0 || !inst.def.onEffect) return\n for (const effect of inst.initialEffects) {\n inst.def.onEffect({ effect, send: inst.send, signal: inst.signal })\n }\n inst.initialEffects = []\n}\n\nexport function hydrateApp<S, M, E>(\n container: HTMLElement,\n def: ComponentDef<S, M, E>,\n serverState: S,\n options?: MountOptions,\n): AppHandle {\n // Run the original init once to capture its effects. The state it\n // returns is discarded — we use `serverState` (what the server\n // rendered with) instead. The effects are preserved and dispatched\n // after the DOM is in place, so components that rely on \"load data\n // or wire subscriptions on mount\" behave consistently between fresh\n // mount and SSR+hydrate. If the original init has already-loaded\n // data for the hydration case, gate the effect emission inside init\n // itself (e.g. based on a `loaded` flag in state).\n const [, originalEffects] = (def.init as (data: unknown) => [S, E[]])(undefined)\n\n const hydrateDef: ComponentDef<S, M, E> = {\n ...def,\n init: () => [serverState, originalEffects],\n }\n\n const inst = createComponentInstance(hydrateDef, undefined, options?.parentScope ?? null)\n\n // Build the component DOM and swap atomically with server HTML.\n // Server HTML remains visible until JS finishes — no flash.\n // onMount callbacks are collected in a queue and flushed synchronously\n // after the swap, matching mountApp's ordering.\n const { queue: onMountQueue, prev: prevMountQueue } = pushMountQueue()\n setFlatBindings(inst.allBindings)\n setRenderContext({ ...inst, container, send: inst.send as (msg: unknown) => void })\n const nodes = hydrateDef.view(createView<S, M>(inst.send))\n clearRenderContext()\n setFlatBindings(null)\n popMountQueue(prevMountQueue)\n\n // Atomic swap — replaces server HTML with client DOM in one operation\n container.replaceChildren(...nodes)\n\n // Flush onMount callbacks synchronously now that the DOM is in place.\n flushMountQueue(onMountQueue)\n\n // Fire the original init's effects post-swap, matching mountApp's\n // lifecycle. Previously these were silently dropped.\n dispatchInitialEffects(inst)\n\n registerInstance(inst)\n let disposed = false\n\n return {\n dispose() {\n if (disposed) return\n disposed = true\n inst.abortController.abort()\n unregisterInstance(inst)\n disposeScope(inst.rootScope)\n container.textContent = ''\n },\n flush() {\n if (disposed) return\n flushInstance(inst)\n },\n send(msg: unknown) {\n if (disposed) return\n ;(inst.send as (m: unknown) => void)(msg)\n },\n }\n}\n"]}
|
|
@@ -43,4 +43,49 @@ export declare function provide<S, T>(ctx: Context<T>, accessor: (s: S) => T, ch
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
export declare function useContext<S, T>(ctx: Context<T>): (s: S) => T;
|
|
46
|
+
/**
|
|
47
|
+
* Provide a state-independent value to every descendant. Companion to
|
|
48
|
+
* `provide()` for the common case of publishing a stable dispatcher
|
|
49
|
+
* bag, callback record, or DI container — anything that doesn't depend
|
|
50
|
+
* on the parent's state.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* provideValue(ToastContext, { show: (m) => send({ type: 'toast', m }) }, () => [
|
|
54
|
+
* main([pageSlot()]),
|
|
55
|
+
* ])
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* Equivalent to `provide(ctx, () => value, children)`, but exists so
|
|
59
|
+
* the call site reads as "provide this value" rather than "provide an
|
|
60
|
+
* accessor that ignores its state argument and returns a value." Pair
|
|
61
|
+
* with `useContextValue` for symmetric ergonomics on the consumer side.
|
|
62
|
+
*
|
|
63
|
+
* Internally still uses the accessor mechanism: the value is wrapped
|
|
64
|
+
* in a constant lambda. Consumers that read via the reactive
|
|
65
|
+
* `useContext` form will get an `(s) => T` whose accessor ignores `s`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function provideValue<T>(ctx: Context<T>, value: T, children: () => Node[]): Node[];
|
|
68
|
+
/**
|
|
69
|
+
* Read a state-independent value from the nearest provider. Companion
|
|
70
|
+
* to `useContext()` for the common case of consuming a stable
|
|
71
|
+
* dispatcher bag, callback record, or DI container.
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* const toast = useContextValue(ToastContext)
|
|
75
|
+
* button({ onClick: () => toast.show('Saved') }, [text('Save')])
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* Equivalent to calling the accessor returned by `useContext` with
|
|
79
|
+
* `undefined`, but reads as a single function call instead of a
|
|
80
|
+
* three-step "look up the accessor, ignore the state arg, get the
|
|
81
|
+
* value" dance.
|
|
82
|
+
*
|
|
83
|
+
* Use this only with values provided via `provideValue` (or via
|
|
84
|
+
* `provide` with an accessor that ignores its state argument). Calling
|
|
85
|
+
* `useContextValue` against a context whose accessor reads from state
|
|
86
|
+
* will resolve the accessor against `undefined` and likely throw or
|
|
87
|
+
* return wrong data — there's no way for the runtime to detect the
|
|
88
|
+
* mismatch, so honor the contract at the API surface.
|
|
89
|
+
*/
|
|
90
|
+
export declare function useContextValue<T>(ctx: Context<T>): T;
|
|
46
91
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/primitives/context.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAE5E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAC1B,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACf,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACrB,QAAQ,EAAE,MAAM,IAAI,EAAE,GACrB,IAAI,EAAE,CAoBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CA0B7D"}
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/primitives/context.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAE5E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAC1B,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACf,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EACrB,QAAQ,EAAE,MAAM,IAAI,EAAE,GACrB,IAAI,EAAE,CAoBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CA0B7D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,GAAG,IAAI,EAAE,CAEzF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAKrD"}
|
|
@@ -93,4 +93,56 @@ export function useContext(ctx) {
|
|
|
93
93
|
`Wrap a parent element with provide(${label}, accessor, () => [...]) ` +
|
|
94
94
|
`or pass a default to createContext().`);
|
|
95
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Provide a state-independent value to every descendant. Companion to
|
|
98
|
+
* `provide()` for the common case of publishing a stable dispatcher
|
|
99
|
+
* bag, callback record, or DI container — anything that doesn't depend
|
|
100
|
+
* on the parent's state.
|
|
101
|
+
*
|
|
102
|
+
* ```ts
|
|
103
|
+
* provideValue(ToastContext, { show: (m) => send({ type: 'toast', m }) }, () => [
|
|
104
|
+
* main([pageSlot()]),
|
|
105
|
+
* ])
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* Equivalent to `provide(ctx, () => value, children)`, but exists so
|
|
109
|
+
* the call site reads as "provide this value" rather than "provide an
|
|
110
|
+
* accessor that ignores its state argument and returns a value." Pair
|
|
111
|
+
* with `useContextValue` for symmetric ergonomics on the consumer side.
|
|
112
|
+
*
|
|
113
|
+
* Internally still uses the accessor mechanism: the value is wrapped
|
|
114
|
+
* in a constant lambda. Consumers that read via the reactive
|
|
115
|
+
* `useContext` form will get an `(s) => T` whose accessor ignores `s`.
|
|
116
|
+
*/
|
|
117
|
+
export function provideValue(ctx, value, children) {
|
|
118
|
+
return provide(ctx, () => value, children);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Read a state-independent value from the nearest provider. Companion
|
|
122
|
+
* to `useContext()` for the common case of consuming a stable
|
|
123
|
+
* dispatcher bag, callback record, or DI container.
|
|
124
|
+
*
|
|
125
|
+
* ```ts
|
|
126
|
+
* const toast = useContextValue(ToastContext)
|
|
127
|
+
* button({ onClick: () => toast.show('Saved') }, [text('Save')])
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* Equivalent to calling the accessor returned by `useContext` with
|
|
131
|
+
* `undefined`, but reads as a single function call instead of a
|
|
132
|
+
* three-step "look up the accessor, ignore the state arg, get the
|
|
133
|
+
* value" dance.
|
|
134
|
+
*
|
|
135
|
+
* Use this only with values provided via `provideValue` (or via
|
|
136
|
+
* `provide` with an accessor that ignores its state argument). Calling
|
|
137
|
+
* `useContextValue` against a context whose accessor reads from state
|
|
138
|
+
* will resolve the accessor against `undefined` and likely throw or
|
|
139
|
+
* return wrong data — there's no way for the runtime to detect the
|
|
140
|
+
* mismatch, so honor the contract at the API surface.
|
|
141
|
+
*/
|
|
142
|
+
export function useContextValue(ctx) {
|
|
143
|
+
const accessor = useContext(ctx);
|
|
144
|
+
// The contract above: the producer side promised this accessor
|
|
145
|
+
// doesn't read its state arg. Pass undefined.
|
|
146
|
+
return accessor(undefined);
|
|
147
|
+
}
|
|
96
148
|
//# sourceMappingURL=context.js.map
|