@elurjs/core 3.6.2 → 3.7.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/async.cjs +1 -1
- package/dist/lib/async.js +1 -1
- package/dist/lib/component.cjs +1 -2
- package/dist/lib/component.js +2 -66
- package/dist/lib/context.cjs +1 -1
- package/dist/lib/context.js +35 -23
- package/dist/lib/devtools.cjs +1 -1
- package/dist/lib/devtools.js +1 -1
- package/dist/lib/elur/async.cjs +1 -1
- package/dist/lib/elur/async.cjs.map +1 -1
- package/dist/lib/elur/async.js +1 -1
- package/dist/lib/elur/component.cjs +1 -2
- package/dist/lib/elur/component.d.cts +1 -17
- package/dist/lib/elur/component.d.ts +1 -17
- package/dist/lib/elur/component.js +2 -66
- package/dist/lib/elur/context.cjs +1 -1
- package/dist/lib/elur/context.cjs.map +1 -1
- package/dist/lib/elur/context.d.cts +5 -0
- package/dist/lib/elur/context.d.ts +5 -0
- package/dist/lib/elur/context.js +35 -23
- package/dist/lib/elur/context.js.map +1 -1
- package/dist/lib/elur/devtools.cjs +1 -1
- package/dist/lib/elur/devtools.cjs.map +1 -1
- package/dist/lib/elur/devtools.js +1 -1
- package/dist/lib/elur/form.cjs +1 -1
- package/dist/lib/elur/form.cjs.map +1 -1
- package/dist/lib/elur/form.js +1 -1
- package/dist/lib/elur/hydrate/index.cjs +1 -2
- package/dist/lib/elur/hydrate/index.d.cts +1 -13
- package/dist/lib/elur/hydrate/index.d.ts +1 -13
- package/dist/lib/elur/hydrate/index.js +2 -410
- package/dist/lib/elur/lifecycle.cjs +1 -1
- package/dist/lib/elur/lifecycle.cjs.map +1 -1
- package/dist/lib/elur/lifecycle.d.cts +27 -0
- package/dist/lib/elur/lifecycle.d.ts +27 -0
- package/dist/lib/elur/lifecycle.js +4 -0
- package/dist/lib/elur/lifecycle.js.map +1 -1
- package/dist/lib/elur/next/component.d.cts +281 -0
- package/dist/lib/elur/next/component.d.ts +281 -0
- package/dist/lib/elur/next/dom-write.d.cts +18 -0
- package/dist/lib/elur/next/dom-write.d.ts +18 -0
- package/dist/lib/elur/next/hydrate.d.cts +14 -0
- package/dist/lib/elur/next/hydrate.d.ts +14 -0
- package/dist/lib/elur/next/keyed-diff.d.cts +46 -0
- package/dist/lib/elur/next/keyed-diff.d.ts +46 -0
- package/dist/lib/elur/next/mount-helpers.d.cts +25 -0
- package/dist/lib/elur/next/mount-helpers.d.ts +25 -0
- package/dist/lib/elur/next/mount.d.cts +29 -0
- package/dist/lib/elur/next/mount.d.ts +29 -0
- package/dist/lib/elur/next/node-binding.d.cts +6 -0
- package/dist/lib/elur/next/node-binding.d.ts +6 -0
- package/dist/lib/elur/next/reactivity.d.cts +193 -0
- package/dist/lib/elur/next/reactivity.d.ts +193 -0
- package/dist/lib/elur/next-2/component.cjs +2 -0
- package/dist/lib/elur/next-2/component.cjs.map +1 -0
- package/dist/lib/elur/next-2/component.d.cts +283 -0
- package/dist/lib/elur/next-2/component.d.ts +283 -0
- package/dist/lib/elur/next-2/component.js +340 -0
- package/dist/lib/elur/next-2/component.js.map +1 -0
- package/dist/lib/elur/next-2/dom-write.cjs +2 -0
- package/dist/lib/elur/next-2/dom-write.cjs.map +1 -0
- package/dist/lib/elur/next-2/dom-write.d.cts +18 -0
- package/dist/lib/elur/next-2/dom-write.d.ts +18 -0
- package/dist/lib/elur/next-2/dom-write.js +31 -0
- package/dist/lib/elur/next-2/dom-write.js.map +1 -0
- package/dist/lib/elur/next-2/hydrate.cjs +2 -0
- package/dist/lib/elur/next-2/hydrate.cjs.map +1 -0
- package/dist/lib/elur/next-2/hydrate.d.cts +30 -0
- package/dist/lib/elur/next-2/hydrate.d.ts +30 -0
- package/dist/lib/elur/next-2/hydrate.js +449 -0
- package/dist/lib/elur/next-2/hydrate.js.map +1 -0
- package/dist/lib/elur/next-2/keyed-diff.cjs +2 -0
- package/dist/lib/elur/next-2/keyed-diff.cjs.map +1 -0
- package/dist/lib/elur/next-2/keyed-diff.d.cts +79 -0
- package/dist/lib/elur/next-2/keyed-diff.d.ts +79 -0
- package/dist/lib/elur/next-2/keyed-diff.js +208 -0
- package/dist/lib/elur/next-2/keyed-diff.js.map +1 -0
- package/dist/lib/elur/next-2/mount-helpers.cjs +2 -0
- package/dist/lib/elur/next-2/mount-helpers.cjs.map +1 -0
- package/dist/lib/elur/next-2/mount-helpers.d.cts +25 -0
- package/dist/lib/elur/next-2/mount-helpers.d.ts +25 -0
- package/dist/lib/elur/next-2/mount-helpers.js +87 -0
- package/dist/lib/elur/next-2/mount-helpers.js.map +1 -0
- package/dist/lib/elur/next-2/mount.cjs +2 -0
- package/dist/lib/elur/next-2/mount.cjs.map +1 -0
- package/dist/lib/elur/next-2/mount.d.cts +29 -0
- package/dist/lib/elur/next-2/mount.d.ts +29 -0
- package/dist/lib/elur/next-2/mount.js +34 -0
- package/dist/lib/elur/next-2/mount.js.map +1 -0
- package/dist/lib/elur/next-2/node-binding.cjs +2 -0
- package/dist/lib/elur/next-2/node-binding.cjs.map +1 -0
- package/dist/lib/elur/next-2/node-binding.d.cts +6 -0
- package/dist/lib/elur/next-2/node-binding.d.ts +6 -0
- package/dist/lib/elur/next-2/node-binding.js +130 -0
- package/dist/lib/elur/next-2/node-binding.js.map +1 -0
- package/dist/lib/elur/next-2/reactivity.cjs +2 -0
- package/dist/lib/elur/next-2/reactivity.cjs.map +1 -0
- package/dist/lib/elur/next-2/reactivity.d.cts +220 -0
- package/dist/lib/elur/next-2/reactivity.d.ts +220 -0
- package/dist/lib/elur/next-2/reactivity.js +614 -0
- package/dist/lib/elur/next-2/reactivity.js.map +1 -0
- package/dist/lib/elur/next-2/scheduler.cjs +2 -0
- package/dist/lib/elur/next-2/scheduler.cjs.map +1 -0
- package/dist/lib/elur/next-2/scheduler.d.cts +23 -0
- package/dist/lib/elur/next-2/scheduler.d.ts +23 -0
- package/dist/lib/elur/next-2/scheduler.js +26 -0
- package/dist/lib/elur/next-2/scheduler.js.map +1 -0
- package/dist/lib/elur/plugins.cjs +1 -1
- package/dist/lib/elur/plugins.cjs.map +1 -1
- package/dist/lib/elur/plugins.js +1 -1
- package/dist/lib/elur/reactivity.cjs +1 -2
- package/dist/lib/elur/reactivity.d.cts +1 -67
- package/dist/lib/elur/reactivity.d.ts +1 -67
- package/dist/lib/elur/reactivity.js +2 -218
- package/dist/lib/elur/router.cjs +1 -1
- package/dist/lib/elur/router.cjs.map +1 -1
- package/dist/lib/elur/router.js +1 -1
- package/dist/lib/elur/server/index.cjs +1 -1
- package/dist/lib/elur/server/index.cjs.map +1 -1
- package/dist/lib/elur/server/index.js +175 -107
- package/dist/lib/elur/server/index.js.map +1 -1
- package/dist/lib/elur/store.cjs +1 -1
- package/dist/lib/elur/store.cjs.map +1 -1
- package/dist/lib/elur/store.js +1 -1
- package/dist/lib/elur/template/bindings.cjs +1 -1
- package/dist/lib/elur/template/bindings.cjs.map +1 -1
- package/dist/lib/elur/template/bindings.js +98 -84
- package/dist/lib/elur/template/bindings.js.map +1 -1
- package/dist/lib/elur/template/dom-write.d.cts +1 -5
- package/dist/lib/elur/template/dom-write.d.ts +1 -5
- package/dist/lib/elur/template/error-boundary.cjs +1 -1
- package/dist/lib/elur/template/error-boundary.cjs.map +1 -1
- package/dist/lib/elur/template/error-boundary.js +56 -50
- package/dist/lib/elur/template/error-boundary.js.map +1 -1
- package/dist/lib/elur/template/html.cjs +1 -1
- package/dist/lib/elur/template/html.cjs.map +1 -1
- package/dist/lib/elur/template/html.js +40 -37
- package/dist/lib/elur/template/html.js.map +1 -1
- package/dist/lib/elur/template/index.cjs +1 -1
- package/dist/lib/elur/template/index.d.cts +2 -1
- package/dist/lib/elur/template/index.d.ts +2 -1
- package/dist/lib/elur/template/index.js +13 -12
- package/dist/lib/elur/template/keyed-diff.d.cts +1 -32
- package/dist/lib/elur/template/keyed-diff.d.ts +1 -32
- package/dist/lib/elur/template/keyed.cjs +1 -1
- package/dist/lib/elur/template/keyed.cjs.map +1 -1
- package/dist/lib/elur/template/keyed.d.cts +10 -2
- package/dist/lib/elur/template/keyed.d.ts +10 -2
- package/dist/lib/elur/template/keyed.js +12 -1
- package/dist/lib/elur/template/keyed.js.map +1 -1
- package/dist/lib/elur/template/mount-helpers.d.cts +1 -29
- package/dist/lib/elur/template/mount-helpers.d.ts +1 -29
- package/dist/lib/elur/template/node-binding.d.cts +1 -6
- package/dist/lib/elur/template/node-binding.d.ts +1 -6
- package/dist/lib/elur/template/portal.cjs +1 -1
- package/dist/lib/elur/template/portal.cjs.map +1 -1
- package/dist/lib/elur/template/portal.js +1 -1
- package/dist/lib/elur/template/transitions.cjs +1 -1
- package/dist/lib/elur/template/transitions.cjs.map +1 -1
- package/dist/lib/elur/template/transitions.js +2 -2
- package/dist/lib/elur/template/types.cjs +1 -1
- package/dist/lib/elur/template/types.cjs.map +1 -1
- package/dist/lib/elur/template/types.d.cts +55 -0
- package/dist/lib/elur/template/types.d.ts +55 -0
- package/dist/lib/elur/template/types.js +5 -1
- package/dist/lib/elur/template/types.js.map +1 -1
- package/dist/lib/elur.cjs +1 -1
- package/dist/lib/elur.js +2 -2
- package/dist/lib/form.cjs +1 -1
- package/dist/lib/form.js +1 -1
- package/dist/lib/hydrate.cjs +1 -2
- package/dist/lib/hydrate.js +2 -410
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.js +2 -2
- package/dist/lib/lifecycle.cjs +1 -1
- package/dist/lib/lifecycle.js +4 -0
- package/dist/lib/plugins.cjs +1 -1
- package/dist/lib/plugins.js +1 -1
- package/dist/lib/router.cjs +1 -1
- package/dist/lib/router.js +1 -1
- package/dist/lib/server.cjs +1 -1
- package/dist/lib/server.js +175 -107
- package/dist/lib/signals.cjs +1 -2
- package/dist/lib/signals.js +2 -218
- package/dist/lib/store.cjs +1 -1
- package/dist/lib/store.js +1 -1
- package/dist/lib/template.cjs +1 -1
- package/dist/lib/template.js +13 -12
- package/package.json +7 -9
- package/dist/lib/elur/component.cjs.map +0 -1
- package/dist/lib/elur/component.js.map +0 -1
- package/dist/lib/elur/hydrate/index.cjs.map +0 -1
- package/dist/lib/elur/hydrate/index.js.map +0 -1
- package/dist/lib/elur/reactivity.cjs.map +0 -1
- package/dist/lib/elur/reactivity.js.map +0 -1
- package/dist/lib/elur/template/dom-write.cjs +0 -2
- package/dist/lib/elur/template/dom-write.cjs.map +0 -1
- package/dist/lib/elur/template/dom-write.js +0 -16
- package/dist/lib/elur/template/dom-write.js.map +0 -1
- package/dist/lib/elur/template/keyed-diff.cjs +0 -2
- package/dist/lib/elur/template/keyed-diff.cjs.map +0 -1
- package/dist/lib/elur/template/keyed-diff.js +0 -100
- package/dist/lib/elur/template/keyed-diff.js.map +0 -1
- package/dist/lib/elur/template/mount-helpers.cjs +0 -2
- package/dist/lib/elur/template/mount-helpers.cjs.map +0 -1
- package/dist/lib/elur/template/mount-helpers.js +0 -132
- package/dist/lib/elur/template/mount-helpers.js.map +0 -1
- package/dist/lib/elur/template/node-binding.cjs +0 -2
- package/dist/lib/elur/template/node-binding.cjs.map +0 -1
- package/dist/lib/elur/template/node-binding.js +0 -95
- package/dist/lib/elur/template/node-binding.js.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* next/ — fork del mount() público (../component.ts) sobre el kernel.
|
|
3
|
+
*
|
|
4
|
+
* Diferencias vs el estable:
|
|
5
|
+
* - Componentes (clase o invocación funcional) montan via ComponentInstance:
|
|
6
|
+
* máquina de estados, owner propio, mount transaccional, onMount
|
|
7
|
+
* post-commit, unmount idempotente.
|
|
8
|
+
* - `options.router` se inyecta via `provides` en el frame de contexto de la
|
|
9
|
+
* instancia (A.12) en vez de un stack global.
|
|
10
|
+
* - Templates raíz montan bajo un Owner raíz — así los componentes internos
|
|
11
|
+
* tienen cadena de owners y provide/inject resuelve por instancias.
|
|
12
|
+
*/
|
|
13
|
+
import type { ElurTemplate, ElurMountHandle } from "../template/index.js";
|
|
14
|
+
import { type ElurComponent } from "../lifecycle.js";
|
|
15
|
+
import type { Router } from "../router.js";
|
|
16
|
+
import { type ComponentInvocation } from "./component.js";
|
|
17
|
+
export interface MountOptions {
|
|
18
|
+
router?: Router;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Mounts a ElurTemplate, ElurComponent o ComponentInvocation en el DOM.
|
|
22
|
+
*
|
|
23
|
+
* mount(Counter({ initial: 10 }), "#app"); // componente funcional
|
|
24
|
+
* mount(new Timer(), "#app"); // clase con lifecycle
|
|
25
|
+
* mount(html`…`, "#app"); // template
|
|
26
|
+
*
|
|
27
|
+
* @returns { unmount() } — mata el árbol reactivo completo y remueve el DOM.
|
|
28
|
+
*/
|
|
29
|
+
export declare function mount(component: ElurTemplate | ElurComponent | ComponentInvocation<any>, container: Element | string, options?: MountOptions): ElurMountHandle;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* next/ — fork del mount() público (../component.ts) sobre el kernel.
|
|
3
|
+
*
|
|
4
|
+
* Diferencias vs el estable:
|
|
5
|
+
* - Componentes (clase o invocación funcional) montan via ComponentInstance:
|
|
6
|
+
* máquina de estados, owner propio, mount transaccional, onMount
|
|
7
|
+
* post-commit, unmount idempotente.
|
|
8
|
+
* - `options.router` se inyecta via `provides` en el frame de contexto de la
|
|
9
|
+
* instancia (A.12) en vez de un stack global.
|
|
10
|
+
* - Templates raíz montan bajo un Owner raíz — así los componentes internos
|
|
11
|
+
* tienen cadena de owners y provide/inject resuelve por instancias.
|
|
12
|
+
*/
|
|
13
|
+
import type { ElurTemplate, ElurMountHandle } from "../template/index.js";
|
|
14
|
+
import { type ElurComponent } from "../lifecycle.js";
|
|
15
|
+
import type { Router } from "../router.js";
|
|
16
|
+
import { type ComponentInvocation } from "./component.js";
|
|
17
|
+
export interface MountOptions {
|
|
18
|
+
router?: Router;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Mounts a ElurTemplate, ElurComponent o ComponentInvocation en el DOM.
|
|
22
|
+
*
|
|
23
|
+
* mount(Counter({ initial: 10 }), "#app"); // componente funcional
|
|
24
|
+
* mount(new Timer(), "#app"); // clase con lifecycle
|
|
25
|
+
* mount(html`…`, "#app"); // template
|
|
26
|
+
*
|
|
27
|
+
* @returns { unmount() } — mata el árbol reactivo completo y remueve el DOM.
|
|
28
|
+
*/
|
|
29
|
+
export declare function mount(component: ElurTemplate | ElurComponent | ComponentInvocation<any>, container: Element | string, options?: MountOptions): ElurMountHandle;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Owner as e, getOwner as t, runWithOwner as n } from "./reactivity.js";
|
|
2
|
+
import { _debugComponentMountEnd as r, _debugComponentMountStart as i, _debugComponentUnmount as a, isElurComponent as o } from "../../lifecycle.js";
|
|
3
|
+
import { ComponentInstance as s, _registerContextOwner as c, isComponentInvocation as l } from "./component.js";
|
|
4
|
+
import { RouterKey as u, _debugRegisterRouter as d, _debugUnregisterRouter as f } from "../router-registry.js";
|
|
5
|
+
//#region src/elur/next-2/mount.ts
|
|
6
|
+
function p(e) {
|
|
7
|
+
let t = typeof e == "string" ? document.querySelector(e) : e;
|
|
8
|
+
if (!t) throw Error(`[elur] mount: container not found: ${e}`);
|
|
9
|
+
return t;
|
|
10
|
+
}
|
|
11
|
+
function m(m, h, g) {
|
|
12
|
+
if (o(m) || l(m)) {
|
|
13
|
+
let e = p(h), t = new s(m);
|
|
14
|
+
i(m);
|
|
15
|
+
try {
|
|
16
|
+
t.mount(e, null, { provides: g?.router ? [[u, g.router]] : void 0 });
|
|
17
|
+
} finally {
|
|
18
|
+
r(m);
|
|
19
|
+
}
|
|
20
|
+
return g?.router && d(g.router), { unmount() {
|
|
21
|
+
t.unmount(), g?.router && f(g.router), a(m);
|
|
22
|
+
} };
|
|
23
|
+
}
|
|
24
|
+
let _ = p(h), v = new e();
|
|
25
|
+
v.parent = t(), g?.router && (c(v, new Map([[u, g.router]])), d(g.router));
|
|
26
|
+
let y = n(v, () => m._render(_, null));
|
|
27
|
+
return { unmount() {
|
|
28
|
+
v.dispose(), y(), g?.router && f(g.router);
|
|
29
|
+
} };
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { m as mount };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=mount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.js","names":[],"sources":["../../../../src/elur/next-2/mount.ts"],"sourcesContent":["/**\n * next/ — fork del mount() público (../component.ts) sobre el kernel.\n *\n * Diferencias vs el estable:\n * - Componentes (clase o invocación funcional) montan via ComponentInstance:\n * máquina de estados, owner propio, mount transaccional, onMount\n * post-commit, unmount idempotente.\n * - `options.router` se inyecta via `provides` en el frame de contexto de la\n * instancia (A.12) en vez de un stack global.\n * - Templates raíz montan bajo un Owner raíz — así los componentes internos\n * tienen cadena de owners y provide/inject resuelve por instancias.\n */\nimport type { ElurTemplate, ElurMountHandle } from \"../template/index.js\";\nimport {\n isElurComponent,\n _debugComponentMountStart,\n _debugComponentMountEnd,\n _debugComponentUnmount,\n type ElurComponent,\n} from \"../lifecycle.js\";\nimport { RouterKey, _debugRegisterRouter, _debugUnregisterRouter } from \"../router-registry.js\";\nimport type { Router } from \"../router.js\";\nimport { Owner, getOwner, runWithOwner } from \"./reactivity.js\";\nimport {\n ComponentInstance,\n isComponentInvocation,\n _registerContextOwner,\n type ComponentInvocation,\n} from \"./component.js\";\n\nexport interface MountOptions {\n router?: Router;\n}\n\nfunction _resolveContainer(container: Element | string): Element {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) as Element)\n : container;\n if (!el) {\n throw new Error(`[elur] mount: container not found: ${container}`);\n }\n return el;\n}\n\n/**\n * Mounts a ElurTemplate, ElurComponent o ComponentInvocation en el DOM.\n *\n * mount(Counter({ initial: 10 }), \"#app\"); // componente funcional\n * mount(new Timer(), \"#app\"); // clase con lifecycle\n * mount(html`…`, \"#app\"); // template\n *\n * @returns { unmount() } — mata el árbol reactivo completo y remueve el DOM.\n */\nexport function mount(\n component: ElurTemplate | ElurComponent | ComponentInvocation<any>,\n container: Element | string,\n options?: MountOptions,\n): ElurMountHandle {\n if (isElurComponent(component) || isComponentInvocation(component)) {\n const el = _resolveContainer(container);\n const inst = new ComponentInstance(component);\n\n _debugComponentMountStart(component as ElurComponent);\n try {\n inst.mount(el, null, {\n provides: options?.router\n ? [[RouterKey, options.router] as const]\n : undefined,\n });\n } finally {\n _debugComponentMountEnd(component as ElurComponent);\n }\n if (options?.router) _debugRegisterRouter(options.router);\n\n return {\n unmount() {\n inst.unmount();\n if (options?.router) _debugUnregisterRouter(options.router);\n _debugComponentUnmount(component as ElurComponent);\n },\n };\n }\n\n const el = _resolveContainer(container);\n // Owner raíz para el template: ancla la cadena de owners (los componentes\n // internos resuelven parent/contexto por ella) y puede portar el frame\n // de contexto del router.\n const root = new Owner();\n root.parent = getOwner();\n if (options?.router) {\n _registerContextOwner(root, new Map([[RouterKey, options.router]]));\n _debugRegisterRouter(options.router);\n }\n const cleanup = runWithOwner(root, () =>\n (component as ElurTemplate)._render(el, null),\n );\n return {\n unmount() {\n root.dispose();\n cleanup();\n if (options?.router) _debugUnregisterRouter(options.router);\n },\n };\n}\n"],"mappings":";;;;;AAkCA,SAAS,EAAkB,GAAsC;CAC7D,IAAM,IACF,OAAO,KAAc,WACd,SAAS,cAAc,EAAU,GAClC;AACV,KAAI,CAAC,EACD,OAAU,MAAM,sCAAsC,IAAY;AAEtE,QAAO;;AAYX,SAAgB,EACZ,GACA,GACA,GACe;AACf,KAAI,EAAgB,EAAU,IAAI,EAAsB,EAAU,EAAE;EAChE,IAAM,IAAK,EAAkB,EAAU,EACjC,IAAO,IAAI,EAAkB,EAAU;AAE7C,IAA0B,EAA2B;AACrD,MAAI;AACA,KAAK,MAAM,GAAI,MAAM,EACjB,UAAU,GAAS,SACb,CAAC,CAAC,GAAW,EAAQ,OAAO,CAAU,GACtC,KAAA,GACT,CAAC;YACI;AACN,KAAwB,EAA2B;;AAIvD,SAFI,GAAS,UAAQ,EAAqB,EAAQ,OAAO,EAElD,EACH,UAAU;AAGN,GAFA,EAAK,SAAS,EACV,GAAS,UAAQ,EAAuB,EAAQ,OAAO,EAC3D,EAAuB,EAA2B;KAEzD;;CAGL,IAAM,IAAK,EAAkB,EAAU,EAIjC,IAAO,IAAI,GAAO;AAExB,CADA,EAAK,SAAS,GAAU,EACpB,GAAS,WACT,EAAsB,GAAM,IAAI,IAAI,CAAC,CAAC,GAAW,EAAQ,OAAO,CAAC,CAAC,CAAC,EACnE,EAAqB,EAAQ,OAAO;CAExC,IAAM,IAAU,EAAa,SACxB,EAA2B,QAAQ,GAAI,KAAK,CAChD;AACD,QAAO,EACH,UAAU;AAGN,EAFA,EAAK,SAAS,EACd,GAAS,EACL,GAAS,UAAQ,EAAuB,EAAQ,OAAO;IAElE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./reactivity.cjs`),t=require(`../template/types.cjs`),n=require(`../../lifecycle.cjs`),r=require(`../../context.cjs`),i=require(`./component.cjs`),a=require(`./mount-helpers.cjs`),o=require(`./keyed-diff.cjs`),s=require(`./dom-write.cjs`);function c(c,l,u,d){if(t.isDerivedBinding(l)&&(l=l.get),typeof l!=`function`){if(l instanceof e.Signal){let t=document.createTextNode(``);c.parentNode.insertBefore(t,c),u.push(e._bindSignal(l,e=>{t.nodeValue=e==null||e===!1?``:String(e)}));return}if(i.isElurSlot(l)&&(l=e.runWithOwner(l.owner,()=>l.render())),typeof l==`object`&&l&&l[t.ELUR_RENDER_PROTOCOL]!=null){let e=l[t.ELUR_RENDER_PROTOCOL];if(e.mountDom){let t=e.mountDom({parent:c.parentNode,before:c});t&&u.push(t);return}}if(n.isElurComponent(l))a._mountComponentDeferred(l,c.parentNode,c,d,u);else if(i.isComponentInvocation(l)){let e=new i.ComponentInstance(l);e.mount(c.parentNode,c,{ctxSnapshot:r._captureContextSnapshot(),deferOnMount:e=>a._deferOnMount(e)}),u.push(()=>e.unmount())}else if(t.isElurTemplate(l))u.push(l._render(c.parentNode,c));else if(t.isKeyedList(l)&&l.delta){let e=l;e._mount(c.parentNode,c),u.push(()=>e._dispose())}else if(t.isKeyedList(l)){let e=r._captureContextSnapshot(),t=new Map,n=document.createTextNode(``);c.parentNode.insertBefore(n,c),o.reconcileKeyedList({zoneStart:n,anchor:c,state:t,prevOrder:[],list:l,mount:o.createKeyedMount(e),ctxSnapshot:e,onDuplicateKey:e=>{console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`)}}),u.push(()=>{for(let e of t.values())e.cleanup();t.clear()})}else if(Array.isArray(l))for(let e of l)n.isElurComponent(e)?a._mountComponentDeferred(e,c.parentNode,c,d,u):t.isElurTemplate(e)?e._render(c.parentNode,c):e!=null&&e!==!1&&c.parentNode.insertBefore(document.createTextNode(String(e)),c);else l!=null&&l!==!1&&c.parentNode.insertBefore(document.createTextNode(String(l)),c);return}let f=null,p=null,m=null,h=null,g=null,_=[],v=null,y=r._captureContextSnapshot(),b=o.createKeyedMount(y),x=!1,S=``,C=!0,w=e._renderEffect(()=>{let r=l();if(typeof r==`string`||typeof r==`number`){S=String(r);let e=()=>{x=!1,p&&=(p(),null),f?f.nodeValue=S:(f=document.createTextNode(S),c.parentNode.insertBefore(f,c))};C?(C=!1,e()):x||(x=!0,s.queueDomWrite(c,`text`,e));return}x=!1,C=!1,f&&=(f.parentNode?.removeChild(f),null);let u=i.isComponentInvocation(r)&&(m?.matches(r)??!1);if(!u&&p&&(p(),p=null),h=null,i.isElurSlot(r)&&(h=r.owner,r=e.runWithOwner(r.owner,()=>r.render())),!(r==null||r===!1))if(n.isElurComponent(r)||i.isComponentInvocation(r))if(u)m.updateProps(r.props);else{let e=new i.ComponentInstance(r);e.mount(c.parentNode,c,{ctxSnapshot:y,declOwner:h,deferOnMount:e=>a._deferOnMount(e)}),m=e,p=()=>{e.unmount(),m=null}}else if(typeof r==`object`&&r&&r[t.ELUR_RENDER_PROTOCOL]!=null){let e=r[t.ELUR_RENDER_PROTOCOL];e.mountDom?p=e.mountDom({parent:c.parentNode,before:c})??null:(f=document.createTextNode(String(r)),c.parentNode.insertBefore(f,c))}else if(t.isElurTemplate(r))p=r._render(c.parentNode,c);else if(t.isKeyedList(r)){if(g||(g=new Map,v=document.createTextNode(``),c.parentNode.insertBefore(v,c)),r.delta){let e=r;e._mount(c.parentNode,c),p=()=>e._dispose();return}o.reconcileKeyedList({zoneStart:v,anchor:c,state:g,prevOrder:_,list:r,mount:b,onDuplicateKey:e=>{console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`)}})}else if(Array.isArray(r)){let e=[];for(let i of r)if(n.isElurComponent(i))e.push(a._mountComponent(i,c.parentNode,c));else if(t.isElurTemplate(i))e.push(i._render(c.parentNode,c));else if(i!=null&&i!==!1){let t=document.createTextNode(String(i));c.parentNode.insertBefore(t,c),e.push(()=>t.parentNode?.removeChild(t))}p=()=>e.forEach(e=>e())}else f=document.createTextNode(String(r)),c.parentNode.insertBefore(f,c)});u.push(()=>{if(w(),p&&=(p(),null),f&&=(f.parentNode?.removeChild(f),null),g){for(let e of g.values())e.cleanup();g=null,v=null}})}exports.activateNodeBinding=c;
|
|
2
|
+
//# sourceMappingURL=node-binding.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-binding.cjs","names":[],"sources":["../../../../src/elur/next-2/node-binding.ts"],"sourcesContent":["// =============================================================================\n// --- next/ — reactive node binding con render-queue + cola DOM tipada ---\n// Fork de ../template/node-binding.ts (B.8/B.11): el binding corre en la cola\n// de render effects (antes que user effects) y los writes de texto usan la cola\n// tipada con last-write-wins por binding id.\n// =============================================================================\n\nimport { _renderEffect, Signal, _bindSignal } from \"./reactivity.js\";\nimport {\n ComponentInstance,\n isComponentInvocation,\n isElurSlot,\n type ComponentInvocation,\n type Slot,\n} from \"./component.js\";\nimport { runWithOwner } from \"./reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport { _captureContextSnapshot } from \"../context.js\";\nimport type { KEntry } from \"../template/types.js\";\nimport type { RepeatKey } from \"../template/keyed.js\";\nimport { isElurTemplate, isKeyedList, ELUR_RENDER_PROTOCOL, isDerivedBinding } from \"../template/types.js\";\nimport {\n _mountComponent,\n _mountComponentWithCtx,\n _mountComponentDeferred,\n _deferOnMount,\n} from \"./mount-helpers.js\";\nimport { createKeyedMount, reconcileKeyedList } from \"./keyed-diff.js\";\nimport { queueDomWrite } from \"./dom-write.js\";\n\n// =============================================================================\n// --- Reactive node binding ---\n// =============================================================================\n\n/**\n * Activates a reactive node binding at `anchor`.\n * Handles: text, ElurTemplate, ElurComponent, KeyedList, Array, and static values.\n * Pushes dispose functions into `disposes`.\n */\nexport function activateNodeBinding(\n anchor: Text,\n value: unknown,\n disposes: Array<() => void>,\n postMountHooks: Array<() => void>,\n): void {\n // C.7 T2: el pack derivado se desenvuelve a getter — el path de function\n // trackea las deps dinámicamente (semántica idéntica al genérico).\n if (isDerivedBinding(value)) value = value.get;\n if (typeof value !== \"function\") {\n // C.6 T1: la señal viaja como valor — edge directa, sin getter ni\n // effect genérico. `${sig}` directo usa el mismo path.\n if (value instanceof Signal) {\n const sigText = document.createTextNode(\"\");\n anchor.parentNode!.insertBefore(sigText, anchor);\n disposes.push(_bindSignal(value, (v) => {\n sigText.nodeValue = v == null || v === false ? \"\" : String(v);\n }));\n return;\n }\n // A.14: slot declarado directamente — render bajo el owner del declarante\n if (isElurSlot(value)) {\n value = runWithOwner(value.owner, () => (value as Slot).render());\n }\n if (value != null && typeof value === \"object\" && (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] != null) {\n const proto = (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as { mountDom?: (ctx: import(\"../template/types.js\").DomProtocolContext) => (() => void) | void };\n if (proto.mountDom) {\n const cleanup = proto.mountDom({\n parent: anchor.parentNode!,\n before: anchor,\n });\n if (cleanup) disposes.push(cleanup);\n return;\n }\n }\n if (isElurComponent(value)) {\n _mountComponentDeferred(value, anchor.parentNode!, anchor, postMountHooks, disposes);\n } else if (isComponentInvocation(value)) {\n // Invocación directa (sin getter): montar por el kernel una vez.\n const inst = new ComponentInstance(value);\n inst.mount(anchor.parentNode!, anchor, {\n ctxSnapshot: _captureContextSnapshot(),\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n disposes.push(() => inst.unmount());\n } else if (isElurTemplate(value)) {\n disposes.push(value._render(anchor.parentNode!, anchor));\n } else if (isKeyedList(value) && (value as { delta?: true }).delta) {\n // B.12.7: liveList — monta la zona una vez; los mutadores aplican\n // deltas directos sin re-reconcile.\n const dl = value as unknown as { _mount(p: Node, a: Node): void; _dispose(): void };\n dl._mount(anchor.parentNode!, anchor);\n disposes.push(() => dl._dispose());\n } else if (isKeyedList(value)) {\n // Static keyed list (`repeat(...)` directly, without a getter):\n // mirror the reactive path so a direct keyed value never falls\n // through to `String(value)`.\n const ctxSnapshot = _captureContextSnapshot();\n const keyedState = new Map<RepeatKey, KEntry>();\n const keyedZoneStart = document.createTextNode(\"\");\n anchor.parentNode!.insertBefore(keyedZoneStart, anchor);\n reconcileKeyedList({\n zoneStart: keyedZoneStart,\n anchor,\n state: keyedState,\n prevOrder: [],\n list: value,\n mount: createKeyedMount(ctxSnapshot),\n ctxSnapshot,\n onDuplicateKey: (key) => {\n console.warn(`[elur] repeat(): duplicate key \"${key}\". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);\n },\n });\n disposes.push(() => {\n for (const entry of keyedState.values()) {\n entry.cleanup();\n }\n keyedState.clear();\n });\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (isElurComponent(item)) {\n _mountComponentDeferred(item, anchor.parentNode!, anchor, postMountHooks, disposes);\n } else if (isElurTemplate(item)) {\n item._render(anchor.parentNode!, anchor);\n } else if (item != null && item !== false) {\n anchor.parentNode!.insertBefore(\n document.createTextNode(String(item)),\n anchor\n );\n }\n }\n } else if (value != null && value !== false) {\n anchor.parentNode!.insertBefore(\n document.createTextNode(String(value)),\n anchor\n );\n }\n return;\n }\n\n // Reactive function path\n let textNode: Text | null = null;\n let innerCleanup: (() => void) | null = null;\n // A.15: instancia montada en este binding — para reconciliación de\n // invocaciones (misma definición+key → updateProps, no remount).\n let mountedInstance: ComponentInstance | null = null;\n // A.14: owner del declarante del slot desenvuelto en la pasada actual —\n // mounts de su contenido se cuelgan de él (contexto léxico).\n let declOwner: import(\"./reactivity.js\").OwnerLike | null = null;\n\n type Key = RepeatKey;\n let keyedState: Map<Key, KEntry> | null = null;\n let prevKeyOrder: Key[] = [];\n let keyedZoneStart: Node | null = null;\n\n const ctxSnapshot = _captureContextSnapshot();\n const keyedMount = createKeyedMount(ctxSnapshot);\n\n let _textQueued = false;\n let _pendingText = \"\";\n let _isFirstText = true;\n\n const dispose = _renderEffect(() => {\n let v = (value as () => unknown)();\n\n if (typeof v === \"string\" || typeof v === \"number\") {\n _pendingText = String(v);\n\n const update = () => {\n _textQueued = false;\n if (innerCleanup) {\n innerCleanup();\n innerCleanup = null;\n }\n if (!textNode) {\n textNode = document.createTextNode(_pendingText);\n anchor.parentNode!.insertBefore(textNode, anchor);\n } else {\n textNode.nodeValue = _pendingText;\n }\n };\n\n if (_isFirstText) {\n _isFirstText = false;\n update();\n } else if (!_textQueued) {\n _textQueued = true;\n queueDomWrite(anchor, \"text\", update);\n }\n return;\n }\n\n _textQueued = false;\n _isFirstText = false;\n\n if (textNode) {\n textNode.parentNode?.removeChild(textNode);\n textNode = null;\n }\n // A.15: reconciliación de invocaciones — si el nuevo valor es la misma\n // definición+key que la instancia montada, se actualizan props y NO se\n // desmonta (el cleanup genérico de abajo la mataría).\n const isReconciled = isComponentInvocation(v) && (mountedInstance?.matches(v) ?? false);\n if (!isReconciled && innerCleanup) {\n innerCleanup();\n innerCleanup = null;\n }\n\n // A.14: slot lazy — desenvolver bajo el owner del declarante y\n // montar su contenido colgado de ese owner (contexto léxico).\n declOwner = null;\n if (isElurSlot(v)) {\n declOwner = v.owner;\n v = runWithOwner(v.owner, () => (v as Slot).render());\n }\n\n if (v == null || v === false) {\n // Empty\n } else if (isElurComponent(v) || isComponentInvocation(v)) {\n // A.15: invocaciones van por la rama reconciliadora — el proto\n // mountDom remontaría en cada write.\n if (isReconciled) {\n // misma definición+key → actualizar props, no recrear setup\n mountedInstance!.updateProps((v as ComponentInvocation<any>).props);\n } else {\n const inst = new ComponentInstance(v);\n inst.mount(anchor.parentNode!, anchor, {\n ctxSnapshot,\n declOwner,\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n mountedInstance = inst;\n innerCleanup = () => { inst.unmount(); mountedInstance = null; };\n }\n } else if (v != null && typeof v === \"object\" && (v as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] != null) {\n const proto = (v as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as { mountDom?: (ctx: import(\"../template/types.js\").DomProtocolContext) => (() => void) | void };\n if (proto.mountDom) {\n innerCleanup = proto.mountDom({ parent: anchor.parentNode!, before: anchor }) ?? null;\n } else {\n textNode = document.createTextNode(String(v));\n anchor.parentNode!.insertBefore(textNode, anchor);\n }\n } else if (isElurTemplate(v)) {\n innerCleanup = v._render(anchor.parentNode!, anchor);\n } else if (isKeyedList(v)) {\n\n if (!keyedState) {\n keyedState = new Map();\n keyedZoneStart = document.createTextNode(\"\");\n anchor.parentNode!.insertBefore(keyedZoneStart, anchor);\n }\n\n if ((v as { delta?: true }).delta) {\n // B.12.7: liveList — _mount es idempotente; al salir del DOM\n // (innerCleanup) se dispone la zona pero la API sigue viva.\n const dl = v as unknown as { _mount(p: Node, a: Node): void; _dispose(): void };\n dl._mount(anchor.parentNode!, anchor);\n innerCleanup = () => dl._dispose();\n return; // dentro del run del effect — early return del callback\n }\n\n reconcileKeyedList({\n zoneStart: keyedZoneStart!,\n anchor,\n state: keyedState,\n prevOrder: prevKeyOrder,\n list: v,\n mount: keyedMount,\n onDuplicateKey: (key) => {\n console.warn(`[elur] repeat(): duplicate key \"${key}\". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);\n },\n });\n } else if (Array.isArray(v)) {\n const cleanups: Array<() => void> = [];\n for (const item of v) {\n if (isElurComponent(item)) {\n cleanups.push(_mountComponent(item, anchor.parentNode!, anchor));\n } else if (isElurTemplate(item)) {\n cleanups.push(item._render(anchor.parentNode!, anchor));\n } else if (item != null && item !== false) {\n const t = document.createTextNode(String(item));\n anchor.parentNode!.insertBefore(t, anchor);\n cleanups.push(() => t.parentNode?.removeChild(t));\n }\n }\n innerCleanup = () => cleanups.forEach((c) => c());\n } else {\n textNode = document.createTextNode(String(v));\n anchor.parentNode!.insertBefore(textNode, anchor);\n }\n });\n\n disposes.push(() => {\n dispose();\n if (innerCleanup) {\n innerCleanup();\n innerCleanup = null;\n }\n if (textNode) {\n textNode.parentNode?.removeChild(textNode);\n textNode = null;\n }\n if (keyedState) {\n for (const entry of keyedState.values()) {\n entry.cleanup();\n }\n keyedState = null;\n keyedZoneStart = null;\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activates a reactive node binding at `anchor`.
|
|
3
|
+
* Handles: text, ElurTemplate, ElurComponent, KeyedList, Array, and static values.
|
|
4
|
+
* Pushes dispose functions into `disposes`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function activateNodeBinding(anchor: Text, value: unknown, disposes: Array<() => void>, postMountHooks: Array<() => void>): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activates a reactive node binding at `anchor`.
|
|
3
|
+
* Handles: text, ElurTemplate, ElurComponent, KeyedList, Array, and static values.
|
|
4
|
+
* Pushes dispose functions into `disposes`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function activateNodeBinding(anchor: Text, value: unknown, disposes: Array<() => void>, postMountHooks: Array<() => void>): void;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { Signal as e, _bindSignal as t, _renderEffect as n, runWithOwner as r } from "./reactivity.js";
|
|
2
|
+
import { ELUR_RENDER_PROTOCOL as i, isDerivedBinding as a, isElurTemplate as o, isKeyedList as s } from "../template/types.js";
|
|
3
|
+
import { isElurComponent as c } from "../../lifecycle.js";
|
|
4
|
+
import { _captureContextSnapshot as l } from "../../context.js";
|
|
5
|
+
import { ComponentInstance as u, isComponentInvocation as d, isElurSlot as f } from "./component.js";
|
|
6
|
+
import { _deferOnMount as p, _mountComponent as m, _mountComponentDeferred as h } from "./mount-helpers.js";
|
|
7
|
+
import { createKeyedMount as g, reconcileKeyedList as _ } from "./keyed-diff.js";
|
|
8
|
+
import { queueDomWrite as v } from "./dom-write.js";
|
|
9
|
+
//#region src/elur/next-2/node-binding.ts
|
|
10
|
+
function y(y, b, x, S) {
|
|
11
|
+
if (a(b) && (b = b.get), typeof b != "function") {
|
|
12
|
+
if (b instanceof e) {
|
|
13
|
+
let e = document.createTextNode("");
|
|
14
|
+
y.parentNode.insertBefore(e, y), x.push(t(b, (t) => {
|
|
15
|
+
e.nodeValue = t == null || t === !1 ? "" : String(t);
|
|
16
|
+
}));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (f(b) && (b = r(b.owner, () => b.render())), typeof b == "object" && b && b[i] != null) {
|
|
20
|
+
let e = b[i];
|
|
21
|
+
if (e.mountDom) {
|
|
22
|
+
let t = e.mountDom({
|
|
23
|
+
parent: y.parentNode,
|
|
24
|
+
before: y
|
|
25
|
+
});
|
|
26
|
+
t && x.push(t);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (c(b)) h(b, y.parentNode, y, S, x);
|
|
31
|
+
else if (d(b)) {
|
|
32
|
+
let e = new u(b);
|
|
33
|
+
e.mount(y.parentNode, y, {
|
|
34
|
+
ctxSnapshot: l(),
|
|
35
|
+
deferOnMount: (e) => p(e)
|
|
36
|
+
}), x.push(() => e.unmount());
|
|
37
|
+
} else if (o(b)) x.push(b._render(y.parentNode, y));
|
|
38
|
+
else if (s(b) && b.delta) {
|
|
39
|
+
let e = b;
|
|
40
|
+
e._mount(y.parentNode, y), x.push(() => e._dispose());
|
|
41
|
+
} else if (s(b)) {
|
|
42
|
+
let e = l(), t = /* @__PURE__ */ new Map(), n = document.createTextNode("");
|
|
43
|
+
y.parentNode.insertBefore(n, y), _({
|
|
44
|
+
zoneStart: n,
|
|
45
|
+
anchor: y,
|
|
46
|
+
state: t,
|
|
47
|
+
prevOrder: [],
|
|
48
|
+
list: b,
|
|
49
|
+
mount: g(e),
|
|
50
|
+
ctxSnapshot: e,
|
|
51
|
+
onDuplicateKey: (e) => {
|
|
52
|
+
console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);
|
|
53
|
+
}
|
|
54
|
+
}), x.push(() => {
|
|
55
|
+
for (let e of t.values()) e.cleanup();
|
|
56
|
+
t.clear();
|
|
57
|
+
});
|
|
58
|
+
} else if (Array.isArray(b)) for (let e of b) c(e) ? h(e, y.parentNode, y, S, x) : o(e) ? e._render(y.parentNode, y) : e != null && e !== !1 && y.parentNode.insertBefore(document.createTextNode(String(e)), y);
|
|
59
|
+
else b != null && b !== !1 && y.parentNode.insertBefore(document.createTextNode(String(b)), y);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let C = null, w = null, T = null, E = null, D = null, O = [], k = null, A = l(), j = g(A), M = !1, N = "", P = !0, F = n(() => {
|
|
63
|
+
let e = b();
|
|
64
|
+
if (typeof e == "string" || typeof e == "number") {
|
|
65
|
+
N = String(e);
|
|
66
|
+
let t = () => {
|
|
67
|
+
M = !1, w &&= (w(), null), C ? C.nodeValue = N : (C = document.createTextNode(N), y.parentNode.insertBefore(C, y));
|
|
68
|
+
};
|
|
69
|
+
P ? (P = !1, t()) : M || (M = !0, v(y, "text", t));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
M = !1, P = !1, C &&= (C.parentNode?.removeChild(C), null);
|
|
73
|
+
let t = d(e) && (T?.matches(e) ?? !1);
|
|
74
|
+
if (!t && w && (w(), w = null), E = null, f(e) && (E = e.owner, e = r(e.owner, () => e.render())), !(e == null || e === !1)) if (c(e) || d(e)) if (t) T.updateProps(e.props);
|
|
75
|
+
else {
|
|
76
|
+
let t = new u(e);
|
|
77
|
+
t.mount(y.parentNode, y, {
|
|
78
|
+
ctxSnapshot: A,
|
|
79
|
+
declOwner: E,
|
|
80
|
+
deferOnMount: (e) => p(e)
|
|
81
|
+
}), T = t, w = () => {
|
|
82
|
+
t.unmount(), T = null;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
else if (typeof e == "object" && e && e[i] != null) {
|
|
86
|
+
let t = e[i];
|
|
87
|
+
t.mountDom ? w = t.mountDom({
|
|
88
|
+
parent: y.parentNode,
|
|
89
|
+
before: y
|
|
90
|
+
}) ?? null : (C = document.createTextNode(String(e)), y.parentNode.insertBefore(C, y));
|
|
91
|
+
} else if (o(e)) w = e._render(y.parentNode, y);
|
|
92
|
+
else if (s(e)) {
|
|
93
|
+
if (D || (D = /* @__PURE__ */ new Map(), k = document.createTextNode(""), y.parentNode.insertBefore(k, y)), e.delta) {
|
|
94
|
+
let t = e;
|
|
95
|
+
t._mount(y.parentNode, y), w = () => t._dispose();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
_({
|
|
99
|
+
zoneStart: k,
|
|
100
|
+
anchor: y,
|
|
101
|
+
state: D,
|
|
102
|
+
prevOrder: O,
|
|
103
|
+
list: e,
|
|
104
|
+
mount: j,
|
|
105
|
+
onDuplicateKey: (e) => {
|
|
106
|
+
console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
} else if (Array.isArray(e)) {
|
|
110
|
+
let t = [];
|
|
111
|
+
for (let n of e) if (c(n)) t.push(m(n, y.parentNode, y));
|
|
112
|
+
else if (o(n)) t.push(n._render(y.parentNode, y));
|
|
113
|
+
else if (n != null && n !== !1) {
|
|
114
|
+
let e = document.createTextNode(String(n));
|
|
115
|
+
y.parentNode.insertBefore(e, y), t.push(() => e.parentNode?.removeChild(e));
|
|
116
|
+
}
|
|
117
|
+
w = () => t.forEach((e) => e());
|
|
118
|
+
} else C = document.createTextNode(String(e)), y.parentNode.insertBefore(C, y);
|
|
119
|
+
});
|
|
120
|
+
x.push(() => {
|
|
121
|
+
if (F(), w &&= (w(), null), C &&= (C.parentNode?.removeChild(C), null), D) {
|
|
122
|
+
for (let e of D.values()) e.cleanup();
|
|
123
|
+
D = null, k = null;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
export { y as activateNodeBinding };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=node-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-binding.js","names":[],"sources":["../../../../src/elur/next-2/node-binding.ts"],"sourcesContent":["// =============================================================================\n// --- next/ — reactive node binding con render-queue + cola DOM tipada ---\n// Fork de ../template/node-binding.ts (B.8/B.11): el binding corre en la cola\n// de render effects (antes que user effects) y los writes de texto usan la cola\n// tipada con last-write-wins por binding id.\n// =============================================================================\n\nimport { _renderEffect, Signal, _bindSignal } from \"./reactivity.js\";\nimport {\n ComponentInstance,\n isComponentInvocation,\n isElurSlot,\n type ComponentInvocation,\n type Slot,\n} from \"./component.js\";\nimport { runWithOwner } from \"./reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport { _captureContextSnapshot } from \"../context.js\";\nimport type { KEntry } from \"../template/types.js\";\nimport type { RepeatKey } from \"../template/keyed.js\";\nimport { isElurTemplate, isKeyedList, ELUR_RENDER_PROTOCOL, isDerivedBinding } from \"../template/types.js\";\nimport {\n _mountComponent,\n _mountComponentWithCtx,\n _mountComponentDeferred,\n _deferOnMount,\n} from \"./mount-helpers.js\";\nimport { createKeyedMount, reconcileKeyedList } from \"./keyed-diff.js\";\nimport { queueDomWrite } from \"./dom-write.js\";\n\n// =============================================================================\n// --- Reactive node binding ---\n// =============================================================================\n\n/**\n * Activates a reactive node binding at `anchor`.\n * Handles: text, ElurTemplate, ElurComponent, KeyedList, Array, and static values.\n * Pushes dispose functions into `disposes`.\n */\nexport function activateNodeBinding(\n anchor: Text,\n value: unknown,\n disposes: Array<() => void>,\n postMountHooks: Array<() => void>,\n): void {\n // C.7 T2: el pack derivado se desenvuelve a getter — el path de function\n // trackea las deps dinámicamente (semántica idéntica al genérico).\n if (isDerivedBinding(value)) value = value.get;\n if (typeof value !== \"function\") {\n // C.6 T1: la señal viaja como valor — edge directa, sin getter ni\n // effect genérico. `${sig}` directo usa el mismo path.\n if (value instanceof Signal) {\n const sigText = document.createTextNode(\"\");\n anchor.parentNode!.insertBefore(sigText, anchor);\n disposes.push(_bindSignal(value, (v) => {\n sigText.nodeValue = v == null || v === false ? \"\" : String(v);\n }));\n return;\n }\n // A.14: slot declarado directamente — render bajo el owner del declarante\n if (isElurSlot(value)) {\n value = runWithOwner(value.owner, () => (value as Slot).render());\n }\n if (value != null && typeof value === \"object\" && (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] != null) {\n const proto = (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as { mountDom?: (ctx: import(\"../template/types.js\").DomProtocolContext) => (() => void) | void };\n if (proto.mountDom) {\n const cleanup = proto.mountDom({\n parent: anchor.parentNode!,\n before: anchor,\n });\n if (cleanup) disposes.push(cleanup);\n return;\n }\n }\n if (isElurComponent(value)) {\n _mountComponentDeferred(value, anchor.parentNode!, anchor, postMountHooks, disposes);\n } else if (isComponentInvocation(value)) {\n // Invocación directa (sin getter): montar por el kernel una vez.\n const inst = new ComponentInstance(value);\n inst.mount(anchor.parentNode!, anchor, {\n ctxSnapshot: _captureContextSnapshot(),\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n disposes.push(() => inst.unmount());\n } else if (isElurTemplate(value)) {\n disposes.push(value._render(anchor.parentNode!, anchor));\n } else if (isKeyedList(value) && (value as { delta?: true }).delta) {\n // B.12.7: liveList — monta la zona una vez; los mutadores aplican\n // deltas directos sin re-reconcile.\n const dl = value as unknown as { _mount(p: Node, a: Node): void; _dispose(): void };\n dl._mount(anchor.parentNode!, anchor);\n disposes.push(() => dl._dispose());\n } else if (isKeyedList(value)) {\n // Static keyed list (`repeat(...)` directly, without a getter):\n // mirror the reactive path so a direct keyed value never falls\n // through to `String(value)`.\n const ctxSnapshot = _captureContextSnapshot();\n const keyedState = new Map<RepeatKey, KEntry>();\n const keyedZoneStart = document.createTextNode(\"\");\n anchor.parentNode!.insertBefore(keyedZoneStart, anchor);\n reconcileKeyedList({\n zoneStart: keyedZoneStart,\n anchor,\n state: keyedState,\n prevOrder: [],\n list: value,\n mount: createKeyedMount(ctxSnapshot),\n ctxSnapshot,\n onDuplicateKey: (key) => {\n console.warn(`[elur] repeat(): duplicate key \"${key}\". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);\n },\n });\n disposes.push(() => {\n for (const entry of keyedState.values()) {\n entry.cleanup();\n }\n keyedState.clear();\n });\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (isElurComponent(item)) {\n _mountComponentDeferred(item, anchor.parentNode!, anchor, postMountHooks, disposes);\n } else if (isElurTemplate(item)) {\n item._render(anchor.parentNode!, anchor);\n } else if (item != null && item !== false) {\n anchor.parentNode!.insertBefore(\n document.createTextNode(String(item)),\n anchor\n );\n }\n }\n } else if (value != null && value !== false) {\n anchor.parentNode!.insertBefore(\n document.createTextNode(String(value)),\n anchor\n );\n }\n return;\n }\n\n // Reactive function path\n let textNode: Text | null = null;\n let innerCleanup: (() => void) | null = null;\n // A.15: instancia montada en este binding — para reconciliación de\n // invocaciones (misma definición+key → updateProps, no remount).\n let mountedInstance: ComponentInstance | null = null;\n // A.14: owner del declarante del slot desenvuelto en la pasada actual —\n // mounts de su contenido se cuelgan de él (contexto léxico).\n let declOwner: import(\"./reactivity.js\").OwnerLike | null = null;\n\n type Key = RepeatKey;\n let keyedState: Map<Key, KEntry> | null = null;\n let prevKeyOrder: Key[] = [];\n let keyedZoneStart: Node | null = null;\n\n const ctxSnapshot = _captureContextSnapshot();\n const keyedMount = createKeyedMount(ctxSnapshot);\n\n let _textQueued = false;\n let _pendingText = \"\";\n let _isFirstText = true;\n\n const dispose = _renderEffect(() => {\n let v = (value as () => unknown)();\n\n if (typeof v === \"string\" || typeof v === \"number\") {\n _pendingText = String(v);\n\n const update = () => {\n _textQueued = false;\n if (innerCleanup) {\n innerCleanup();\n innerCleanup = null;\n }\n if (!textNode) {\n textNode = document.createTextNode(_pendingText);\n anchor.parentNode!.insertBefore(textNode, anchor);\n } else {\n textNode.nodeValue = _pendingText;\n }\n };\n\n if (_isFirstText) {\n _isFirstText = false;\n update();\n } else if (!_textQueued) {\n _textQueued = true;\n queueDomWrite(anchor, \"text\", update);\n }\n return;\n }\n\n _textQueued = false;\n _isFirstText = false;\n\n if (textNode) {\n textNode.parentNode?.removeChild(textNode);\n textNode = null;\n }\n // A.15: reconciliación de invocaciones — si el nuevo valor es la misma\n // definición+key que la instancia montada, se actualizan props y NO se\n // desmonta (el cleanup genérico de abajo la mataría).\n const isReconciled = isComponentInvocation(v) && (mountedInstance?.matches(v) ?? false);\n if (!isReconciled && innerCleanup) {\n innerCleanup();\n innerCleanup = null;\n }\n\n // A.14: slot lazy — desenvolver bajo el owner del declarante y\n // montar su contenido colgado de ese owner (contexto léxico).\n declOwner = null;\n if (isElurSlot(v)) {\n declOwner = v.owner;\n v = runWithOwner(v.owner, () => (v as Slot).render());\n }\n\n if (v == null || v === false) {\n // Empty\n } else if (isElurComponent(v) || isComponentInvocation(v)) {\n // A.15: invocaciones van por la rama reconciliadora — el proto\n // mountDom remontaría en cada write.\n if (isReconciled) {\n // misma definición+key → actualizar props, no recrear setup\n mountedInstance!.updateProps((v as ComponentInvocation<any>).props);\n } else {\n const inst = new ComponentInstance(v);\n inst.mount(anchor.parentNode!, anchor, {\n ctxSnapshot,\n declOwner,\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n mountedInstance = inst;\n innerCleanup = () => { inst.unmount(); mountedInstance = null; };\n }\n } else if (v != null && typeof v === \"object\" && (v as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] != null) {\n const proto = (v as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as { mountDom?: (ctx: import(\"../template/types.js\").DomProtocolContext) => (() => void) | void };\n if (proto.mountDom) {\n innerCleanup = proto.mountDom({ parent: anchor.parentNode!, before: anchor }) ?? null;\n } else {\n textNode = document.createTextNode(String(v));\n anchor.parentNode!.insertBefore(textNode, anchor);\n }\n } else if (isElurTemplate(v)) {\n innerCleanup = v._render(anchor.parentNode!, anchor);\n } else if (isKeyedList(v)) {\n\n if (!keyedState) {\n keyedState = new Map();\n keyedZoneStart = document.createTextNode(\"\");\n anchor.parentNode!.insertBefore(keyedZoneStart, anchor);\n }\n\n if ((v as { delta?: true }).delta) {\n // B.12.7: liveList — _mount es idempotente; al salir del DOM\n // (innerCleanup) se dispone la zona pero la API sigue viva.\n const dl = v as unknown as { _mount(p: Node, a: Node): void; _dispose(): void };\n dl._mount(anchor.parentNode!, anchor);\n innerCleanup = () => dl._dispose();\n return; // dentro del run del effect — early return del callback\n }\n\n reconcileKeyedList({\n zoneStart: keyedZoneStart!,\n anchor,\n state: keyedState,\n prevOrder: prevKeyOrder,\n list: v,\n mount: keyedMount,\n onDuplicateKey: (key) => {\n console.warn(`[elur] repeat(): duplicate key \"${key}\". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);\n },\n });\n } else if (Array.isArray(v)) {\n const cleanups: Array<() => void> = [];\n for (const item of v) {\n if (isElurComponent(item)) {\n cleanups.push(_mountComponent(item, anchor.parentNode!, anchor));\n } else if (isElurTemplate(item)) {\n cleanups.push(item._render(anchor.parentNode!, anchor));\n } else if (item != null && item !== false) {\n const t = document.createTextNode(String(item));\n anchor.parentNode!.insertBefore(t, anchor);\n cleanups.push(() => t.parentNode?.removeChild(t));\n }\n }\n innerCleanup = () => cleanups.forEach((c) => c());\n } else {\n textNode = document.createTextNode(String(v));\n anchor.parentNode!.insertBefore(textNode, anchor);\n }\n });\n\n disposes.push(() => {\n dispose();\n if (innerCleanup) {\n innerCleanup();\n innerCleanup = null;\n }\n if (textNode) {\n textNode.parentNode?.removeChild(textNode);\n textNode = null;\n }\n if (keyedState) {\n for (const entry of keyedState.values()) {\n entry.cleanup();\n }\n keyedState = null;\n keyedZoneStart = null;\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./scheduler.cjs`);var t=0,n=1,r=2,i=4,a=8,o=16,s=32,c=0,l=0,u=null,d=null,f=1,ee=2,p=4,m=8,h=[],g=[],te=class{childrenHead=null;childCount=0;cleanups=null;parent=null;nextOwned=null;prevOwned=null;onOwnerError;_disposed=!1;dispose(){this._disposed||(this._disposed=!0,_(this),y(this))}};function _(e){if(e.cleanups){for(let t of e.cleanups)t();e.cleanups=null}let t=e.childrenHead;for(e.childrenHead=null,e.childCount=0;t;){let e=t.nextOwned;t.nextOwned=null,t.prevOwned=null,t.parent=null,t.dispose(),t=e}}function v(e){if(!d)return;e.parent=d;let t=d.childrenHead;e.nextOwned=t,e.prevOwned=null,t&&(t.prevOwned=e),d.childrenHead=e,d.childCount++}function y(e){let t=e.parent;e.parent=null,e.prevOwned?e.prevOwned.nextOwned=e.nextOwned:t&&(t.childrenHead=e.nextOwned),e.nextOwned&&(e.nextOwned.prevOwned=e.prevOwned),e.nextOwned=null,e.prevOwned=null,t&&t.childCount--}function ne(){return d}function re(e,t){let n=d,r=u;d=e,u=null;try{return t()}finally{d=n,u=r}}function ie(e){let t=new te;return t.parent=d,re(t,()=>e(()=>t.dispose()))}function ae(e){d&&(d.cleanups??=[]).push(e)}var oe=1e4,b=100,x=class extends Error{constructor(e,t){let n=[];for(let t=e.sourcesHead;t;t=t.nextSource){let e=t.source;if(n.push(e instanceof Q?`computed(v${e.version})`:`signal(v${e.version})`),n.length>=8){n.push(`…`);break}}super(`[elur] Maximum effect re-execution depth exceeded (possible infinite loop). Ciclo de efectos: un effect corrió ${t} veces en un solo flush (límite por nodo ${b}). Fuentes del effect: [${n.join(`, `)}]. Probable write-inside-effect que se re-encola a sí mismo.`),this.name=`ReactiveCycleError`}},S=[],C=null;function se(e){S.push(C),C=e}function ce(){C=S.pop()??null}var w=null,T=null;function E(){let e=T;if(!e||e.size===0){w=null;return}if(e.size===1){w=e.values().next().value??null;return}w={onCreate(t,n){for(let r of e)r.onCreate?.(t,n)},onWrite(t,n){for(let r of e)r.onWrite?.(t,n)}}}function le(e){let t=new Set;e&&t.add(e),T=t,E()}function ue(e){let t=T;return t||(t=new Set,w&&t.add(w),T=t),t.add(e),E(),()=>{t.delete(e),E()}}function de(){return 0}var D=[],O=[],k=null,A=0,fe=8192;function j(e,t,n,r){let i=k;return i?(k=i.nextSource,A--,i.source=e,i.target=t,i.seenVersion=n,i.mark=r,i.linked=!1,i.prevSource=null,i.nextTarget=null,i.prevTarget=null,i):{source:e,target:t,seenVersion:n,mark:r,linked:!1,nextSource:null,prevSource:null,nextTarget:null,prevTarget:null}}function M(e){A>=fe||(e.source=null,e.target=null,e.nextTarget=null,e.prevTarget=null,e.prevSource=null,e.nextSource=k,k=e,A++)}function N(e,t){t.nextTarget=e.consumersHead,t.prevTarget=null,e.consumersHead&&(e.consumersHead.prevTarget=t),e.consumersHead=t,t.linked=!0,e.liveCount++,e.liveCount===1&&e instanceof Q&&D.push(e)}function P(e,t){t.linked&&(t.prevTarget?t.prevTarget.nextTarget=t.nextTarget:e.consumersHead=t.nextTarget,t.nextTarget&&(t.nextTarget.prevTarget=t.prevTarget),t.linked=!1,e.liveCount--,e.liveCount===0&&e instanceof Q&&O.push(e))}function F(){for(;D.length;){let e=D.pop();for(let t=e.sourcesHead;t;t=t.nextSource)t.linked||N(t.source,t)}}function I(){for(;O.length;){let e=O.pop();for(let t=e.sourcesHead;t;t=t.nextSource)P(t.source,t)}}function pe(e,t){if(e.durable)return;for(let n=t.sourcesHead;n;n=n.nextSource)if(n.source===e){n.seenVersion=e.version,n.mark=t.evalMark;return}let n=j(e,t,e.version,t.evalMark);n.nextSource=t.sourcesHead,t.sourcesHead&&(t.sourcesHead.prevSource=n),t.sourcesHead=n,t.live()&&(N(e,n),D.length&&F())}function L(e){let t=e.sourcesHead;for(;t;){let n=t.nextSource;t.mark!==e.evalMark&&(t.prevSource?t.prevSource.nextSource=t.nextSource:e.sourcesHead=t.nextSource,t.nextSource&&(t.nextSource.prevSource=t.prevSource),P(t.source,t),M(t)),t=n}O.length&&I()}var R=[];function me(e){if(!(e.state&(r|o))&&!(e instanceof Q&&e.state&i))if(e.state=r,e instanceof Q){for(let r=e.consumersHead;r;r=r.nextTarget){let e=r.target;e.state===t&&(e.state=n,e instanceof Q?R.push(r):H(e))}for(;R.length;){let e=R.pop();for(let r=e.target.consumersHead;r;r=r.nextTarget){let e=r.target;e.state===t&&(e.state=n,e instanceof Q?R.push(r):H(e))}}}else H(e)}function he(e){for(let t=e.consumersHead;t;t=t.nextTarget)me(t.target);l===0&&Oe()}function ge(e){(e.childrenHead!==null||e.cleanups!==null)&&_(e),e.evalMark++;let n=u,a=d;u=e,d=e,e.state=i;let o,s=!0;try{o=e.fn(),s=!1}finally{u=n,d=a,s&&e.state&i&&(e.state=r)}L(e),e.state=t,e.lastCleanEpoch=c,(!(e.flags&f)||!e.equals(o,e._value))&&(e._value=o,e.flags|=f,e.version++)}var _e=64,z=128,B=256,V=z|320,ve=[],ye=0;function be(e){let n=e.state&(r|5);if(e.state&o)return;if(n===i)throw Error(`[elur-next] Ciclo reactivo detectado en computed().`);if(n===0&&e.flags&f&&(e.live()||e.lastCleanEpoch===c))return;let a=n===r||!(e.flags&f),l=!1;for(let n=e.sourcesHead;n;n=n.nextSource){let e=n.source;if(e instanceof Q&&(!(e.flags&f)||e.state!==t||!e.live()&&e.lastCleanEpoch!==c)){l=!0;break}!a&&e.version!==n.seenVersion&&(a=!0)}if(!l){if(a)ge(e);else{e.state=t,e.lastCleanEpoch=c;for(let t=e.sourcesHead;t;t=t.nextSource)t.seenVersion=t.source.version}return}let u=ye++===0?ve:[];try{let n=e;for(;n;){if(!(n.state&_e)){n.state|=_e,n._pCursor=null,n._pLink=null;let e=n.state&(r|5);if(n.state&o){n.state&=~s,n.state&=~V,n=u.pop();continue}if(e===i&&xe(u,n),e===0&&n.flags&f&&(n.live()||n.lastCleanEpoch===c)){n.state&=~V,n=u.pop();continue}n.state|=s,e===r&&(n.state|=z),n._pCursor=n.sourcesHead}if(n._pLink){let e=n._pLink;n._pLink=null,e.source.version!==e.seenVersion&&(n.state|=B)}let e=!1;for(;n._pCursor;){let r=n._pCursor;n._pCursor=r.nextSource;let i=r.source;if(i instanceof Q&&(!(i.flags&f)||i.state!==t||!i.live()&&i.lastCleanEpoch!==c)){i.state&s&&xe(u,n),n._pLink=r,u.push(n),i.state|=s,n=i,e=!0;break}i.version!==r.seenVersion&&(n.state|=B)}if(!e){if(n.state&=~s,n.state&(z|B)||!(n.flags&f))ge(n);else{n.state=t,n.lastCleanEpoch=c;for(let e=n.sourcesHead;e;e=e.nextSource)e.seenVersion=e.source.version}n.state&=~V,n._pCursor=null,n._pLink=null,n=u.pop()}}}finally{ye--}}function xe(e,t){for(let t of e)t.state&=~(s|V),t._pCursor=null,t._pLink=null;throw t.state&=~(s|V),e.length=0,Error(`[elur-next] Ciclo reactivo detectado en computed().`)}function Se(e){(e.state!==t||!e.live()&&e.lastCleanEpoch!==c)&&be(e)}function Ce(e){let t=!1;for(let n=e.sourcesHead;n;n=n.nextSource)n.source instanceof Q&&Se(n.source),n.source.version!==n.seenVersion&&(t=!0);return t}function H(e){e.state&(a|o)||(e.state|=a,(e.flags&p?h:g).push(e))}var U=!1,W=0,G=0,K=0,we=0,q=0,J=!1,Te=256,Y=()=>{h.length=0,g.length=0,G=0,K=0};function X(){W++,U=!1}function Ee(){for(;G<h.length||K<g.length;){if(++we>oe)throw Y(),Error(`[elur] Maximum effect re-execution depth exceeded (possible infinite loop).`);if(q++,G>=h.length&&K<g.length&&q>Te&&e.inputPending()){De();return}let n=G<h.length?h[G++]:g[K++];if(n.state&=~a,n.state&o)continue;if(n.state!==r&&!Ce(n)){n.state=t;continue}let i=Math.floor(n._flush/1024),s=(i===W?n._flush-i*1024:0)+1;if(n._flush=W*1024+s,s>b)throw Y(),new x(n,s);n.run()}Y()}function De(){J||(J=!0,e.yieldControl().then(()=>{J=!1,q=0;try{Ee()}catch(e){X(),queueMicrotask(()=>{throw e});return}J||X()}))}function Oe(){if(!U){U=!0,we=0,q=0;try{Ee()}catch(e){throw X(),e}J||X()}}var Z=class{version=0;liveCount=0;durable=!1;consumersHead=null;_v;constructor(e){this._v=e,w?.onCreate?.(this,e)}get value(){return u&&pe(this,u),this._v}set value(e){if(this.durable){console.warn(`[elur-next2] constSignal: write ignorada — el producer es estático (B.12.4).`);return}Object.is(this._v,e)||(this._v=e,w?.onWrite?.(this,e),this.version++,c++,he(this))}update(e){this.value=e(this._v)}peek(){return this._v}dispose(){for(;this.consumersHead;){let e=this.consumersHead;P(this,e),e.prevSource?e.prevSource.nextSource=e.nextSource:e.target.sourcesHead=e.nextSource,e.nextSource&&(e.nextSource.prevSource=e.prevSource),M(e)}I()}},Q=class extends Z{state=t;sourcesHead=null;evalMark=0;lastCleanEpoch=-1;childrenHead=null;childCount=0;nextOwned=null;prevOwned=null;cleanups=null;parent=null;_value;fn;equals;flags=0;_pCursor=null;_pLink=null;constructor(e,t=Object.is){super(void 0),this.fn=e,this.equals=t,v(this)}live(){return this.consumersHead!==null}get value(){return this.flags&ee||(this.flags|=ee,this.state=r),Se(this),u&&pe(this,u),this._value}peek(){return this._value}dispose(){this.state=o,_(this),this.evalMark++,L(this);let e=this.consumersHead;for(;e;){let t=e.nextTarget;P(this,e),e.prevSource?e.prevSource.nextSource=e.nextSource:e.target.sourcesHead=e.nextSource,e.nextSource&&(e.nextSource.prevSource=e.prevSource),M(e),e=t}this.sourcesHead=null,I(),y(this)}},ke=class{state=t;sourcesHead=null;evalMark=0;childrenHead=null;childCount=0;nextOwned=null;prevOwned=null;cleanups=null;parent=null;flags=0;_flush=0;_fn;_cleanup=void 0;_errorHandler;constructor(e,t=!1){this._fn=e,t&&(this.flags|=p),this._errorHandler=C,v(this)}live(){return!0}run(){if(this.flags&m)return;if(this.state&i)throw Error(`[elur-next] Effect re-entrante detectado.`);typeof this._cleanup==`function`&&this._cleanup(),(this.childrenHead!==null||this.cleanups!==null)&&_(this),this.evalMark++;let e=u,n=d;u=this,d=this,this.state=i;let a=!0;try{this._cleanup=this._fn(),a=!1}catch(e){if(this._errorHandler)this._errorHandler(e),a=!1;else{let t=!1;for(let n=this.parent;n;n=n.parent)if(n.onOwnerError?.(e)){t=!0;break}if(t)a=!1;else throw e}}finally{u=e,d=n,a&&this.state&i&&(this.state=r)}L(this),this.state=t}dispose(){this.flags&m||(this.flags|=m,this.state=o,typeof this._cleanup==`function`&&this._cleanup(),_(this),this.evalMark++,L(this),y(this))}};function Ae(e){return new Z(e)}function je(e){let t=new Z(e);return t.durable=!0,t}function Me(e,t=Object.is){return new Q(e,t)}function Ne(e){let t=new ke(e);return t.run(),()=>t.dispose()}function Pe(e){let t=new ke(e,!0);return t.run(),()=>t.dispose()}function Fe(e){l++;try{return e()}finally{l--,l===0&&Oe()}}function $(e){let t=u;u=null;try{return e()}finally{u=t}}function Ie(e,t,n={}){let{immediate:r=!1,once:i=!1}=n,a=e instanceof Z?()=>e.value:e,o=!0,s,c=()=>{};return c=Ne(()=>{let e=a();if(o&&(o=!1,!r)){s=e;return}t(e,s),s=e,i&&c()}),c}function Le(e){return Promise.resolve().then(e)}var Re=class{state=t;flags=p;_flush=0;sourcesHead=null;evalMark=0;childrenHead=null;childCount=0;nextOwned=null;prevOwned=null;cleanups=null;parent=null;_fn;_node;constructor(e,t){this._fn=e,this._node=t,v(this)}live(){return!0}run(){if(this.flags&m||this.state&i)return;(this.childrenHead!==null||this.cleanups!==null)&&_(this),this.evalMark++;let e=u,n=d;u=this,d=this,this.state=i;try{let e=this._fn();this._node.nodeValue=e==null||e===!1?``:String(e)}finally{u=e,d=n}L(this),this.state=t}dispose(){this.flags&m||(this.flags|=m,this.state=o,_(this),this.evalMark++,L(this),y(this))}};function ze(e,t){let n=new Re(t,e);return n.run(),()=>n.dispose()}var Be=class{state=t;flags=p;_flush=0;sourcesHead=null;evalMark=0;childrenHead=null;childCount=0;nextOwned=null;prevOwned=null;cleanups=null;parent=null;_source;_link=null;_write;_prev;constructor(e,t){if(this._source=e,this._write=t,this._prev=e instanceof Q?$(()=>e.value):e.peek(),t(this._prev),v(this),!e.durable){let t=j(e,this,e.version,0);t.nextSource=null,this._link=t,this.sourcesHead=t,N(e,t),D.length&&F()}}live(){return!0}run(){let e=this._source.peek();this._link&&(this._link.seenVersion=this._source.version),e!==this._prev&&(this._prev=e,this._write(e)),this.state=t}dispose(){this.flags&m||(this.flags|=m,this.state=o,this._link&&(P(this._source,this._link),M(this._link),this._link=null,this.sourcesHead=null),y(this))}};function Ve(e,t){let n=new Be(e,t);return()=>n.dispose()}var He=class{state=t;flags=p;_flush=0;sourcesHead=null;evalMark=0;childrenHead=null;childCount=0;nextOwned=null;prevOwned=null;cleanups=null;parent=null;_source;_link=null;_get;_write;_prev;constructor(e,t,n){if(this._source=e,this._get=t,this._write=n,this._prev=$(t),n(this._prev),v(this),!e.durable){let t=j(e,this,e.version,0);t.nextSource=null,this._link=t,this.sourcesHead=t,N(e,t),D.length&&F()}}live(){return!0}run(){let e=$(this._get);this._link&&(this._link.seenVersion=this._source.version),e!==this._prev&&(this._prev=e,this._write(e)),this.state=t}dispose(){this.flags&m||(this.flags|=m,this.state=o,this._link&&(P(this._source,this._link),M(this._link),this._link=null,this.sourcesHead=null),y(this))}};function Ue(e,t,n){let r=new He(e,t,n);return()=>r.dispose()}exports.Computed=Q,exports.Owner=te,exports.ReactiveCycleError=x,exports.Signal=Z,exports._addSignalDebugHooks=ue,exports._bindDerived=Ue,exports._bindSignal=Ve,exports._bindText=ze,exports._getNotifyBufSize=de,exports._popErrorHandler=ce,exports._pushErrorHandler=se,exports._renderEffect=Pe,exports._setSignalDebugHooks=le,exports.batch=Fe,exports.computed=Me,exports.constSignal=je,exports.createRoot=ie,exports.effect=Ne,exports.getOwner=ne,exports.nextTick=Le,exports.onCleanup=ae,exports.runWithOwner=re,exports.signal=Ae,exports.untrack=$,exports.watch=Ie;
|
|
2
|
+
//# sourceMappingURL=reactivity.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactivity.cjs","names":[],"sources":["../../../../src/elur/next-2/reactivity.ts"],"sourcesContent":["/**\n * Elur \"next\" — grafo reactivo push-pull versionado (experimental).\n *\n * Módulo aislado de `../reactivity.ts` (PLAN_TECNICO_ELUR_NEXT §B.3–B.9):\n * nunca importar ambos en el mismo path de producción — mezclar signals de\n * dos grafos rompe la semántica.\n *\n * Modelo:\n * - PUSH: signal.set() → version++ → invalida consumidores (DIRTY directos,\n * CHECK transitivos) y encola effects una sola vez. No recalcula nada.\n * - PULL: antes de ejecutar un effect se estabilizan sus fuentes — los\n * computeds DIRTY/CHECK se refrescan recursivamente y sólo propagan si el\n * resultado realmente cambió (early cutoff por versión).\n * - Liveness: un computed sin consumidores vivos no se suscribe a sus\n * fuentes; se refresca por sondeo de versiones al leerse (O(1) si el\n * epoch global no cambió).\n * - Edges: `Link` doble-enlazado compartido entre la lista de sources del\n * consumidor y la de consumers del productor — subscribe/remove O(1),\n * reutilizados entre evaluaciones (mark & sweep por `evalMark`).\n */\n\nimport { inputPending, yieldControl } from \"./scheduler.js\";\n\n// --- Estados del grafo (B.4) ------------------------------------------------\n\nconst CLEAN = 0;\nconst CHECK = 1 << 0;\nconst DIRTY = 1 << 1;\nconst RUNNING = 1 << 2;\nconst ENQUEUED = 1 << 3;\nconst DISPOSED = 1 << 4;\n/** B.12.1: nodo en el stack del DFS de refresh — detecta back-edges (ciclos). */\nconst PROBING = 1 << 5;\n\n// --- Estado global del grafo -------------------------------------------------\n\nlet globalEpoch = 0;\nlet batchLevel = 0;\nlet activeConsumer: ConsumerNode | null = null;\n/** Owner activo: los consumidores creados aquí dentro le pertenecen (B.10). */\nlet activeOwner: OwnerLike | null = null;\n/** Flags de shape: booleans colapsados en un int (anexo §1.12 bitflags). */\nconst F_HAS_VALUE = 1 << 0;\nconst F_EVALUATED = 1 << 1;\nconst F_RENDER = 1 << 2;\nconst F_DEAD = 1 << 3;\n\n/** Cualquier consumidor no-computed encolable al flush (effects, bindings). */\ninterface Flushable extends ConsumerNode {\n /** Bitflags: F_RENDER → cola de render; F_DEAD → dispuesto. */\n flags: number;\n /** B.9: gen*1024 + corridas en el flush (epoch → sin reset loop). */\n _flush: number;\n run(): void;\n}\n\n/** B.8: colas separadas — render effects (bindings DOM) antes que user effects. */\nconst renderQueue: Flushable[] = [];\nconst effectQueue: Flushable[] = [];\n\n// --- Ownership (B.10 / A.11) --------------------------------------------------\n\n/** Cualquier cosa que pueda poseer consumidores: Owner raíz, Effect, Computed. */\nexport interface OwnerLike {\n /**\n * Cabeza de la lista doblemente enlazada de hijos poseídos (effects,\n * computeds, sub-owners). Lista intrusiva — el unregistro de un hijo es\n * O(1) (antes: array con indexOf+splice O(n), que hacía el clear de\n * listas grandes O(n²) — el gap de `09_clear1k` en Krausest).\n */\n childrenHead: (Disposable & OwnerLike) | null;\n /** Número de hijos vivos — `childCount` para diagnóstico/tests. */\n childCount: number;\n /** Cleanups registrados con onCleanup() durante la última evaluación. */\n cleanups: (() => void)[] | null;\n /** Owner que era activo cuando este nodo fue creado (árbol de owners). */\n parent: OwnerLike | null;\n /** Links intrusivos al sibling anterior/siguiente en la lista del padre. */\n nextOwned: (Disposable & OwnerLike) | null;\n prevOwned: (Disposable & OwnerLike) | null;\n /**\n * A.16: boundary por owner — un consumidor sin handler propio burbujea\n * el error por la cadena de owners hasta que uno lo maneja (true).\n */\n onOwnerError?: (err: unknown) => boolean;\n}\n\nexport interface Disposable {\n dispose(): void;\n}\n\n/** Raíz de ownership explícita (un mount, un test, un sub-árbol). */\nexport class Owner implements OwnerLike, Disposable {\n childrenHead: (Disposable & OwnerLike) | null = null;\n childCount = 0;\n cleanups: (() => void)[] | null = null;\n parent: OwnerLike | null = null;\n nextOwned: (Disposable & OwnerLike) | null = null;\n prevOwned: (Disposable & OwnerLike) | null = null;\n onOwnerError?: (err: unknown) => boolean;\n private _disposed = false;\n\n dispose(): void {\n if (this._disposed) return;\n this._disposed = true;\n disposeOwnerChildren(this);\n unown(this);\n }\n}\n\nfunction disposeOwnerChildren(o: OwnerLike): void {\n if (o.cleanups) {\n for (const fn of o.cleanups) fn();\n o.cleanups = null;\n }\n // Detach-first: se camina la lista con los punteros del hijo ya\n // limpiados, así unown() dentro de dispose() del hijo es no-op y no\n // muta la cadena que se está recorriendo.\n let child = o.childrenHead;\n o.childrenHead = null;\n o.childCount = 0;\n while (child) {\n const next = child.nextOwned;\n child.nextOwned = null;\n child.prevOwned = null;\n child.parent = null;\n child.dispose();\n child = next;\n }\n}\n\nfunction own(d: Disposable & OwnerLike): void {\n if (!activeOwner) return;\n d.parent = activeOwner;\n const head = activeOwner.childrenHead;\n d.nextOwned = head;\n d.prevOwned = null;\n if (head) head.prevOwned = d;\n activeOwner.childrenHead = d;\n activeOwner.childCount++;\n}\n\n/** Des-registrar del padre — O(1) por links intrusivos. */\nfunction unown(d: Disposable & OwnerLike): void {\n const p = d.parent;\n d.parent = null;\n if (d.prevOwned) d.prevOwned.nextOwned = d.nextOwned;\n else if (p) p.childrenHead = d.nextOwned;\n if (d.nextOwned) d.nextOwned.prevOwned = d.prevOwned;\n d.nextOwned = null;\n d.prevOwned = null;\n if (p) p.childCount--;\n}\n\n/** Owner actual — para diagnóstico e integración con el kernel de mounts. */\nexport function getOwner(): OwnerLike | null {\n return activeOwner;\n}\n\n/**\n * Ejecuta fn con `owner` como dueño activo. Todo effect/computed creado\n * dentro queda poseído por él y se destruye con él.\n */\nexport function runWithOwner<T>(owner: OwnerLike | null, fn: () => T): T {\n const prevOwner = activeOwner;\n const prevConsumer = activeConsumer;\n activeOwner = owner;\n activeConsumer = null;\n try {\n return fn();\n } finally {\n activeOwner = prevOwner;\n activeConsumer = prevConsumer;\n }\n}\n\n/**\n * Raíz reactiva: `const dispose = createRoot(d => {...})`. Todo lo creado\n * dentro muere con `dispose()` — elimina la clase de leaks de B.2.5.\n */\nexport function createRoot<T>(fn: (dispose: () => void) => T): T {\n const root = new Owner();\n root.parent = activeOwner;\n return runWithOwner(root, () => fn(() => root.dispose()));\n}\n\n/** Registra una limpieza en el owner activo (effect, computed o root). */\nexport function onCleanup(fn: () => void): void {\n if (activeOwner) (activeOwner.cleanups ??= []).push(fn);\n}\n\n/** Cap de seguridad para writes re-entrantes en effects (B.9). */\nconst MAX_FLUSH_STEPS = 10_000;\n/** B.9: máximo de corridas de UN efecto dentro de un mismo flush. */\nconst MAX_RUNS_PER_FLUSH = 100;\n\n/**\n * B.9: ciclo de efectos — un write dentro de un effect re-encola trabajo; si\n * un nodo corre más de MAX_RUNS_PER_FLUSH en el mismo flush, es un bucle.\n * El mensaje incluye el camino de dependencias del efecto (sus fuentes y,\n * si son computeds, las suyas) para localizar el ciclo.\n */\nexport class ReactiveCycleError extends Error {\n constructor(effect: ConsumerNode, runs: number) {\n const path: string[] = [];\n for (let l = effect.sourcesHead; l; l = l.nextSource) {\n const p = l.source;\n path.push(p instanceof Computed ? `computed(v${p.version})` : `signal(v${p.version})`);\n if (path.length >= 8) { path.push(\"…\"); break; }\n }\n super(\n `[elur] Maximum effect re-execution depth exceeded (possible infinite loop). ` +\n `Ciclo de efectos: un effect corrió ${runs} veces en un solo flush ` +\n `(límite por nodo ${MAX_RUNS_PER_FLUSH}). Fuentes del effect: ` +\n `[${path.join(\", \")}]. Probable write-inside-effect que se re-encola a sí mismo.`,\n );\n this.name = \"ReactiveCycleError\";\n }\n}\n\n// --- Superficie interna (paridad con reactivity.ts para el swap de tests) -----\n\ninterface ErrorHandler {\n (err: unknown): void;\n}\nconst errorHandlerStack: ErrorHandler[] = [];\nlet activeErrorHandler: ErrorHandler | null = null;\n\n/** @internal */\nexport function _pushErrorHandler(h: ErrorHandler): void {\n errorHandlerStack.push(activeErrorHandler as ErrorHandler);\n activeErrorHandler = h;\n}\n\n/** @internal */\nexport function _popErrorHandler(): void {\n activeErrorHandler = errorHandlerStack.pop() ?? null;\n}\n\nexport interface _SignalDebugHooks {\n onCreate?: (signal: Signal<any>, initialValue: unknown) => void;\n onWrite?: (signal: Signal<any>, value: unknown) => void;\n}\n\nlet signalDebugHooks: _SignalDebugHooks | null = null;\nlet signalDebugHookSet: Set<_SignalDebugHooks> | null = null;\n\nfunction _syncSignalDebugHooks(): void {\n const set = signalDebugHookSet;\n if (!set || set.size === 0) {\n signalDebugHooks = null;\n return;\n }\n if (set.size === 1) {\n signalDebugHooks = set.values().next().value ?? null;\n return;\n }\n signalDebugHooks = {\n onCreate(signal, initialValue) {\n for (const hooks of set) hooks.onCreate?.(signal, initialValue);\n },\n onWrite(signal, value) {\n for (const hooks of set) hooks.onWrite?.(signal, value);\n },\n };\n}\n\n/** @internal */\nexport function _setSignalDebugHooks(hooks: _SignalDebugHooks | null): void {\n const set = new Set<_SignalDebugHooks>();\n if (hooks) set.add(hooks);\n signalDebugHookSet = set;\n _syncSignalDebugHooks();\n}\n\n/** @internal — añade suscriptor sin reemplazar; devuelve unsubscribe. */\nexport function _addSignalDebugHooks(hooks: _SignalDebugHooks): () => void {\n let set = signalDebugHookSet;\n if (!set) {\n set = new Set<_SignalDebugHooks>();\n if (signalDebugHooks) set.add(signalDebugHooks);\n signalDebugHookSet = set;\n }\n set.add(hooks);\n _syncSignalDebugHooks();\n return () => {\n set.delete(hooks);\n _syncSignalDebugHooks();\n };\n}\n\n/** @internal — la nueva impl no tiene notify buffer; se expone para paridad. */\nexport function _getNotifyBufSize(): number {\n return 0;\n}\n\ninterface ProducerNode {\n /** Incrementa en cada cambio real de valor. */\n version: number;\n /**\n * B.12.4 (durabilidad, Salsa): producer estático — nunca cambia.\n * `link()` no crea edge: cero bookkeeping para deps estáticas.\n */\n durable?: boolean;\n /** Nº de links vivos en `consumersHead` (liveness del productor). */\n liveCount: number;\n consumersHead: Link | null;\n}\n\n/**\n * Edge compartido: vive en dos listas a la vez — la de sources del consumer\n * (`nextSource/prevSource`) y la de consumers del producer\n * (`nextTarget/prevTarget`). `mark` lo usa el consumer para decidir qué\n * links sobrevivieron a la última evaluación; `linked` indica si está\n * insertado en la lista del producer (los computeds fríos no lo están).\n */\ninterface Link {\n source: ProducerNode;\n target: ConsumerNode;\n seenVersion: number;\n mark: number;\n linked: boolean;\n nextSource: Link | null;\n prevSource: Link | null;\n nextTarget: Link | null;\n prevTarget: Link | null;\n}\n\ninterface ConsumerNode {\n state: number;\n sourcesHead: Link | null;\n /** Contador de evaluación — marca los links usados en esta pasada. */\n evalMark: number;\n live(): boolean;\n}\n\n// --- Gestión de links ---------------------------------------------------------\n\n// B.12.1: colas de liveness — un computed que gana/pierde su última\n// suscripción se encola; el drenado ocurre en puntos seguros (link/sweep),\n// nunca recursivamente (las cadenas profundas no comen call stack).\nconst acquireQueue: Computed<unknown>[] = [];\nconst releaseQueue: Computed<unknown>[] = [];\n\n// F3: freelist de Links — las edges de bindings/effects se allocan y mueren\n// en masa al montar/clear listas; reciclarlas evita el churn de GC. Un link\n// sólo entra al pool cuando está muerto de verdad (fuera de AMBAS listas);\n// los que quedan colgados en `sourcesHead` de un consumidor vivo (muerte del\n// producer) los barre `sweep` después — nunca se poolan referencias vivas.\n// `nextSource` hace de puntero de freelist. Cap: evita retener picos.\nlet linkPool: Link | null = null;\nlet linkPoolSize = 0;\nconst LINK_POOL_MAX = 8192;\n\nfunction allocLink(\n source: ProducerNode,\n target: ConsumerNode,\n seenVersion: number,\n mark: number,\n): Link {\n const l = linkPool;\n if (l) {\n linkPool = l.nextSource;\n linkPoolSize--;\n l.source = source;\n l.target = target;\n l.seenVersion = seenVersion;\n l.mark = mark;\n l.linked = false;\n l.prevSource = null;\n l.nextTarget = null;\n l.prevTarget = null;\n // `nextSource` lo fija el caller (o queda null en bindings de 1 dep).\n return l;\n }\n return {\n source, target, seenVersion, mark,\n linked: false,\n nextSource: null, prevSource: null, nextTarget: null, prevTarget: null,\n };\n}\n\nfunction freeLink(l: Link): void {\n if (linkPoolSize >= LINK_POOL_MAX) return;\n // Soltar refs: un link pooled no debe retener productor ni consumidor.\n l.source = null as unknown as ProducerNode;\n l.target = null as unknown as ConsumerNode;\n l.nextTarget = null;\n l.prevTarget = null;\n l.prevSource = null;\n l.nextSource = linkPool;\n linkPool = l;\n linkPoolSize++;\n}\n\nfunction producerAddLink(p: ProducerNode, l: Link): void {\n l.nextTarget = p.consumersHead;\n l.prevTarget = null;\n if (p.consumersHead) p.consumersHead.prevTarget = l;\n p.consumersHead = l;\n l.linked = true;\n p.liveCount++;\n // Si el producer es un computed que acaba de ganar su primer consumidor,\n // hay que suscribirlo a SUS fuentes (podía estar frío) — encolado.\n if (p.liveCount === 1 && p instanceof Computed) acquireQueue.push(p);\n}\n\nfunction producerRemoveLink(p: ProducerNode, l: Link): void {\n if (!l.linked) return;\n if (l.prevTarget) l.prevTarget.nextTarget = l.nextTarget;\n else p.consumersHead = l.nextTarget;\n if (l.nextTarget) l.nextTarget.prevTarget = l.prevTarget;\n l.linked = false;\n p.liveCount--;\n if (p.liveCount === 0 && p instanceof Computed) releaseQueue.push(p);\n}\n\n/** Drena adquisiciones: cada computed vivo se suscribe a sus fuentes. */\nfunction drainAcquireQueue(): void {\n while (acquireQueue.length) {\n const cur = acquireQueue.pop()!;\n for (let l = cur.sourcesHead; l; l = l.nextSource) {\n if (!l.linked) producerAddLink(l.source, l);\n }\n }\n}\n\n/** Drena liberaciones: cada computed frío se des-suscribe de sus fuentes. */\nfunction drainReleaseQueue(): void {\n while (releaseQueue.length) {\n const cur = releaseQueue.pop()!;\n for (let l = cur.sourcesHead; l; l = l.nextSource) {\n producerRemoveLink(l.source, l);\n }\n }\n}\n\nfunction link(producer: ProducerNode, consumer: ConsumerNode): void {\n // B.12.4: producers estáticos nunca invalidan — no registramos la edge.\n if (producer.durable) return;\n // Reutilizar el Link si ya existe (scan lineal — n de fuentes es típicamente\n // pequeño; el orden de deps suele ser estable entre evaluaciones).\n for (let l = consumer.sourcesHead; l; l = l.nextSource) {\n if (l.source === producer) {\n l.seenVersion = producer.version;\n l.mark = consumer.evalMark;\n return;\n }\n }\n const l = allocLink(producer, consumer, producer.version, consumer.evalMark);\n l.nextSource = consumer.sourcesHead;\n if (consumer.sourcesHead) consumer.sourcesHead.prevSource = l;\n consumer.sourcesHead = l;\n if (consumer.live()) {\n producerAddLink(producer, l);\n if (acquireQueue.length) drainAcquireQueue();\n }\n}\n\n/** Elimina los links no re-usados en la última evaluación del consumidor. */\nfunction sweep(consumer: ConsumerNode): void {\n let l = consumer.sourcesHead;\n while (l) {\n const next = l.nextSource;\n if (l.mark !== consumer.evalMark) {\n if (l.prevSource) l.prevSource.nextSource = l.nextSource;\n else consumer.sourcesHead = l.nextSource;\n if (l.nextSource) l.nextSource.prevSource = l.prevSource;\n producerRemoveLink(l.source, l);\n freeLink(l);\n }\n l = next;\n }\n if (releaseQueue.length) drainReleaseQueue();\n}\n\n// --- Invalidación (fase push) ------------------------------------------------\n\n/**\n * B.12.1: worklist compartida para la cascada CHECK — marcado iterativo\n * sin call stack (anexo: DFS iterativo alien-signals). Segura porque el\n * marcado no corre código de usuario: se vacía antes de retornar.\n */\nconst checkWorklist: Link[] = [];\n\nfunction markDirty(c: ConsumerNode): void {\n if (c.state & (DIRTY | DISPOSED)) return;\n // Un computed RUNNING es un ciclo → se ignora aquí y revienta en refresh.\n // Un effect RUNNING es write-inside-effect → se re-encola (cap de flush).\n if (c instanceof Computed && c.state & RUNNING) return;\n c.state = DIRTY;\n if (c instanceof Computed) {\n // Cascada CHECK iterativa sobre el subgrafo de consumidores.\n for (let l = c.consumersHead; l; l = l.nextTarget) {\n const t = l.target;\n if (t.state === CLEAN) {\n t.state = CHECK;\n if (t instanceof Computed) checkWorklist.push(l);\n else enqueue(t as Flushable);\n }\n }\n while (checkWorklist.length) {\n const l = checkWorklist.pop()!;\n // l.target es el computed ya marcado CHECK — seguir a SUS consumidores.\n for (let u = (l.target as Computed<unknown>).consumersHead; u; u = u.nextTarget) {\n const t = u.target;\n if (t.state === CLEAN) {\n t.state = CHECK;\n if (t instanceof Computed) checkWorklist.push(u);\n else enqueue(t as Flushable);\n }\n }\n }\n } else {\n enqueue(c as Flushable);\n }\n}\n\nfunction invalidate(producer: ProducerNode): void {\n for (let l = producer.consumersHead; l; l = l.nextTarget) markDirty(l.target);\n if (batchLevel === 0) flushEffects();\n}\n\n// --- Estabilización (fase pull) ----------------------------------------------\n\n/** Re-evalúa un computed: corre fn() bajo sí mismo como consumer+owner. */\nfunction evalComputed(c: Computed<any>): void {\n // Los hijos poseídos por la pasada anterior mueren antes de re-evaluar.\n if (c.childrenHead !== null || c.cleanups !== null) disposeOwnerChildren(c);\n c.evalMark++;\n const prevConsumer = activeConsumer;\n const prevOwner = activeOwner;\n activeConsumer = c;\n activeOwner = c;\n c.state = RUNNING;\n let result: unknown;\n let threw = true;\n try {\n result = c.fn();\n threw = false;\n } finally {\n activeConsumer = prevConsumer;\n activeOwner = prevOwner;\n if (threw && c.state & RUNNING) c.state = DIRTY; // guard recuperable\n }\n sweep(c);\n c.state = CLEAN;\n c.lastCleanEpoch = globalEpoch;\n if (!(c.flags & F_HAS_VALUE) || !c.equals(result, c._value)) {\n c._value = result;\n c.flags |= F_HAS_VALUE;\n c.version++;\n }\n}\n\n// B.12.1: estado transiente del DFS vive EN el nodo (anexo: DFS manual,\n// cero frames/alloc) — flags empaquetados + cursores.\n// Bits extra en `state` durante el DFS (transientes — se limpian al salir).\nconst _P_STARTED = 1 << 6;\nconst _P_DIRTY = 1 << 7;\nconst _P_CHANGED = 1 << 8;\nconst _P_MASK = _P_STARTED | _P_DIRTY | _P_CHANGED;\n\n/**\n * B.12.1: worklist del DFS de refresh — compartida sólo en llamadas no\n * anidadas; una lectura de computed dentro de una evaluación (fn() puede leer\n * otros computeds) usa un array propio para no mezclar estados.\n */\nconst sharedProbeStack: Computed<any>[] = [];\nlet probeDepth = 0;\n\n/**\n * B.12.1: refresco iterativo (anexo: DFS manual sin call stack).\n * Post-order: las fuentes se resuelven antes que el nodo. El bit PROBING\n * marca nodos en el stack — un back-edge es un ciclo en el DAG.\n */\nfunction refreshComputed(root: Computed<any>): void {\n // Fast path en UNA pasada: necesita DFS si alguna fuente computed no está\n // resuelta; cambio si alguna versión difiere. El orden importa: un computed\n // sin resolver puede tener versión vieja — hay que resolverlo antes de\n // comparar.\n const phase = root.state & (CHECK | DIRTY | RUNNING);\n if (root.state & DISPOSED) return;\n if (phase === RUNNING) {\n throw new Error(\"[elur-next] Ciclo reactivo detectado en computed().\");\n }\n if (phase === 0 && (root.flags & F_HAS_VALUE) && (root.live() || root.lastCleanEpoch === globalEpoch)) {\n return;\n }\n let changed = phase === DIRTY || !(root.flags & F_HAS_VALUE);\n let deep = false;\n for (let l = root.sourcesHead; l; l = l.nextSource) {\n const src = l.source;\n if (\n src instanceof Computed &&\n (!(src.flags & F_HAS_VALUE) || src.state !== CLEAN ||\n (!src.live() && src.lastCleanEpoch !== globalEpoch))\n ) {\n deep = true;\n break;\n }\n if (!changed && src.version !== l.seenVersion) changed = true;\n }\n if (!deep) {\n if (changed) evalComputed(root);\n else {\n root.state = CLEAN;\n root.lastCleanEpoch = globalEpoch;\n for (let l = root.sourcesHead; l; l = l.nextSource) {\n l.seenVersion = l.source.version;\n }\n }\n return;\n }\n const stack: Computed<any>[] = probeDepth++ === 0 ? sharedProbeStack : [];\n try {\n let cur: Computed<any> | undefined = root;\n while (cur) {\n if (!(cur.state & _P_STARTED)) {\n // Primera visita: decidir según la fase baja del estado.\n cur.state |= _P_STARTED;\n cur._pCursor = null;\n cur._pLink = null;\n const phase = cur.state & (CHECK | DIRTY | RUNNING);\n if (cur.state & DISPOSED) { cur.state &= ~PROBING; cur.state &= ~_P_MASK; cur = stack.pop(); continue; }\n if (phase === RUNNING) failCycle(stack, cur);\n if (\n phase === 0 &&\n (cur.flags & F_HAS_VALUE) &&\n (cur.live() || cur.lastCleanEpoch === globalEpoch)\n ) {\n // CLEAN, fresco y con valor — nada que hacer.\n cur.state &= ~_P_MASK;\n cur = stack.pop();\n continue;\n }\n // CHECK/DIRTY, o CLEAN frío con epoch vieja: SIEMPRE descender por las\n // fuentes primero — si evaluáramos un DIRTY directo, su fn() leería\n // el getter de la fuente sin resolver y la recursión volvería por la\n // puerta de atrás (el bug de las cadenas profundas).\n cur.state |= PROBING;\n if (phase === DIRTY) cur.state |= _P_DIRTY;\n cur._pCursor = cur.sourcesHead;\n }\n // Resume tras un descend: chequear el link cuya fuente se resolvió.\n if (cur._pLink) {\n const l = cur._pLink;\n cur._pLink = null;\n if (l.source.version !== l.seenVersion) cur.state |= _P_CHANGED;\n }\n // Avanzar el cursor de fuentes.\n let descended = false;\n while (cur._pCursor) {\n const l = cur._pCursor;\n cur._pCursor = l.nextSource;\n const src = l.source;\n if (\n src instanceof Computed &&\n (!(src.flags & F_HAS_VALUE) || src.state !== CLEAN ||\n (!src.live() && src.lastCleanEpoch !== globalEpoch))\n ) {\n if (src.state & PROBING) failCycle(stack, cur); // back-edge = ciclo\n cur._pLink = l;\n stack.push(cur);\n src.state |= PROBING;\n cur = src;\n descended = true;\n break;\n }\n if (src.version !== l.seenVersion) cur.state |= _P_CHANGED;\n }\n if (descended) continue;\n // Fuentes resueltas.\n cur.state &= ~PROBING;\n if (cur.state & (_P_DIRTY | _P_CHANGED) || !(cur.flags & F_HAS_VALUE)) {\n evalComputed(cur);\n } else {\n cur.state = CLEAN;\n cur.lastCleanEpoch = globalEpoch;\n // Baselines frescas para futuros sondeos (pollCold).\n for (let l = cur.sourcesHead; l; l = l.nextSource) {\n l.seenVersion = l.source.version;\n }\n }\n cur.state &= ~_P_MASK;\n cur._pCursor = null;\n cur._pLink = null;\n cur = stack.pop();\n }\n } finally {\n probeDepth--;\n }\n}\n\nfunction failCycle(stack: Computed<any>[], cur: Computed<any>): never {\n // Limpiar PROBING + transientes en todos los nodos vivos antes de lanzar.\n for (const n of stack) {\n n.state &= ~(PROBING | _P_MASK);\n n._pCursor = null;\n n._pLink = null;\n }\n cur.state &= ~(PROBING | _P_MASK);\n stack.length = 0;\n throw new Error(\"[elur-next] Ciclo reactivo detectado en computed().\");\n}\n\n/** Asegura que un computed esté fresco: pull si dirty, sondeo si frío. */\nfunction ensureFreshComputed(c: Computed<any>): void {\n if (c.state !== CLEAN || (!c.live() && c.lastCleanEpoch !== globalEpoch)) {\n refreshComputed(c);\n }\n}\n\n/** Estabiliza las fuentes de un consumidor; true si algo cambió de verdad. */\nfunction stabilize(consumer: ConsumerNode): boolean {\n let changed = false;\n for (let l = consumer.sourcesHead; l; l = l.nextSource) {\n if (l.source instanceof Computed) ensureFreshComputed(l.source);\n if (l.source.version !== l.seenVersion) changed = true;\n }\n return changed;\n}\n\n// --- Effects ------------------------------------------------------------------\n\nfunction enqueue(e: Flushable): void {\n if (e.state & (ENQUEUED | DISPOSED)) return;\n e.state |= ENQUEUED;\n ((e.flags & F_RENDER) ? renderQueue : effectQueue).push(e);\n}\n\nlet flushing = false;\n/** B.9: id del flush en curso — los contadores por nodo expiran por epoch. */\nlet flushGeneration = 0;\n\n// F5: cursores/steps a nivel módulo — el flush puede ceder el hilo cuando hay\n// input pendiente y la continuación retoma las colas en el mismo orden.\nlet renderCursor = 0;\nlet effectCursor = 0;\nlet flushSteps = 0;\n/** Pasos desde el último yield — cada continuación trabaja un tramo completo\n * antes de volver a ceder (si no, con input sostenido el flush haría\n * yield→continue→yield sin avanzar hasta el cap de pasos). */\nlet stepsSinceYield = 0;\nlet flushContinuationScheduled = false;\n/** Pasos de user-queue antes de considerar ceder el hilo a input pendiente. */\nconst FLUSH_YIELD_STEPS = 256;\n\nconst clearQueues = (): void => {\n renderQueue.length = 0;\n effectQueue.length = 0;\n renderCursor = 0;\n effectCursor = 0;\n};\n\n/** Cierra el epoch del flush exactamente una vez (sync o tras el último yield). */\nfunction finishFlush(): void {\n flushGeneration++; // los stamps viejos expiran solos — sin reset\n flushing = false;\n}\n\nfunction flushLoop(): void {\n while (renderCursor < renderQueue.length || effectCursor < effectQueue.length) {\n if (++flushSteps > MAX_FLUSH_STEPS) {\n clearQueues();\n throw new Error(\n \"[elur] Maximum effect re-execution depth exceeded (possible infinite loop).\"\n );\n }\n // F5: una vez drenada la cola de render, si quedan muchos USER effects y\n // hay input del usuario esperando, cedemos el hilo — la continuación\n // retoma la cola en orden (scheduler.yield → al frente, no al fondo).\n // Los render writes NUNCA ceden: feedback visual en el mismo turno (INP).\n stepsSinceYield++;\n if (\n renderCursor >= renderQueue.length &&\n effectCursor < effectQueue.length &&\n stepsSinceYield > FLUSH_YIELD_STEPS &&\n inputPending()\n ) {\n scheduleFlushContinuation();\n return;\n }\n // Orden B.8: render effects primero, luego user effects.\n const e = renderCursor < renderQueue.length\n ? renderQueue[renderCursor++]\n : effectQueue[effectCursor++];\n e.state &= ~ENQUEUED;\n if (e.state & DISPOSED) continue;\n // Fast-path DIRTY: una fuente directa escribió → el cambio es real por\n // construcción; los computeds CHECK se refrescan lazy en el getter.\n // Sólo los effects CHECK (invalidados vía computed) necesitan stabilize()\n // para el early-cutoff de falsas alarmas.\n if (e.state !== DIRTY && !stabilize(e)) {\n e.state = CLEAN;\n continue;\n }\n // B.9: contador por nodo por flush (epoch stamp — sin reset loop) —\n // identifica el efecto exacto del ciclo.\n const gen = Math.floor(e._flush / 1024);\n const runs = (gen === flushGeneration ? e._flush - gen * 1024 : 0) + 1;\n e._flush = flushGeneration * 1024 + runs;\n if (runs > MAX_RUNS_PER_FLUSH) {\n clearQueues();\n throw new ReactiveCycleError(e, runs);\n }\n e.run();\n }\n clearQueues();\n}\n\nfunction scheduleFlushContinuation(): void {\n if (flushContinuationScheduled) return;\n flushContinuationScheduled = true;\n void yieldControl().then(() => {\n flushContinuationScheduled = false;\n stepsSinceYield = 0; // nuevo tramo — trabaja antes de volver a ceder\n try {\n flushLoop();\n } catch (err) {\n finishFlush();\n // El error ya no puede lanzar sync al caller — misma visibilidad que\n // una excepción de efecto async: uncaught error.\n queueMicrotask(() => {\n throw err;\n });\n return;\n }\n if (!flushContinuationScheduled) finishFlush();\n });\n}\n\nfunction flushEffects(): void {\n // Re-entrante: si un write dentro de un effect encola más trabajo, lo\n // procesa el MISMO bucle (o la continuación ya agendada tras un yield) —\n // así el cap MAX_FLUSH_STEPS sí protege contra bucles de writes (antes\n // cada flush anidado tenía su propio contador y el bucle reventaba por\n // stack overflow en vez de por el guard).\n if (flushing) return;\n flushing = true;\n flushSteps = 0;\n stepsSinceYield = 0;\n try {\n flushLoop();\n } catch (err) {\n finishFlush();\n throw err;\n }\n // Si el loop cedió, `flushing` sigue true durante el gap — writes reentrantes\n // encolan sin arrancar otro flush y la continuación los drena en orden.\n if (!flushContinuationScheduled) finishFlush();\n}\n\n// --- API -----------------------------------------------------------------------\n\nexport class Signal<T> implements ProducerNode {\n version = 0;\n liveCount = 0;\n durable = false;\n consumersHead: Link | null = null;\n private _v: T;\n\n constructor(initialValue: T) {\n this._v = initialValue;\n signalDebugHooks?.onCreate?.(this, initialValue);\n }\n\n get value(): T {\n if (activeConsumer) link(this, activeConsumer);\n return this._v;\n }\n\n set value(newValue: T) {\n if (this.durable) {\n console.warn(\"[elur-next2] constSignal: write ignorada — el producer es estático (B.12.4).\");\n return;\n }\n if (Object.is(this._v, newValue)) return;\n this._v = newValue;\n signalDebugHooks?.onWrite?.(this, newValue);\n this.version++;\n globalEpoch++;\n invalidate(this);\n }\n\n update(fn: (current: T) => T): void {\n this.value = fn(this._v);\n }\n\n peek(): T {\n return this._v;\n }\n\n dispose(): void {\n while (this.consumersHead) {\n const l = this.consumersHead;\n producerRemoveLink(this, l);\n // También quitar el link de la lista de sources del consumidor.\n if (l.prevSource) l.prevSource.nextSource = l.nextSource;\n else l.target.sourcesHead = l.nextSource;\n if (l.nextSource) l.nextSource.prevSource = l.prevSource;\n freeLink(l); // muerto de verdad: fuera de las dos listas\n }\n drainReleaseQueue();\n }\n}\n\n// Computed extiende Signal por paridad con la impl actual: el resto del\n// runtime (store, watch, templates) hace `x instanceof Signal`.\nexport class Computed<T> extends Signal<T> implements ConsumerNode, OwnerLike {\n state: number = CLEAN;\n sourcesHead: Link | null = null;\n evalMark = 0;\n /** Último epoch en que se verificó fresco — sondeo O(1) para fríos. */\n lastCleanEpoch = -1;\n childrenHead: (Disposable & OwnerLike) | null = null;\n childCount = 0;\n nextOwned: (Disposable & OwnerLike) | null = null;\n prevOwned: (Disposable & OwnerLike) | null = null;\n cleanups: (() => void)[] | null = null;\n parent: OwnerLike | null = null;\n _value: T | undefined;\n fn: () => T;\n equals: (a: T, b: T) => boolean;\n flags = 0;\n /** B.12.1: transientes del DFS de refresh (null entre refreshes). */\n _pCursor: Link | null = null;\n _pLink: Link | null = null;\n\n constructor(fn: () => T, equals: (a: T, b: T) => boolean = Object.is) {\n super(undefined as T); // el valor real lo gestiona _value/_evaluated\n this.fn = fn;\n this.equals = equals;\n own(this);\n }\n\n live(): boolean {\n return this.consumersHead !== null;\n }\n\n get value(): T {\n // Refrescar antes de linkear: el consumidor debe registrar la versión\n // post-refresh, no la vieja (si no, stabilize() vería un falso cambio).\n if (!(this.flags & F_EVALUATED)) {\n this.flags |= F_EVALUATED;\n this.state = DIRTY;\n }\n ensureFreshComputed(this);\n if (activeConsumer) link(this, activeConsumer);\n return this._value as T;\n }\n\n peek(): T {\n return this._value as T;\n }\n\n dispose(): void {\n this.state = DISPOSED;\n disposeOwnerChildren(this);\n this.evalMark++; // primero: sweep quita TODOS los links (mark !== evalMark)\n sweep(this);\n let l = this.consumersHead;\n while (l) {\n const next = l.nextTarget;\n producerRemoveLink(this, l);\n // El link también sale de la lista de fuentes del consumidor — así\n // muere completo y puede reciclarse (antes quedaba colgado hasta el\n // próximo sweep del consumidor).\n if (l.prevSource) l.prevSource.nextSource = l.nextSource;\n else l.target.sourcesHead = l.nextSource;\n if (l.nextSource) l.nextSource.prevSource = l.prevSource;\n freeLink(l);\n l = next;\n }\n this.sourcesHead = null;\n drainReleaseQueue();\n unown(this);\n }\n}\n\nclass EffectNode implements ConsumerNode, OwnerLike {\n state: number = CLEAN;\n sourcesHead: Link | null = null;\n evalMark = 0;\n childrenHead: (Disposable & OwnerLike) | null = null;\n childCount = 0;\n nextOwned: (Disposable & OwnerLike) | null = null;\n prevOwned: (Disposable & OwnerLike) | null = null;\n cleanups: (() => void)[] | null = null;\n parent: OwnerLike | null = null;\n flags = 0;\n _flush = 0;\n private _fn: () => void | (() => void);\n private _cleanup: (() => void) | void = undefined;\n private _errorHandler: ErrorHandler | null;\n\n constructor(fn: () => void | (() => void), render = false) {\n this._fn = fn;\n if (render) this.flags |= F_RENDER;\n this._errorHandler = activeErrorHandler;\n own(this);\n }\n\n live(): boolean {\n return true;\n }\n\n run(): void {\n if (this.flags & F_DEAD) return;\n if (this.state & RUNNING) {\n throw new Error(\"[elur-next] Effect re-entrante detectado.\");\n }\n if (typeof this._cleanup === \"function\") this._cleanup();\n // Los hijos (effects/computeds/cleanups creados en la pasada anterior)\n // mueren antes de re-evaluar — evita leaks de computations anidadas.\n // Guard inline: la mayoría de los effects no posee nada — salta la llamada.\n if (this.childrenHead !== null || this.cleanups !== null) disposeOwnerChildren(this);\n this.evalMark++;\n const prevConsumer = activeConsumer;\n const prevOwner = activeOwner;\n activeConsumer = this;\n activeOwner = this;\n this.state = RUNNING;\n let threw = true;\n try {\n this._cleanup = this._fn();\n threw = false;\n } catch (err) {\n if (this._errorHandler) {\n this._errorHandler(err);\n threw = false;\n } else {\n // A.16: burbujear por la cadena de owners hasta una boundary.\n let handled = false;\n for (let o: OwnerLike | null = this.parent; o; o = o.parent) {\n if (o.onOwnerError?.(err)) { handled = true; break; }\n }\n if (handled) threw = false;\n else throw err;\n }\n } finally {\n activeConsumer = prevConsumer;\n activeOwner = prevOwner;\n if (threw && this.state & RUNNING) this.state = DIRTY; // guard recuperable\n }\n sweep(this);\n this.state = CLEAN;\n }\n\n dispose(): void {\n if (this.flags & F_DEAD) return;\n this.flags |= F_DEAD;\n this.state = DISPOSED;\n if (typeof this._cleanup === \"function\") this._cleanup();\n disposeOwnerChildren(this);\n this.evalMark++;\n sweep(this);\n unown(this);\n }\n}\n\n// --- Factories ------------------------------------------------------------------\n\nexport function signal<T>(initialValue: T): Signal<T> {\n return new Signal(initialValue);\n}\n\n/**\n * B.12.4 (durabilidad): signal estática — `link()` no crea edges sobre ella,\n * así que dependencias estáticas no cuestan bookkeeping ni checks de refresh.\n * Escribirla rompe el contrato (warn en dev); el valor no se propaga.\n */\nexport function constSignal<T>(value: T): Signal<T> {\n const s = new Signal(value);\n s.durable = true;\n return s;\n}\n\nexport function computed<T>(\n fn: () => T,\n equals: (a: T, b: T) => boolean = Object.is,\n): Computed<T> {\n return new Computed(fn, equals);\n}\n\n/** Corre una vez al crear; re-corre sólo si una fuente cambió de verdad. */\nexport function effect(fn: () => void | (() => void)): () => void {\n const node = new EffectNode(fn);\n node.run();\n return () => node.dispose();\n}\n\n/**\n * @internal — effect de render (bindings DOM internos): se encola en la\n * cola de render, que se drena ANTES que la de user effects (B.8). La API\n * pública `effect()` sigue siendo la de usuario.\n */\nexport function _renderEffect(fn: () => void | (() => void)): () => void {\n const node = new EffectNode(fn, true);\n node.run();\n return () => node.dispose();\n}\n\nexport function batch<T>(fn: () => T): T {\n batchLevel++;\n try {\n return fn();\n } finally {\n batchLevel--;\n if (batchLevel === 0) flushEffects();\n }\n}\n\nexport function untrack<T>(fn: () => T): T {\n const prev = activeConsumer;\n activeConsumer = null;\n try {\n return fn();\n } finally {\n activeConsumer = prev;\n }\n}\n\nexport interface WatchOptions {\n immediate?: boolean;\n once?: boolean;\n}\n\nexport function watch<T>(\n source: Signal<T> | (() => T),\n cb: (value: T, oldValue: T | undefined) => void,\n options: WatchOptions = {},\n): () => void {\n const { immediate = false, once = false } = options;\n const getter: () => T =\n source instanceof Signal ? () => source.value : source;\n let first = true;\n let old: T | undefined;\n let stop: () => void = () => { };\n stop = effect(() => {\n const v = getter();\n if (first) {\n first = false;\n if (!immediate) {\n old = v;\n return;\n }\n }\n cb(v, old);\n old = v;\n if (once) stop();\n });\n return stop;\n}\n\nexport function nextTick(fn?: () => void): Promise<void> {\n return Promise.resolve().then(fn as () => void | Promise<void>);\n}\n\n// --- C.6/C.17: binding especializado signal→texto ----------------------------\n\n/**\n * Consumidor mínimo para bindings de texto (lo que el compiler emite para\n * `${expr}` cuando sabe que produce texto). Salta toda la maquinaria de\n * EffectNode: no hay cleanup-fn, ni innerCleanup, ni dispatch por tipo de\n * valor — re-corre el getter y escribe `nodeValue` directamente, en la cola\n * de render (B.8). Escribir es síncrono: el writer directo ES el punto.\n */\nclass TextBindingNode implements ConsumerNode, OwnerLike, Disposable {\n state = CLEAN;\n flags = F_RENDER;\n _flush = 0;\n sourcesHead: Link | null = null;\n evalMark = 0;\n childrenHead: (Disposable & OwnerLike) | null = null;\n childCount = 0;\n nextOwned: (Disposable & OwnerLike) | null = null;\n prevOwned: (Disposable & OwnerLike) | null = null;\n cleanups: (() => void)[] | null = null;\n parent: OwnerLike | null = null;\n private _fn: () => unknown;\n private _node: { nodeValue: string | null };\n\n constructor(fn: () => unknown, node: { nodeValue: string | null }) {\n this._fn = fn;\n this._node = node;\n own(this);\n }\n\n live(): boolean {\n return true;\n }\n\n run(): void {\n if (this.flags & F_DEAD || this.state & RUNNING) return;\n if (this.childrenHead !== null || this.cleanups !== null) disposeOwnerChildren(this);\n this.evalMark++;\n const prevConsumer = activeConsumer;\n const prevOwner = activeOwner;\n activeConsumer = this;\n activeOwner = this;\n this.state = RUNNING;\n try {\n const v = this._fn();\n this._node.nodeValue = v == null || v === false ? \"\" : String(v);\n } finally {\n activeConsumer = prevConsumer;\n activeOwner = prevOwner;\n }\n sweep(this);\n this.state = CLEAN;\n }\n\n dispose(): void {\n if (this.flags & F_DEAD) return;\n this.flags |= F_DEAD;\n this.state = DISPOSED;\n disposeOwnerChildren(this);\n this.evalMark++;\n sweep(this);\n unown(this);\n }\n}\n\n/**\n * @internal — binding de texto especializado (C.6): `node.nodeValue` sigue\n * `fn()` con el mínimo consumer posible. `null`/`false`/`undefined` → \"\".\n * Devuelve disposer (mata la suscripción; el caller remueve el nodo).\n */\nexport function _bindText(\n node: { nodeValue: string | null },\n fn: () => unknown,\n): () => void {\n const b = new TextBindingNode(fn, node);\n b.run();\n return () => b.dispose();\n}\n\n// --- C.6 tier T1: binding directo signal→writer --------------------------------\n\n/**\n * C.6/C.8 tier T1: el compiler emite esto cuando la expresión es una lectura\n * directa de señal (`() => <path>.value`) — la SEÑAL viaja como arg y el\n * binding es una edge permanente: sin getter de usuario, sin tracking\n * dinámico, sin sweep — `run()` escribe y punto.\n *\n * La edge no se re-evalúa nunca (la fuente es fija por construcción), así que\n * el nodo no necesita `sourcesHead` real: el Link sólo vive en la lista de\n * consumers del producer. `seenVersion` se mantiene al día en run() para que\n * el early-cutoff de stabilize() siga funcionando si la fuente es un Computed\n * (un T1 sobre computed recibe CHECK, no DIRTY).\n */\nclass SignalBinding implements ConsumerNode, OwnerLike, Disposable {\n state = CLEAN;\n flags = F_RENDER;\n _flush = 0;\n sourcesHead: Link | null = null;\n evalMark = 0;\n childrenHead: (Disposable & OwnerLike) | null = null;\n childCount = 0;\n nextOwned: (Disposable & OwnerLike) | null = null;\n prevOwned: (Disposable & OwnerLike) | null = null;\n cleanups: (() => void)[] | null = null;\n parent: OwnerLike | null = null;\n private _source: ProducerNode;\n private _link: Link | null = null;\n private _write: (v: unknown) => void;\n private _prev: unknown;\n\n constructor(source: Signal<unknown>, write: (v: unknown) => void) {\n this._source = source;\n this._write = write;\n // `.value` (no peek) sólo para computeds: fuerza la evaluación lazy de\n // los fríos — peek() devolvería _value crudo (stale). Signals planos van\n // por peek: evita el closure + save/restore de untrack en el path caliente\n // (un binding por fila en listas grandes).\n this._prev = source instanceof Computed\n ? untrack(() => source.value)\n : (source as Signal<unknown>).peek();\n write(this._prev);\n own(this);\n if (!source.durable) {\n const l = allocLink(source, this, source.version, 0);\n l.nextSource = null;\n this._link = l;\n this.sourcesHead = l;\n producerAddLink(source, l);\n // La edge puede despertar un computed frío — drenar adquisiciones.\n if (acquireQueue.length) drainAcquireQueue();\n }\n }\n\n live(): boolean {\n return true;\n }\n\n run(): void {\n const v = (this._source as Signal<unknown>).peek();\n if (this._link) this._link.seenVersion = this._source.version;\n if (v !== this._prev) {\n this._prev = v;\n this._write(v);\n }\n this.state = CLEAN;\n }\n\n dispose(): void {\n if (this.flags & F_DEAD) return;\n this.flags |= F_DEAD;\n this.state = DISPOSED;\n if (this._link) {\n producerRemoveLink(this._source, this._link);\n freeLink(this._link);\n this._link = null;\n this.sourcesHead = null;\n }\n unown(this);\n }\n}\n\n/**\n * @internal — C.6 T1: suscripción directa señal→writer. El writer corre una\n * vez al montar (valor inicial) y por cada cambio real de la señal, en la\n * cola de render. Devuelve disposer.\n */\nexport function _bindSignal<T>(\n source: Signal<T>,\n write: (v: T) => void,\n): () => void {\n const b = new SignalBinding(source, write as (v: unknown) => void);\n return () => b.dispose();\n}\n\n/**\n * C.7 T2: binding derivado — una edge permanente a la señal dep; run()\n * re-evalúa `get` untracked (las deps ya están conectadas por la edge —\n * evaluar tracked contaminaría al consumidor activo, ver bug de select1k),\n * compara el resultado y sólo escribe si cambió.\n */\nclass DerivedBinding implements ConsumerNode, OwnerLike, Disposable {\n state = CLEAN;\n flags = F_RENDER;\n _flush = 0;\n sourcesHead: Link | null = null;\n evalMark = 0;\n childrenHead: (Disposable & OwnerLike) | null = null;\n childCount = 0;\n nextOwned: (Disposable & OwnerLike) | null = null;\n prevOwned: (Disposable & OwnerLike) | null = null;\n cleanups: (() => void)[] | null = null;\n parent: OwnerLike | null = null;\n private _source: ProducerNode;\n private _link: Link | null = null;\n private _get: () => unknown;\n private _write: (v: unknown) => void;\n private _prev: unknown;\n\n constructor(\n source: Signal<unknown>,\n get: () => unknown,\n write: (v: unknown) => void,\n ) {\n this._source = source;\n this._get = get;\n this._write = write;\n this._prev = untrack(get);\n write(this._prev);\n own(this);\n if (!source.durable) {\n const l = allocLink(source, this, source.version, 0);\n l.nextSource = null;\n this._link = l;\n this.sourcesHead = l;\n producerAddLink(source, l);\n if (acquireQueue.length) drainAcquireQueue();\n }\n }\n\n live(): boolean {\n return true;\n }\n\n run(): void {\n const v = untrack(this._get);\n if (this._link) this._link.seenVersion = this._source.version;\n if (v !== this._prev) {\n this._prev = v;\n this._write(v);\n }\n this.state = CLEAN;\n }\n\n dispose(): void {\n if (this.flags & F_DEAD) return;\n this.flags |= F_DEAD;\n this.state = DISPOSED;\n if (this._link) {\n producerRemoveLink(this._source, this._link);\n freeLink(this._link);\n this._link = null;\n this.sourcesHead = null;\n }\n unown(this);\n }\n}\n\n/**\n * @internal — C.7 T2: suscripción directa señal→(getter derivado)→writer.\n * Equivale a `_bindSignal(dep, () => write(get()))` con compare incluido,\n * pero sin el closure intermedio ni el double-compare: un solo binding.\n * Devuelve disposer.\n */\nexport function _bindDerived<T>(\n source: Signal<unknown>,\n get: () => T,\n write: (v: T) => void,\n): () => void {\n const b = new DerivedBinding(source, get as () => unknown, write as (v: unknown) => void);\n return () => b.dispose();\n}\n"],"mappings":"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"}
|