@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.
Files changed (213) hide show
  1. package/dist/lib/async.cjs +1 -1
  2. package/dist/lib/async.js +1 -1
  3. package/dist/lib/component.cjs +1 -2
  4. package/dist/lib/component.js +2 -66
  5. package/dist/lib/context.cjs +1 -1
  6. package/dist/lib/context.js +35 -23
  7. package/dist/lib/devtools.cjs +1 -1
  8. package/dist/lib/devtools.js +1 -1
  9. package/dist/lib/elur/async.cjs +1 -1
  10. package/dist/lib/elur/async.cjs.map +1 -1
  11. package/dist/lib/elur/async.js +1 -1
  12. package/dist/lib/elur/component.cjs +1 -2
  13. package/dist/lib/elur/component.d.cts +1 -17
  14. package/dist/lib/elur/component.d.ts +1 -17
  15. package/dist/lib/elur/component.js +2 -66
  16. package/dist/lib/elur/context.cjs +1 -1
  17. package/dist/lib/elur/context.cjs.map +1 -1
  18. package/dist/lib/elur/context.d.cts +5 -0
  19. package/dist/lib/elur/context.d.ts +5 -0
  20. package/dist/lib/elur/context.js +35 -23
  21. package/dist/lib/elur/context.js.map +1 -1
  22. package/dist/lib/elur/devtools.cjs +1 -1
  23. package/dist/lib/elur/devtools.cjs.map +1 -1
  24. package/dist/lib/elur/devtools.js +1 -1
  25. package/dist/lib/elur/form.cjs +1 -1
  26. package/dist/lib/elur/form.cjs.map +1 -1
  27. package/dist/lib/elur/form.js +1 -1
  28. package/dist/lib/elur/hydrate/index.cjs +1 -2
  29. package/dist/lib/elur/hydrate/index.d.cts +1 -13
  30. package/dist/lib/elur/hydrate/index.d.ts +1 -13
  31. package/dist/lib/elur/hydrate/index.js +2 -410
  32. package/dist/lib/elur/lifecycle.cjs +1 -1
  33. package/dist/lib/elur/lifecycle.cjs.map +1 -1
  34. package/dist/lib/elur/lifecycle.d.cts +27 -0
  35. package/dist/lib/elur/lifecycle.d.ts +27 -0
  36. package/dist/lib/elur/lifecycle.js +4 -0
  37. package/dist/lib/elur/lifecycle.js.map +1 -1
  38. package/dist/lib/elur/next/component.d.cts +281 -0
  39. package/dist/lib/elur/next/component.d.ts +281 -0
  40. package/dist/lib/elur/next/dom-write.d.cts +18 -0
  41. package/dist/lib/elur/next/dom-write.d.ts +18 -0
  42. package/dist/lib/elur/next/hydrate.d.cts +14 -0
  43. package/dist/lib/elur/next/hydrate.d.ts +14 -0
  44. package/dist/lib/elur/next/keyed-diff.d.cts +46 -0
  45. package/dist/lib/elur/next/keyed-diff.d.ts +46 -0
  46. package/dist/lib/elur/next/mount-helpers.d.cts +25 -0
  47. package/dist/lib/elur/next/mount-helpers.d.ts +25 -0
  48. package/dist/lib/elur/next/mount.d.cts +29 -0
  49. package/dist/lib/elur/next/mount.d.ts +29 -0
  50. package/dist/lib/elur/next/node-binding.d.cts +6 -0
  51. package/dist/lib/elur/next/node-binding.d.ts +6 -0
  52. package/dist/lib/elur/next/reactivity.d.cts +193 -0
  53. package/dist/lib/elur/next/reactivity.d.ts +193 -0
  54. package/dist/lib/elur/next-2/component.cjs +2 -0
  55. package/dist/lib/elur/next-2/component.cjs.map +1 -0
  56. package/dist/lib/elur/next-2/component.d.cts +283 -0
  57. package/dist/lib/elur/next-2/component.d.ts +283 -0
  58. package/dist/lib/elur/next-2/component.js +340 -0
  59. package/dist/lib/elur/next-2/component.js.map +1 -0
  60. package/dist/lib/elur/next-2/dom-write.cjs +2 -0
  61. package/dist/lib/elur/next-2/dom-write.cjs.map +1 -0
  62. package/dist/lib/elur/next-2/dom-write.d.cts +18 -0
  63. package/dist/lib/elur/next-2/dom-write.d.ts +18 -0
  64. package/dist/lib/elur/next-2/dom-write.js +31 -0
  65. package/dist/lib/elur/next-2/dom-write.js.map +1 -0
  66. package/dist/lib/elur/next-2/hydrate.cjs +2 -0
  67. package/dist/lib/elur/next-2/hydrate.cjs.map +1 -0
  68. package/dist/lib/elur/next-2/hydrate.d.cts +30 -0
  69. package/dist/lib/elur/next-2/hydrate.d.ts +30 -0
  70. package/dist/lib/elur/next-2/hydrate.js +449 -0
  71. package/dist/lib/elur/next-2/hydrate.js.map +1 -0
  72. package/dist/lib/elur/next-2/keyed-diff.cjs +2 -0
  73. package/dist/lib/elur/next-2/keyed-diff.cjs.map +1 -0
  74. package/dist/lib/elur/next-2/keyed-diff.d.cts +79 -0
  75. package/dist/lib/elur/next-2/keyed-diff.d.ts +79 -0
  76. package/dist/lib/elur/next-2/keyed-diff.js +208 -0
  77. package/dist/lib/elur/next-2/keyed-diff.js.map +1 -0
  78. package/dist/lib/elur/next-2/mount-helpers.cjs +2 -0
  79. package/dist/lib/elur/next-2/mount-helpers.cjs.map +1 -0
  80. package/dist/lib/elur/next-2/mount-helpers.d.cts +25 -0
  81. package/dist/lib/elur/next-2/mount-helpers.d.ts +25 -0
  82. package/dist/lib/elur/next-2/mount-helpers.js +87 -0
  83. package/dist/lib/elur/next-2/mount-helpers.js.map +1 -0
  84. package/dist/lib/elur/next-2/mount.cjs +2 -0
  85. package/dist/lib/elur/next-2/mount.cjs.map +1 -0
  86. package/dist/lib/elur/next-2/mount.d.cts +29 -0
  87. package/dist/lib/elur/next-2/mount.d.ts +29 -0
  88. package/dist/lib/elur/next-2/mount.js +34 -0
  89. package/dist/lib/elur/next-2/mount.js.map +1 -0
  90. package/dist/lib/elur/next-2/node-binding.cjs +2 -0
  91. package/dist/lib/elur/next-2/node-binding.cjs.map +1 -0
  92. package/dist/lib/elur/next-2/node-binding.d.cts +6 -0
  93. package/dist/lib/elur/next-2/node-binding.d.ts +6 -0
  94. package/dist/lib/elur/next-2/node-binding.js +130 -0
  95. package/dist/lib/elur/next-2/node-binding.js.map +1 -0
  96. package/dist/lib/elur/next-2/reactivity.cjs +2 -0
  97. package/dist/lib/elur/next-2/reactivity.cjs.map +1 -0
  98. package/dist/lib/elur/next-2/reactivity.d.cts +220 -0
  99. package/dist/lib/elur/next-2/reactivity.d.ts +220 -0
  100. package/dist/lib/elur/next-2/reactivity.js +614 -0
  101. package/dist/lib/elur/next-2/reactivity.js.map +1 -0
  102. package/dist/lib/elur/next-2/scheduler.cjs +2 -0
  103. package/dist/lib/elur/next-2/scheduler.cjs.map +1 -0
  104. package/dist/lib/elur/next-2/scheduler.d.cts +23 -0
  105. package/dist/lib/elur/next-2/scheduler.d.ts +23 -0
  106. package/dist/lib/elur/next-2/scheduler.js +26 -0
  107. package/dist/lib/elur/next-2/scheduler.js.map +1 -0
  108. package/dist/lib/elur/plugins.cjs +1 -1
  109. package/dist/lib/elur/plugins.cjs.map +1 -1
  110. package/dist/lib/elur/plugins.js +1 -1
  111. package/dist/lib/elur/reactivity.cjs +1 -2
  112. package/dist/lib/elur/reactivity.d.cts +1 -67
  113. package/dist/lib/elur/reactivity.d.ts +1 -67
  114. package/dist/lib/elur/reactivity.js +2 -218
  115. package/dist/lib/elur/router.cjs +2 -2
  116. package/dist/lib/elur/router.cjs.map +1 -1
  117. package/dist/lib/elur/router.js +2 -2
  118. package/dist/lib/elur/router.js.map +1 -1
  119. package/dist/lib/elur/server/index.cjs +1 -1
  120. package/dist/lib/elur/server/index.cjs.map +1 -1
  121. package/dist/lib/elur/server/index.js +180 -108
  122. package/dist/lib/elur/server/index.js.map +1 -1
  123. package/dist/lib/elur/store.cjs +1 -1
  124. package/dist/lib/elur/store.cjs.map +1 -1
  125. package/dist/lib/elur/store.js +10 -4
  126. package/dist/lib/elur/store.js.map +1 -1
  127. package/dist/lib/elur/template/bindings.cjs +1 -1
  128. package/dist/lib/elur/template/bindings.cjs.map +1 -1
  129. package/dist/lib/elur/template/bindings.js +98 -84
  130. package/dist/lib/elur/template/bindings.js.map +1 -1
  131. package/dist/lib/elur/template/dom-write.d.cts +1 -5
  132. package/dist/lib/elur/template/dom-write.d.ts +1 -5
  133. package/dist/lib/elur/template/error-boundary.cjs +1 -1
  134. package/dist/lib/elur/template/error-boundary.cjs.map +1 -1
  135. package/dist/lib/elur/template/error-boundary.js +56 -50
  136. package/dist/lib/elur/template/error-boundary.js.map +1 -1
  137. package/dist/lib/elur/template/html.cjs +1 -1
  138. package/dist/lib/elur/template/html.cjs.map +1 -1
  139. package/dist/lib/elur/template/html.js +40 -37
  140. package/dist/lib/elur/template/html.js.map +1 -1
  141. package/dist/lib/elur/template/index.cjs +1 -1
  142. package/dist/lib/elur/template/index.d.cts +2 -1
  143. package/dist/lib/elur/template/index.d.ts +2 -1
  144. package/dist/lib/elur/template/index.js +13 -12
  145. package/dist/lib/elur/template/keyed-diff.d.cts +1 -32
  146. package/dist/lib/elur/template/keyed-diff.d.ts +1 -32
  147. package/dist/lib/elur/template/keyed.cjs +1 -1
  148. package/dist/lib/elur/template/keyed.cjs.map +1 -1
  149. package/dist/lib/elur/template/keyed.d.cts +10 -2
  150. package/dist/lib/elur/template/keyed.d.ts +10 -2
  151. package/dist/lib/elur/template/keyed.js +12 -1
  152. package/dist/lib/elur/template/keyed.js.map +1 -1
  153. package/dist/lib/elur/template/mount-helpers.d.cts +1 -29
  154. package/dist/lib/elur/template/mount-helpers.d.ts +1 -29
  155. package/dist/lib/elur/template/node-binding.d.cts +1 -6
  156. package/dist/lib/elur/template/node-binding.d.ts +1 -6
  157. package/dist/lib/elur/template/portal.cjs +1 -1
  158. package/dist/lib/elur/template/portal.cjs.map +1 -1
  159. package/dist/lib/elur/template/portal.js +1 -1
  160. package/dist/lib/elur/template/transitions.cjs +1 -1
  161. package/dist/lib/elur/template/transitions.cjs.map +1 -1
  162. package/dist/lib/elur/template/transitions.js +2 -2
  163. package/dist/lib/elur/template/types.cjs +1 -1
  164. package/dist/lib/elur/template/types.cjs.map +1 -1
  165. package/dist/lib/elur/template/types.d.cts +55 -0
  166. package/dist/lib/elur/template/types.d.ts +55 -0
  167. package/dist/lib/elur/template/types.js +5 -1
  168. package/dist/lib/elur/template/types.js.map +1 -1
  169. package/dist/lib/elur.cjs +1 -1
  170. package/dist/lib/elur.js +2 -2
  171. package/dist/lib/form.cjs +1 -1
  172. package/dist/lib/form.js +1 -1
  173. package/dist/lib/hydrate.cjs +1 -2
  174. package/dist/lib/hydrate.js +2 -410
  175. package/dist/lib/index.cjs +1 -1
  176. package/dist/lib/index.js +2 -2
  177. package/dist/lib/lifecycle.cjs +1 -1
  178. package/dist/lib/lifecycle.js +4 -0
  179. package/dist/lib/plugins.cjs +1 -1
  180. package/dist/lib/plugins.js +1 -1
  181. package/dist/lib/router.cjs +2 -2
  182. package/dist/lib/router.js +2 -2
  183. package/dist/lib/server.cjs +1 -1
  184. package/dist/lib/server.js +180 -108
  185. package/dist/lib/signals.cjs +1 -2
  186. package/dist/lib/signals.js +2 -218
  187. package/dist/lib/store.cjs +1 -1
  188. package/dist/lib/store.js +10 -4
  189. package/dist/lib/template.cjs +1 -1
  190. package/dist/lib/template.js +13 -12
  191. package/package.json +7 -9
  192. package/dist/lib/elur/component.cjs.map +0 -1
  193. package/dist/lib/elur/component.js.map +0 -1
  194. package/dist/lib/elur/hydrate/index.cjs.map +0 -1
  195. package/dist/lib/elur/hydrate/index.js.map +0 -1
  196. package/dist/lib/elur/reactivity.cjs.map +0 -1
  197. package/dist/lib/elur/reactivity.js.map +0 -1
  198. package/dist/lib/elur/template/dom-write.cjs +0 -2
  199. package/dist/lib/elur/template/dom-write.cjs.map +0 -1
  200. package/dist/lib/elur/template/dom-write.js +0 -16
  201. package/dist/lib/elur/template/dom-write.js.map +0 -1
  202. package/dist/lib/elur/template/keyed-diff.cjs +0 -2
  203. package/dist/lib/elur/template/keyed-diff.cjs.map +0 -1
  204. package/dist/lib/elur/template/keyed-diff.js +0 -100
  205. package/dist/lib/elur/template/keyed-diff.js.map +0 -1
  206. package/dist/lib/elur/template/mount-helpers.cjs +0 -2
  207. package/dist/lib/elur/template/mount-helpers.cjs.map +0 -1
  208. package/dist/lib/elur/template/mount-helpers.js +0 -132
  209. package/dist/lib/elur/template/mount-helpers.js.map +0 -1
  210. package/dist/lib/elur/template/node-binding.cjs +0 -2
  211. package/dist/lib/elur/template/node-binding.cjs.map +0 -1
  212. package/dist/lib/elur/template/node-binding.js +0 -95
  213. 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