@elurjs/core 3.6.1 → 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 +2 -2
- package/dist/lib/elur/router.cjs.map +1 -1
- package/dist/lib/elur/router.js +2 -2
- package/dist/lib/elur/router.js.map +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 +180 -108
- 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 +10 -4
- package/dist/lib/elur/store.js.map +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 +2 -2
- package/dist/lib/router.js +2 -2
- package/dist/lib/server.cjs +1 -1
- package/dist/lib/server.js +180 -108
- 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 +10 -4
- 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,46 @@
|
|
|
1
|
+
import { type KEntry, type KeyedList } from "../template/types.js";
|
|
2
|
+
import { type RepeatKey } from "../template/keyed.js";
|
|
3
|
+
/**
|
|
4
|
+
* C.16.1: lista keyed "live" — renderItem recibe accessors (`getItem`,
|
|
5
|
+
* `getIndex`) en vez del item capturado. Misma key + objeto nuevo → las
|
|
6
|
+
* señales del item se actualizan y los bindings re-corren sin remount,
|
|
7
|
+
* preservando identidad de DOM y estado del item.
|
|
8
|
+
*/
|
|
9
|
+
export interface LiveKeyedList<T = unknown> {
|
|
10
|
+
readonly __isKeyedList: true;
|
|
11
|
+
readonly live: true;
|
|
12
|
+
readonly items: T[];
|
|
13
|
+
readonly keyFn: (item: T, index: number) => string | number;
|
|
14
|
+
readonly renderItem: (getItem: () => T, getIndex: () => number) => unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare function repeatLive<T>(items: T[], keyFn: (item: T, index: number) => string | number, renderItem: (getItem: () => T, getIndex: () => number) => unknown): LiveKeyedList<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Mounts a single keyed item's rendered value before `endMarker` inside `parent`.
|
|
19
|
+
* Used by the DOM renderer and the hydration renderer so both engines share the
|
|
20
|
+
* exact same reconciliation semantics.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createKeyedMount(ctxSnapshot: Map<unknown, unknown>[]): (rendered: unknown, parent: Node, endMarker: Node) => () => void;
|
|
23
|
+
export interface KeyedDiffOptions {
|
|
24
|
+
/** Node marking the start of the keyed zone. */
|
|
25
|
+
zoneStart: Node;
|
|
26
|
+
/** End boundary; new content is inserted before this node. */
|
|
27
|
+
anchor: Node;
|
|
28
|
+
/** Live map of key → entry (start/end markers + cleanup). */
|
|
29
|
+
state: Map<RepeatKey, KEntry>;
|
|
30
|
+
/** Key order from the previous reconciliation pass. */
|
|
31
|
+
prevOrder: RepeatKey[];
|
|
32
|
+
/** The current keyed list value (clásica o live). */
|
|
33
|
+
list: KeyedList | LiveKeyedList;
|
|
34
|
+
/** Mounts a freshly rendered item into the DOM. */
|
|
35
|
+
mount: (rendered: unknown, parent: Node, endMarker: Node) => () => void;
|
|
36
|
+
/** Context snapshot for component mounts inside the effect. */
|
|
37
|
+
ctxSnapshot?: Map<unknown, unknown>[];
|
|
38
|
+
/** Called when a duplicate key is encountered. */
|
|
39
|
+
onDuplicateKey?: (key: RepeatKey) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reconciles a keyed list between `zoneStart` and `anchor` using the same LIS
|
|
43
|
+
* algorithm used by the DOM renderer. Total replacement (O(1)) when no key
|
|
44
|
+
* survives; otherwise remove/insert/move with minimal DOM operations.
|
|
45
|
+
*/
|
|
46
|
+
export declare function reconcileKeyedList(opts: KeyedDiffOptions): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ElurComponent } from "../lifecycle.js";
|
|
2
|
+
import { type _captureContextSnapshot } from "../context.js";
|
|
3
|
+
export declare function _postMountScope<T>(fn: () => T): T;
|
|
4
|
+
export declare function _postMountScopeSub<T>(fn: () => T): T;
|
|
5
|
+
export declare function _deferOnMount(fn: () => void): void;
|
|
6
|
+
/**
|
|
7
|
+
* Monta un ElurComponent via kernel: onInit → render → _render → onMount
|
|
8
|
+
* (post-commit). Errores van por onError o re-lanzan. Cleanup = unmount().
|
|
9
|
+
*/
|
|
10
|
+
export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Igual que `_mountComponent` pero traga todos los errores de lifecycle —
|
|
13
|
+
* para contenido de transitions y fallbacks de error boundaries.
|
|
14
|
+
*/
|
|
15
|
+
export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Monta con contexto capturado — para render dinámico/keyed dentro de
|
|
18
|
+
* effects, donde provide/inject hereda del punto de declaración.
|
|
19
|
+
*/
|
|
20
|
+
export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Mount con onMount diferido — dentro de fragments de `html` donde el DOM
|
|
23
|
+
* aún no está insertado: el hook corre cuando el fragment hace commit.
|
|
24
|
+
*/
|
|
25
|
+
export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ElurComponent } from "../lifecycle.js";
|
|
2
|
+
import { type _captureContextSnapshot } from "../context.js";
|
|
3
|
+
export declare function _postMountScope<T>(fn: () => T): T;
|
|
4
|
+
export declare function _postMountScopeSub<T>(fn: () => T): T;
|
|
5
|
+
export declare function _deferOnMount(fn: () => void): void;
|
|
6
|
+
/**
|
|
7
|
+
* Monta un ElurComponent via kernel: onInit → render → _render → onMount
|
|
8
|
+
* (post-commit). Errores van por onError o re-lanzan. Cleanup = unmount().
|
|
9
|
+
*/
|
|
10
|
+
export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Igual que `_mountComponent` pero traga todos los errores de lifecycle —
|
|
13
|
+
* para contenido de transitions y fallbacks de error boundaries.
|
|
14
|
+
*/
|
|
15
|
+
export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Monta con contexto capturado — para render dinámico/keyed dentro de
|
|
18
|
+
* effects, donde provide/inject hereda del punto de declaración.
|
|
19
|
+
*/
|
|
20
|
+
export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Mount con onMount diferido — dentro de fragments de `html` donde el DOM
|
|
23
|
+
* aún no está insertado: el hook corre cuando el fragment hace commit.
|
|
24
|
+
*/
|
|
25
|
+
export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
|
|
@@ -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,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,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elur "next" — grafo reactivo push-pull versionado (experimental).
|
|
3
|
+
*
|
|
4
|
+
* Módulo aislado de `../reactivity.ts` (PLAN_TECNICO_ELUR_NEXT §B.3–B.9):
|
|
5
|
+
* nunca importar ambos en el mismo path de producción — mezclar signals de
|
|
6
|
+
* dos grafos rompe la semántica.
|
|
7
|
+
*
|
|
8
|
+
* Modelo:
|
|
9
|
+
* - PUSH: signal.set() → version++ → invalida consumidores (DIRTY directos,
|
|
10
|
+
* CHECK transitivos) y encola effects una sola vez. No recalcula nada.
|
|
11
|
+
* - PULL: antes de ejecutar un effect se estabilizan sus fuentes — los
|
|
12
|
+
* computeds DIRTY/CHECK se refrescan recursivamente y sólo propagan si el
|
|
13
|
+
* resultado realmente cambió (early cutoff por versión).
|
|
14
|
+
* - Liveness: un computed sin consumidores vivos no se suscribe a sus
|
|
15
|
+
* fuentes; se refresca por sondeo de versiones al leerse (O(1) si el
|
|
16
|
+
* epoch global no cambió).
|
|
17
|
+
* - Edges: `Link` doble-enlazado compartido entre la lista de sources del
|
|
18
|
+
* consumidor y la de consumers del productor — subscribe/remove O(1),
|
|
19
|
+
* reutilizados entre evaluaciones (mark & sweep por `evalMark`).
|
|
20
|
+
*/
|
|
21
|
+
/** Cualquier cosa que pueda poseer consumidores: Owner raíz, Effect, Computed. */
|
|
22
|
+
export interface OwnerLike {
|
|
23
|
+
/** Hijos poseídos (effects, computeds, sub-owners) — disposal recursivo. */
|
|
24
|
+
children: Disposable[] | null;
|
|
25
|
+
/** Cleanups registrados con onCleanup() durante la última evaluación. */
|
|
26
|
+
cleanups: (() => void)[] | null;
|
|
27
|
+
/** Owner que era activo cuando este nodo fue creado (árbol de owners). */
|
|
28
|
+
parent: OwnerLike | null;
|
|
29
|
+
/**
|
|
30
|
+
* A.16: boundary por owner — un consumidor sin handler propio burbujea
|
|
31
|
+
* el error por la cadena de owners hasta que uno lo maneja (true).
|
|
32
|
+
*/
|
|
33
|
+
onOwnerError?: (err: unknown) => boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface Disposable {
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
|
38
|
+
/** Raíz de ownership explícita (un mount, un test, un sub-árbol). */
|
|
39
|
+
export declare class Owner implements OwnerLike, Disposable {
|
|
40
|
+
children: Disposable[] | null;
|
|
41
|
+
cleanups: (() => void)[] | null;
|
|
42
|
+
parent: OwnerLike | null;
|
|
43
|
+
onOwnerError?: (err: unknown) => boolean;
|
|
44
|
+
private _disposed;
|
|
45
|
+
dispose(): void;
|
|
46
|
+
}
|
|
47
|
+
/** Owner actual — para diagnóstico e integración con el kernel de mounts. */
|
|
48
|
+
export declare function getOwner(): OwnerLike | null;
|
|
49
|
+
/**
|
|
50
|
+
* Ejecuta fn con `owner` como dueño activo. Todo effect/computed creado
|
|
51
|
+
* dentro queda poseído por él y se destruye con él.
|
|
52
|
+
*/
|
|
53
|
+
export declare function runWithOwner<T>(owner: OwnerLike | null, fn: () => T): T;
|
|
54
|
+
/**
|
|
55
|
+
* Raíz reactiva: `const dispose = createRoot(d => {...})`. Todo lo creado
|
|
56
|
+
* dentro muere con `dispose()` — elimina la clase de leaks de B.2.5.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createRoot<T>(fn: (dispose: () => void) => T): T;
|
|
59
|
+
/** Registra una limpieza en el owner activo (effect, computed o root). */
|
|
60
|
+
export declare function onCleanup(fn: () => void): void;
|
|
61
|
+
/**
|
|
62
|
+
* B.9: ciclo de efectos — un write dentro de un effect re-encola trabajo; si
|
|
63
|
+
* un nodo corre más de MAX_RUNS_PER_FLUSH en el mismo flush, es un bucle.
|
|
64
|
+
* El mensaje incluye el camino de dependencias del efecto (sus fuentes y,
|
|
65
|
+
* si son computeds, las suyas) para localizar el ciclo.
|
|
66
|
+
*/
|
|
67
|
+
export declare class ReactiveCycleError extends Error {
|
|
68
|
+
constructor(effect: ConsumerNode, runs: number);
|
|
69
|
+
}
|
|
70
|
+
interface ErrorHandler {
|
|
71
|
+
(err: unknown): void;
|
|
72
|
+
}
|
|
73
|
+
/** @internal */
|
|
74
|
+
export declare function _pushErrorHandler(h: ErrorHandler): void;
|
|
75
|
+
/** @internal */
|
|
76
|
+
export declare function _popErrorHandler(): void;
|
|
77
|
+
export interface _SignalDebugHooks {
|
|
78
|
+
onCreate?: (signal: Signal<any>, initialValue: unknown) => void;
|
|
79
|
+
onWrite?: (signal: Signal<any>, value: unknown) => void;
|
|
80
|
+
}
|
|
81
|
+
/** @internal */
|
|
82
|
+
export declare function _setSignalDebugHooks(hooks: _SignalDebugHooks | null): void;
|
|
83
|
+
/** @internal — añade suscriptor sin reemplazar; devuelve unsubscribe. */
|
|
84
|
+
export declare function _addSignalDebugHooks(hooks: _SignalDebugHooks): () => void;
|
|
85
|
+
/** @internal — la nueva impl no tiene notify buffer; se expone para paridad. */
|
|
86
|
+
export declare function _getNotifyBufSize(): number;
|
|
87
|
+
interface ProducerNode {
|
|
88
|
+
/** Incrementa en cada cambio real de valor. */
|
|
89
|
+
version: number;
|
|
90
|
+
/** Nº de links vivos en `consumersHead` (liveness del productor). */
|
|
91
|
+
liveCount: number;
|
|
92
|
+
consumersHead: Link | null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Edge compartido: vive en dos listas a la vez — la de sources del consumer
|
|
96
|
+
* (`nextSource/prevSource`) y la de consumers del producer
|
|
97
|
+
* (`nextTarget/prevTarget`). `mark` lo usa el consumer para decidir qué
|
|
98
|
+
* links sobrevivieron a la última evaluación; `linked` indica si está
|
|
99
|
+
* insertado en la lista del producer (los computeds fríos no lo están).
|
|
100
|
+
*/
|
|
101
|
+
interface Link {
|
|
102
|
+
source: ProducerNode;
|
|
103
|
+
target: ConsumerNode;
|
|
104
|
+
seenVersion: number;
|
|
105
|
+
mark: number;
|
|
106
|
+
linked: boolean;
|
|
107
|
+
nextSource: Link | null;
|
|
108
|
+
prevSource: Link | null;
|
|
109
|
+
nextTarget: Link | null;
|
|
110
|
+
prevTarget: Link | null;
|
|
111
|
+
}
|
|
112
|
+
interface ConsumerNode {
|
|
113
|
+
state: number;
|
|
114
|
+
sourcesHead: Link | null;
|
|
115
|
+
/** Contador de evaluación — marca los links usados en esta pasada. */
|
|
116
|
+
evalMark: number;
|
|
117
|
+
live(): boolean;
|
|
118
|
+
}
|
|
119
|
+
export declare class Signal<T> implements ProducerNode {
|
|
120
|
+
version: number;
|
|
121
|
+
liveCount: number;
|
|
122
|
+
consumersHead: Link | null;
|
|
123
|
+
private _v;
|
|
124
|
+
constructor(initialValue: T);
|
|
125
|
+
get value(): T;
|
|
126
|
+
set value(newValue: T);
|
|
127
|
+
update(fn: (current: T) => T): void;
|
|
128
|
+
peek(): T;
|
|
129
|
+
dispose(): void;
|
|
130
|
+
}
|
|
131
|
+
export declare class Computed<T> extends Signal<T> implements ConsumerNode, OwnerLike {
|
|
132
|
+
state: number;
|
|
133
|
+
sourcesHead: Link | null;
|
|
134
|
+
evalMark: number;
|
|
135
|
+
/** Último epoch en que se verificó fresco — sondeo O(1) para fríos. */
|
|
136
|
+
lastCleanEpoch: number;
|
|
137
|
+
children: Disposable[] | null;
|
|
138
|
+
cleanups: (() => void)[] | null;
|
|
139
|
+
parent: OwnerLike | null;
|
|
140
|
+
_value: T | undefined;
|
|
141
|
+
fn: () => T;
|
|
142
|
+
equals: (a: T, b: T) => boolean;
|
|
143
|
+
hasValue: boolean;
|
|
144
|
+
private _evaluated;
|
|
145
|
+
/** B.12.1: transientes del DFS de refresh (0 entre refreshes). */
|
|
146
|
+
_pFlags: number;
|
|
147
|
+
_pCursor: Link | null;
|
|
148
|
+
_pLink: Link | null;
|
|
149
|
+
constructor(fn: () => T, equals?: (a: T, b: T) => boolean);
|
|
150
|
+
live(): boolean;
|
|
151
|
+
get value(): T;
|
|
152
|
+
peek(): T;
|
|
153
|
+
dispose(): void;
|
|
154
|
+
}
|
|
155
|
+
export declare function signal<T>(initialValue: T): Signal<T>;
|
|
156
|
+
export declare function computed<T>(fn: () => T, equals?: (a: T, b: T) => boolean): Computed<T>;
|
|
157
|
+
/** Corre una vez al crear; re-corre sólo si una fuente cambió de verdad. */
|
|
158
|
+
export declare function effect(fn: () => void | (() => void)): () => void;
|
|
159
|
+
/**
|
|
160
|
+
* @internal — effect de render (bindings DOM internos): se encola en la
|
|
161
|
+
* cola de render, que se drena ANTES que la de user effects (B.8). La API
|
|
162
|
+
* pública `effect()` sigue siendo la de usuario.
|
|
163
|
+
*/
|
|
164
|
+
export declare function _renderEffect(fn: () => void | (() => void)): () => void;
|
|
165
|
+
export declare function batch<T>(fn: () => T): T;
|
|
166
|
+
export declare function untrack<T>(fn: () => T): T;
|
|
167
|
+
export interface WatchOptions {
|
|
168
|
+
immediate?: boolean;
|
|
169
|
+
once?: boolean;
|
|
170
|
+
}
|
|
171
|
+
export declare function watch<T>(source: Signal<T> | (() => T), cb: (value: T, oldValue: T | undefined) => void, options?: WatchOptions): () => void;
|
|
172
|
+
export declare function nextTick(fn?: () => void): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* @internal — binding de texto especializado (C.6): `node.nodeValue` sigue
|
|
175
|
+
* `fn()` con el mínimo consumer posible. `null`/`false`/`undefined` → "".
|
|
176
|
+
* Devuelve disposer (mata la suscripción; el caller remueve el nodo).
|
|
177
|
+
*/
|
|
178
|
+
export declare function _bindText(node: {
|
|
179
|
+
nodeValue: string | null;
|
|
180
|
+
}, fn: () => unknown): () => void;
|
|
181
|
+
/**
|
|
182
|
+
* @internal — C.6 T1: suscripción directa señal→writer. El writer corre una
|
|
183
|
+
* vez al montar (valor inicial) y por cada cambio real de la señal, en la
|
|
184
|
+
* cola de render. Devuelve disposer.
|
|
185
|
+
*/
|
|
186
|
+
export declare function _bindSignal<T>(source: Signal<T>, write: (v: T) => void): () => void;
|
|
187
|
+
/**
|
|
188
|
+
* @internal — C.7 T2: suscripción directa señal→(getter derivado)→writer.
|
|
189
|
+
* Equivale a `_bindSignal(dep, () => write(get()))` con compare incluido,
|
|
190
|
+
* sin el closure intermedio ni el double-compare. Devuelve disposer.
|
|
191
|
+
*/
|
|
192
|
+
export declare function _bindDerived<T>(source: Signal<unknown>, get: () => T, write: (v: T) => void): () => void;
|
|
193
|
+
export {};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elur "next" — grafo reactivo push-pull versionado (experimental).
|
|
3
|
+
*
|
|
4
|
+
* Módulo aislado de `../reactivity.ts` (PLAN_TECNICO_ELUR_NEXT §B.3–B.9):
|
|
5
|
+
* nunca importar ambos en el mismo path de producción — mezclar signals de
|
|
6
|
+
* dos grafos rompe la semántica.
|
|
7
|
+
*
|
|
8
|
+
* Modelo:
|
|
9
|
+
* - PUSH: signal.set() → version++ → invalida consumidores (DIRTY directos,
|
|
10
|
+
* CHECK transitivos) y encola effects una sola vez. No recalcula nada.
|
|
11
|
+
* - PULL: antes de ejecutar un effect se estabilizan sus fuentes — los
|
|
12
|
+
* computeds DIRTY/CHECK se refrescan recursivamente y sólo propagan si el
|
|
13
|
+
* resultado realmente cambió (early cutoff por versión).
|
|
14
|
+
* - Liveness: un computed sin consumidores vivos no se suscribe a sus
|
|
15
|
+
* fuentes; se refresca por sondeo de versiones al leerse (O(1) si el
|
|
16
|
+
* epoch global no cambió).
|
|
17
|
+
* - Edges: `Link` doble-enlazado compartido entre la lista de sources del
|
|
18
|
+
* consumidor y la de consumers del productor — subscribe/remove O(1),
|
|
19
|
+
* reutilizados entre evaluaciones (mark & sweep por `evalMark`).
|
|
20
|
+
*/
|
|
21
|
+
/** Cualquier cosa que pueda poseer consumidores: Owner raíz, Effect, Computed. */
|
|
22
|
+
export interface OwnerLike {
|
|
23
|
+
/** Hijos poseídos (effects, computeds, sub-owners) — disposal recursivo. */
|
|
24
|
+
children: Disposable[] | null;
|
|
25
|
+
/** Cleanups registrados con onCleanup() durante la última evaluación. */
|
|
26
|
+
cleanups: (() => void)[] | null;
|
|
27
|
+
/** Owner que era activo cuando este nodo fue creado (árbol de owners). */
|
|
28
|
+
parent: OwnerLike | null;
|
|
29
|
+
/**
|
|
30
|
+
* A.16: boundary por owner — un consumidor sin handler propio burbujea
|
|
31
|
+
* el error por la cadena de owners hasta que uno lo maneja (true).
|
|
32
|
+
*/
|
|
33
|
+
onOwnerError?: (err: unknown) => boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface Disposable {
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
|
38
|
+
/** Raíz de ownership explícita (un mount, un test, un sub-árbol). */
|
|
39
|
+
export declare class Owner implements OwnerLike, Disposable {
|
|
40
|
+
children: Disposable[] | null;
|
|
41
|
+
cleanups: (() => void)[] | null;
|
|
42
|
+
parent: OwnerLike | null;
|
|
43
|
+
onOwnerError?: (err: unknown) => boolean;
|
|
44
|
+
private _disposed;
|
|
45
|
+
dispose(): void;
|
|
46
|
+
}
|
|
47
|
+
/** Owner actual — para diagnóstico e integración con el kernel de mounts. */
|
|
48
|
+
export declare function getOwner(): OwnerLike | null;
|
|
49
|
+
/**
|
|
50
|
+
* Ejecuta fn con `owner` como dueño activo. Todo effect/computed creado
|
|
51
|
+
* dentro queda poseído por él y se destruye con él.
|
|
52
|
+
*/
|
|
53
|
+
export declare function runWithOwner<T>(owner: OwnerLike | null, fn: () => T): T;
|
|
54
|
+
/**
|
|
55
|
+
* Raíz reactiva: `const dispose = createRoot(d => {...})`. Todo lo creado
|
|
56
|
+
* dentro muere con `dispose()` — elimina la clase de leaks de B.2.5.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createRoot<T>(fn: (dispose: () => void) => T): T;
|
|
59
|
+
/** Registra una limpieza en el owner activo (effect, computed o root). */
|
|
60
|
+
export declare function onCleanup(fn: () => void): void;
|
|
61
|
+
/**
|
|
62
|
+
* B.9: ciclo de efectos — un write dentro de un effect re-encola trabajo; si
|
|
63
|
+
* un nodo corre más de MAX_RUNS_PER_FLUSH en el mismo flush, es un bucle.
|
|
64
|
+
* El mensaje incluye el camino de dependencias del efecto (sus fuentes y,
|
|
65
|
+
* si son computeds, las suyas) para localizar el ciclo.
|
|
66
|
+
*/
|
|
67
|
+
export declare class ReactiveCycleError extends Error {
|
|
68
|
+
constructor(effect: ConsumerNode, runs: number);
|
|
69
|
+
}
|
|
70
|
+
interface ErrorHandler {
|
|
71
|
+
(err: unknown): void;
|
|
72
|
+
}
|
|
73
|
+
/** @internal */
|
|
74
|
+
export declare function _pushErrorHandler(h: ErrorHandler): void;
|
|
75
|
+
/** @internal */
|
|
76
|
+
export declare function _popErrorHandler(): void;
|
|
77
|
+
export interface _SignalDebugHooks {
|
|
78
|
+
onCreate?: (signal: Signal<any>, initialValue: unknown) => void;
|
|
79
|
+
onWrite?: (signal: Signal<any>, value: unknown) => void;
|
|
80
|
+
}
|
|
81
|
+
/** @internal */
|
|
82
|
+
export declare function _setSignalDebugHooks(hooks: _SignalDebugHooks | null): void;
|
|
83
|
+
/** @internal — añade suscriptor sin reemplazar; devuelve unsubscribe. */
|
|
84
|
+
export declare function _addSignalDebugHooks(hooks: _SignalDebugHooks): () => void;
|
|
85
|
+
/** @internal — la nueva impl no tiene notify buffer; se expone para paridad. */
|
|
86
|
+
export declare function _getNotifyBufSize(): number;
|
|
87
|
+
interface ProducerNode {
|
|
88
|
+
/** Incrementa en cada cambio real de valor. */
|
|
89
|
+
version: number;
|
|
90
|
+
/** Nº de links vivos en `consumersHead` (liveness del productor). */
|
|
91
|
+
liveCount: number;
|
|
92
|
+
consumersHead: Link | null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Edge compartido: vive en dos listas a la vez — la de sources del consumer
|
|
96
|
+
* (`nextSource/prevSource`) y la de consumers del producer
|
|
97
|
+
* (`nextTarget/prevTarget`). `mark` lo usa el consumer para decidir qué
|
|
98
|
+
* links sobrevivieron a la última evaluación; `linked` indica si está
|
|
99
|
+
* insertado en la lista del producer (los computeds fríos no lo están).
|
|
100
|
+
*/
|
|
101
|
+
interface Link {
|
|
102
|
+
source: ProducerNode;
|
|
103
|
+
target: ConsumerNode;
|
|
104
|
+
seenVersion: number;
|
|
105
|
+
mark: number;
|
|
106
|
+
linked: boolean;
|
|
107
|
+
nextSource: Link | null;
|
|
108
|
+
prevSource: Link | null;
|
|
109
|
+
nextTarget: Link | null;
|
|
110
|
+
prevTarget: Link | null;
|
|
111
|
+
}
|
|
112
|
+
interface ConsumerNode {
|
|
113
|
+
state: number;
|
|
114
|
+
sourcesHead: Link | null;
|
|
115
|
+
/** Contador de evaluación — marca los links usados en esta pasada. */
|
|
116
|
+
evalMark: number;
|
|
117
|
+
live(): boolean;
|
|
118
|
+
}
|
|
119
|
+
export declare class Signal<T> implements ProducerNode {
|
|
120
|
+
version: number;
|
|
121
|
+
liveCount: number;
|
|
122
|
+
consumersHead: Link | null;
|
|
123
|
+
private _v;
|
|
124
|
+
constructor(initialValue: T);
|
|
125
|
+
get value(): T;
|
|
126
|
+
set value(newValue: T);
|
|
127
|
+
update(fn: (current: T) => T): void;
|
|
128
|
+
peek(): T;
|
|
129
|
+
dispose(): void;
|
|
130
|
+
}
|
|
131
|
+
export declare class Computed<T> extends Signal<T> implements ConsumerNode, OwnerLike {
|
|
132
|
+
state: number;
|
|
133
|
+
sourcesHead: Link | null;
|
|
134
|
+
evalMark: number;
|
|
135
|
+
/** Último epoch en que se verificó fresco — sondeo O(1) para fríos. */
|
|
136
|
+
lastCleanEpoch: number;
|
|
137
|
+
children: Disposable[] | null;
|
|
138
|
+
cleanups: (() => void)[] | null;
|
|
139
|
+
parent: OwnerLike | null;
|
|
140
|
+
_value: T | undefined;
|
|
141
|
+
fn: () => T;
|
|
142
|
+
equals: (a: T, b: T) => boolean;
|
|
143
|
+
hasValue: boolean;
|
|
144
|
+
private _evaluated;
|
|
145
|
+
/** B.12.1: transientes del DFS de refresh (0 entre refreshes). */
|
|
146
|
+
_pFlags: number;
|
|
147
|
+
_pCursor: Link | null;
|
|
148
|
+
_pLink: Link | null;
|
|
149
|
+
constructor(fn: () => T, equals?: (a: T, b: T) => boolean);
|
|
150
|
+
live(): boolean;
|
|
151
|
+
get value(): T;
|
|
152
|
+
peek(): T;
|
|
153
|
+
dispose(): void;
|
|
154
|
+
}
|
|
155
|
+
export declare function signal<T>(initialValue: T): Signal<T>;
|
|
156
|
+
export declare function computed<T>(fn: () => T, equals?: (a: T, b: T) => boolean): Computed<T>;
|
|
157
|
+
/** Corre una vez al crear; re-corre sólo si una fuente cambió de verdad. */
|
|
158
|
+
export declare function effect(fn: () => void | (() => void)): () => void;
|
|
159
|
+
/**
|
|
160
|
+
* @internal — effect de render (bindings DOM internos): se encola en la
|
|
161
|
+
* cola de render, que se drena ANTES que la de user effects (B.8). La API
|
|
162
|
+
* pública `effect()` sigue siendo la de usuario.
|
|
163
|
+
*/
|
|
164
|
+
export declare function _renderEffect(fn: () => void | (() => void)): () => void;
|
|
165
|
+
export declare function batch<T>(fn: () => T): T;
|
|
166
|
+
export declare function untrack<T>(fn: () => T): T;
|
|
167
|
+
export interface WatchOptions {
|
|
168
|
+
immediate?: boolean;
|
|
169
|
+
once?: boolean;
|
|
170
|
+
}
|
|
171
|
+
export declare function watch<T>(source: Signal<T> | (() => T), cb: (value: T, oldValue: T | undefined) => void, options?: WatchOptions): () => void;
|
|
172
|
+
export declare function nextTick(fn?: () => void): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* @internal — binding de texto especializado (C.6): `node.nodeValue` sigue
|
|
175
|
+
* `fn()` con el mínimo consumer posible. `null`/`false`/`undefined` → "".
|
|
176
|
+
* Devuelve disposer (mata la suscripción; el caller remueve el nodo).
|
|
177
|
+
*/
|
|
178
|
+
export declare function _bindText(node: {
|
|
179
|
+
nodeValue: string | null;
|
|
180
|
+
}, fn: () => unknown): () => void;
|
|
181
|
+
/**
|
|
182
|
+
* @internal — C.6 T1: suscripción directa señal→writer. El writer corre una
|
|
183
|
+
* vez al montar (valor inicial) y por cada cambio real de la señal, en la
|
|
184
|
+
* cola de render. Devuelve disposer.
|
|
185
|
+
*/
|
|
186
|
+
export declare function _bindSignal<T>(source: Signal<T>, write: (v: T) => void): () => void;
|
|
187
|
+
/**
|
|
188
|
+
* @internal — C.7 T2: suscripción directa señal→(getter derivado)→writer.
|
|
189
|
+
* Equivale a `_bindSignal(dep, () => write(get()))` con compare incluido,
|
|
190
|
+
* sin el closure intermedio ni el double-compare. Devuelve disposer.
|
|
191
|
+
*/
|
|
192
|
+
export declare function _bindDerived<T>(source: Signal<unknown>, get: () => T, write: (v: T) => void): () => void;
|
|
193
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./reactivity.cjs`),t=require(`../template/types.cjs`),n=require(`../../lifecycle.cjs`),r=require(`../../context.cjs`);function i(e){return t.isElurTemplate(e)?e:null}function a(e){return typeof e==`object`&&!!e&&e.__isElurSlot===!0}var o=1,s=class t{id=o++;kind;state=`created`;owner=new e.Owner;parent=null;hooks={};renderable=null;context=new Map;_inst=null;_invocation=null;_renderCleanup=null;_mountCleanups=null;_propSignals=null;_liveProps=null;_phase=`setup`;_mountParent=null;_mountBefore=null;_domNodes=null;_controllers=null;constructor(e){n.isElurComponent(e)?(this.kind=`class`,this._inst=e):(this.kind=`function`,this._invocation=e),this.owner.onOwnerError=e=>c(this,{phase:`effect`,component:this,cause:e}).handled}mount(r,i,a){if(this.state!==`created`)throw Error(`[elur-next] ComponentInstance.mount(): estado inválido "${this.state}" (una instancia montada no puede montarse otra vez).`);if(f.set(this.owner,this),p.set(this.owner,this.context),this._resolveParent(),this.owner.parent=a?.declOwner===void 0?e.getOwner():a.declOwner,a?.provides)for(let[e,t]of a.provides)this.context.set(e,t);this._mountParent=r,this._mountBefore=i;let o=!n.isElurComponent(this._inst),s=this;o&&n._debugComponentMountStart(s);let l=i?Array.prototype.indexOf.call(r.childNodes,i):r.childNodes.length;try{this.state=`initializing`,e.runWithOwner(this.owner,()=>this._withScope(a?.ctxSnapshot,()=>{if(this._initBody(),this._inst?._controllers)for(let e of this._inst._controllers)this.addController(e);if(this._controllers)for(let e of this._controllers)e.hostInit?.();this._phase=`mount`,this.state=`pending-mount`,this._renderCleanup=this.renderable._render(r,i);let e=i?Array.prototype.indexOf.call(r.childNodes,i):r.childNodes.length;this._domNodes=Array.prototype.slice.call(r.childNodes,l,e)})),this.state=`mounted`;let t=()=>this._runOnMount();a?.deferOnMount?a.deferOnMount(t):t()}catch(e){this._rollback();let n=c(this,{phase:this._phase,component:this,cause:e});if(!n.handled)throw e;`retry`in n&&n.retry?new t(this._inst??this._invocation).mount(r,i,a):`fallback`in n&&n.fallback!==void 0&&this._renderFallback(n.fallback,r,i)}finally{o&&n._debugComponentMountEnd(s)}}addController(e){(this._controllers??=[]).push(e)}detach(){if(this.state!==`mounted`||!this._domNodes)return;let t=document.createDocumentFragment();for(let e of this._domNodes)t.appendChild(e);this.state=`deactivated`,this._controllers&&e.runWithOwner(this.owner,()=>{for(let e of this._controllers)e.hostDeactivate?.()})}attach(t,n){if(this.state!==`deactivated`||!this._domNodes)return;let r=t??this._mountParent,i=n===void 0?this._mountBefore:n;if(r){for(let e of this._domNodes)r.insertBefore(e,i);this.state=`mounted`,this._controllers&&e.runWithOwner(this.owner,()=>{for(let e of this._controllers)e.hostActivate?.()})}}unmount(){if(this.state!==`created`&&!(this.state===`disposing`||this.state===`disposed`)){if(this.state===`failed`){this.state=`disposed`;return}this.state===`deactivated`&&(this._domNodes=null),this.state=`disposing`,n.isElurComponent(this._inst)||n._debugComponentUnmount(this);try{e.runWithOwner(this.owner,()=>{if(this.hooks.onUnmount?.call(this._inst??void 0),this._inst?.onUnmount?.(),this._controllers)for(let e of this._controllers)e.hostUnmount?.()})}catch(e){this._reportSwallowed(e,`unmount`)}if(this._mountCleanups){for(let e of this._mountCleanups)try{e()}catch(e){this._reportSwallowed(e,`cleanup`)}this._mountCleanups=null}this.owner.dispose();try{this._renderCleanup?.()}finally{this._renderCleanup=null,this.state=`disposed`}}}dispose(){this.unmount()}_runOnMount(){if(this.state===`mounted`)try{let t=e.runWithOwner(this.owner,()=>{let e=this.kind===`class`?this._inst.onMount?.():this.hooks.onMount?.();if(this._controllers)for(let e of this._controllers)e.hostMounted?.();return e});typeof t==`function`&&(this._mountCleanups??=[]).push(t)}catch(e){this._rollback();let t=c(this,{phase:`mount`,component:this,cause:e});if(!t.handled)throw e;`fallback`in t&&t.fallback!==void 0&&this._renderFallback(t.fallback,this._mountParent,this._mountBefore)}}_handleError(e){if(this.kind===`function`&&this.hooks.onError){let t=this.hooks.onError(e);return t===void 0?{handled:!0}:t}return this.kind===`class`&&this._inst?.onError?(this._inst.onError(e.cause),{handled:!0}):null}_reportSwallowed(e,t){c(this,{phase:t,component:this,cause:e}).handled||console.error(`[elur-next] error en `+t+`:`,e)}_renderFallback(e,n,r){let a=i(e);if(a)a._render(n,r);else if(typeof e==`string`||typeof e==`number`)n.insertBefore(document.createTextNode(String(e)),r);else if(Array.isArray(e))for(let t of e)this._renderFallback(t,n,r);else e&&new t(e).mount(n,r)}_resolveParent(){let t=e.getOwner();for(;t;){let e=f.get(t);if(e){this.parent=e;return}t=t.parent}}_rollback(){this.owner.dispose();try{this._renderCleanup?.()}finally{this._renderCleanup=null,this.state=`failed`}}_makeSetupCtx(){let e=this;return{owner:this.owner,onMount(t){e.hooks.onMount=t},onUnmount(t){e.hooks.onUnmount=t},onError(t){e.hooks.onError=t},onServerRender(t){e.hooks.onServerRender=t},propSignal(t){return e._propSignals?.get(t)},slots:this._invocation?.slots,slot(t=`default`){return e._invocation?.slots?.[t]}}}_initBody(){if(this.kind===`class`){let e=this._inst;this._phase=`init`,e.onInit?.(),this._phase=`render`,this.state=`rendering`,this.renderable=i(e.render())}else{let e=this._invocation,t=this._makeSetupCtx();this._phase=`setup`,this.state=`rendering`,this.renderable=i(e.definition.setup(this._initProps(e.props),t))}if(!this.renderable)throw Error(`[elur-next] El componente #${this.id} no produjo un template renderizable.`)}_withScope(e,t){if(e)r._withComponentContext(e,t);else{r._pushComponentContext();try{t()}finally{r._popComponentContext()}}}_hydrate(t){if(this.state!==`created`)throw Error(`[elur-next] _hydrate(): estado inválido "${this.state}".`);f.set(this.owner,this),p.set(this.owner,this.context),this._resolveParent(),this.owner.parent=e.getOwner();try{this.state=`initializing`;let n;e.runWithOwner(this.owner,()=>this._withScope(void 0,()=>{this._initBody(),this.state=`pending-mount`,n=t.render(this.renderable)})),this._renderCleanup=typeof n==`function`?n:null,this.state=`mounted`,this._runOnMount()}catch(n){if(t.mismatch===`throw`)throw n;t.mismatch!==`remount`&&console.warn(`[elur] Hydration mismatch en componente; remounting:`,n),this.owner.dispose();let r=this.renderable;this.state=`initializing`,e.runWithOwner(this.owner,()=>this._withScope(void 0,()=>{r||this._initBody(),this.state=`pending-mount`,this._renderCleanup=this.renderable._render(t.parent,t.bounds?.end??null)})),this.state=`mounted`,this._runOnMount()}}async _renderServer(t){this.state=`initializing`,f.set(this.owner,this),p.set(this.owner,this.context),this._resolveParent(),this.owner.parent=e.getOwner(),e.runWithOwner(this.owner,()=>this._withScope(void 0,()=>{this._initBody(),this.kind===`class`?this._inst.onServerRender?.():this.hooks.onServerRender?.()}));try{return await t.render(this.renderable,{markers:t.markers})}finally{this.owner.dispose(),this.state=`disposed`}}_initProps(t){if(this._propSignals=new Map,this._liveProps={},typeof t==`object`&&t)for(let[n,r]of Object.entries(t)){if(n===`key`)continue;let t=e.signal(r);this._propSignals.set(n,t),Object.defineProperty(this._liveProps,n,{enumerable:!0,get:()=>t.value})}return this._liveProps}matches(e){if(this.kind!==`function`||!this._invocation)return!1;let t=e=>typeof e==`object`&&e?e.key:void 0;return e.definition===this._invocation.definition&&t(e.props)===t(this._invocation.props)}updateProps(t){if(!this._propSignals||!this._liveProps)return;let n=new Set;if(typeof t==`object`&&t)for(let[r,i]of Object.entries(t)){if(r===`key`)continue;n.add(r);let t=this._propSignals.get(r);if(t)t.value=i;else{let t=e.signal(i);this._propSignals.set(r,t),Object.defineProperty(this._liveProps,r,{enumerable:!0,get:()=>t.value})}}for(let e of this._propSignals.keys())n.has(e)||(this._propSignals.get(e).value=void 0)}};function c(e,t){let n=e;for(;n;){let e=n._handleError(t);if(e!==null)return e;n=n.parent}return{handled:!1}}function l(e){return new s(e)}var u=class{[t.ELUR_RENDER_PROTOCOL]={mountDom:e=>{let t=new s(this);return t.mount(e.parent,e.before),()=>t.unmount()},renderServer:e=>new s(this)._renderServer(e),hydrateDom:e=>{let t=new s(this);return t._hydrate(e),()=>t.unmount()}};definition;props;slots;constructor(e,t,n){this.definition=e,this.props=t,this.slots=n}};function d(e){return e instanceof u}var f=new WeakMap,p=new WeakMap;function m(e,t){p.set(e,t)}r._pushContextScopeResolver(()=>{let t=[],n=e.getOwner();for(;n;){let e=p.get(n);e&&t.push(e),n=n.parent}if(t.length!==0)return t.reverse(),t}),exports.ComponentInstance=s,exports._registerContextOwner=m,exports.adaptClassComponent=l,exports.isComponentInvocation=d,exports.isElurSlot=a;
|
|
2
|
+
//# sourceMappingURL=component.cjs.map
|