@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,283 @@
1
+ /**
2
+ * Elur "next" — kernel unificado de componentes (experimental).
3
+ *
4
+ * Implementa A.6–A.9 del PLAN_TECNICO_ELUR_NEXT sobre el ownership de
5
+ * `./reactivity.ts`:
6
+ * - Una sola `ComponentInstance` para clases y funciones (adaptadores).
7
+ * - Máquina de estados (A.7): created → initializing → rendering →
8
+ * pending-mount → mounted → disposing → disposed (o failed).
9
+ * - Mount transaccional (A.9): cualquier fallo dispara rollback —
10
+ * cleanups registrados, owner reactivo disposed, DOM insertado removido.
11
+ * - `unmount()` idempotente (A.2.10).
12
+ * - `onMount` corre DESPUÉS del commit DOM (A.2.9).
13
+ * - Todo lo creado en setup/render pertenece al owner de la instancia y
14
+ * muere con unmount (A.2.1 — no más effects huérfanos).
15
+ *
16
+ * Las invocaciones implementan `ELUR_RENDER_PROTOCOL.mountDom`, así el
17
+ * renderer existente las monta sin saber que son componentes.
18
+ */
19
+ import { Owner, Signal, type Disposable, type OwnerLike } from "./reactivity.js";
20
+ import { type ElurComponent, type ComponentController } from "../lifecycle.js";
21
+ import { ELUR_RENDER_PROTOCOL, type DomProtocolContext } from "../template/types.js";
22
+ export type ComponentState = "created" | "initializing" | "rendering" | "pending-mount" | "mounted" | "deactivated" | "disposing" | "disposed" | "failed";
23
+ /** Fase del lifecycle donde ocurrió el error. */
24
+ export type ErrorPhase = "setup" | "init" | "render" | "hydrate" | "mount" | "effect" | "activate" | "deactivate" | "cleanup" | "unmount";
25
+ /** Información estructurada del error (A.16). */
26
+ export interface ComponentErrorInfo {
27
+ phase: ErrorPhase;
28
+ /** Instancia donde ocurrió el error (no la boundary que lo maneja). */
29
+ component: ComponentInstance;
30
+ cause: unknown;
31
+ }
32
+ /** Resolución de una boundary (A.16). */
33
+ export type ErrorResolution = {
34
+ handled: false;
35
+ } | {
36
+ handled: true;
37
+ fallback?: Renderable;
38
+ } | {
39
+ handled: true;
40
+ retry: true;
41
+ };
42
+ export interface ComponentHooks {
43
+ /** Tras el commit DOM. Puede devolver cleanup (corre en unmount). */
44
+ onMount?: () => (() => void) | void;
45
+ /** Antes de remover el DOM. */
46
+ onUnmount?: () => void;
47
+ /**
48
+ * Boundary de errores (A.16): recibe info estructurada; el error burbujea
49
+ * por la cadena de instancias hasta una boundary que devuelva handled.
50
+ * `void` = manejado sin más.
51
+ */
52
+ onError?: (info: ComponentErrorInfo) => ErrorResolution | void;
53
+ /** A.17: tras setup durante SSR — nunca en cliente. */
54
+ onServerRender?: () => void;
55
+ }
56
+ /** Contexto que recibe el setup de un componente funcional. */
57
+ export interface SetupCtx {
58
+ onMount(fn: () => (() => void) | void): void;
59
+ onUnmount(fn: () => void): void;
60
+ onError(fn: (info: ComponentErrorInfo) => ErrorResolution | void): void;
61
+ /** A.17: hook server-side — corre tras setup durante SSR, nunca en cliente. */
62
+ onServerRender(fn: () => void): void;
63
+ /** Owner de la instancia — para runWithOwner/getOwner manual. */
64
+ readonly owner: OwnerLike;
65
+ /** Señal interna de una prop (A.13) — para acceso reactivo explícito. */
66
+ propSignal<K extends string>(key: K): Signal<unknown> | undefined;
67
+ /**
68
+ * A.14: renderiza el contenido de un slot (lazy — corre el render del
69
+ * slot bajo el owner del padre que lo declaró). `"default"` por defecto.
70
+ */
71
+ slot(name?: string): unknown;
72
+ /** A.14: slots declarados en la invocación. */
73
+ readonly slots: Record<string, Slot> | undefined;
74
+ }
75
+ interface RenderableValue {
76
+ _render(parent: Node, before: Node | null): () => void;
77
+ }
78
+ /** Renderable común: cualquier cosa montable en un binding. */
79
+ export type Renderable = ElurComponent | ComponentInvocation<unknown> | Slot | {
80
+ _render(parent: Node, before: Node | null): () => void;
81
+ } | string | number | bigint | false | null | undefined | Renderable[];
82
+ /**
83
+ * Slot lazy y marcado (A.14): el contenido se renderiza bajo el owner del
84
+ * padre que LO DECLARÓ (contexto léxico), aunque se monte dentro del
85
+ * componente consumidor.
86
+ */
87
+ export interface Slot {
88
+ readonly __isElurSlot: true;
89
+ /** Owner capturado en el punto de declaración (contexto léxico). */
90
+ readonly owner: OwnerLike | null;
91
+ render(): unknown;
92
+ }
93
+ export declare function slot(render: () => unknown): Slot;
94
+ export declare function isElurSlot(v: unknown): v is Slot;
95
+ export declare class ComponentInstance implements Disposable {
96
+ readonly id: number;
97
+ readonly kind: "class" | "function";
98
+ state: ComponentState;
99
+ /** Owner reactivo de la instancia — todo lo creado dentro muere con él. */
100
+ readonly owner: Owner;
101
+ /** Instancia padre (owner activo cuando se creó esta instancia). */
102
+ parent: ComponentInstance | null;
103
+ hooks: ComponentHooks;
104
+ renderable: RenderableValue | null;
105
+ /** A.12: frame de provide/inject propio de la instancia — permanente. */
106
+ readonly context: Map<unknown, unknown>;
107
+ private _inst;
108
+ private _invocation;
109
+ private _renderCleanup;
110
+ private _mountCleanups;
111
+ /** A.13: señales internas por prop + objeto live pasado al setup. */
112
+ private _propSignals;
113
+ private _liveProps;
114
+ /** A.16: fase actual del lifecycle — para el ComponentErrorInfo. */
115
+ private _phase;
116
+ /** A.16: posición de montaje — para renderizar fallback de boundary. */
117
+ private _mountParent;
118
+ private _mountBefore;
119
+ /** A.3.8: nodos DOM de la instancia — para detach/attach. */
120
+ private _domNodes;
121
+ /** A.21: controllers de ciclo de vida (Lit-style). */
122
+ private _controllers;
123
+ constructor(source: ElurComponent | ComponentInvocation<any>);
124
+ /**
125
+ * Mount transaccional (A.9). Cualquier fase que falle → rollback completo:
126
+ * owner disposed, cleanups corridos, DOM insertado removido, state=failed.
127
+ *
128
+ * Opciones:
129
+ * - `ctxSnapshot`: contexto capturado en el punto de declaración
130
+ * (mounts dentro de effects dinámicos heredan provide/inject).
131
+ * - `deferOnMount`: recibe una función `fire()` que corre onMount; el
132
+ * caller decide cuándo invocarla (fragments aún no insertados).
133
+ */
134
+ mount(parent: Node, before: Node | null, opts?: {
135
+ ctxSnapshot?: Map<unknown, unknown>[];
136
+ deferOnMount?: (fire: () => void) => void;
137
+ /** Valores a proveer en el frame de contexto de la instancia (A.12). */
138
+ provides?: Iterable<readonly [unknown, unknown]>;
139
+ /**
140
+ * A.14: owner del declarante — para contenido de slots, el owner padre
141
+ * es el del padre que declaró el contenido, no el del punto de montaje.
142
+ */
143
+ declOwner?: OwnerLike | null;
144
+ }): void;
145
+ /** A.21: registra un controller — sus hooks corren bajo este owner. */
146
+ addController(c: ComponentController): void;
147
+ /**
148
+ * A.3.8: saca el DOM de la instancia SIN disponer nada — effects, signals
149
+ * y contexto siguen vivos (página cached, Suspense, transición). No-op si
150
+ * no está montado.
151
+ */
152
+ detach(): void;
153
+ /**
154
+ * A.3.8: reinserta el DOM de una instancia detached en la posición original
155
+ * (o en parent/before dados). No-op si no está deactivated.
156
+ */
157
+ attach(parent?: Node, before?: Node | null): void;
158
+ /** Idempotente (A.2.10): disponer dos veces es seguro. */
159
+ unmount(): void;
160
+ dispose(): void;
161
+ /** @internal — corre onMount una vez; no-op si ya no está montado. */
162
+ _runOnMount(): void;
163
+ /**
164
+ * @internal A.16: intenta manejar el error con el boundary propio.
165
+ * `null` = este nodo no tiene boundary — seguir subiendo.
166
+ */
167
+ _handleError(info: ComponentErrorInfo): ErrorResolution | null;
168
+ /** A.16: errores de teardown — se reportan a la cadena; si nadie los maneja quedan registrados. */
169
+ private _reportSwallowed;
170
+ /** A.16: renderiza el fallback de una boundary en la posición del componente. */
171
+ private _renderFallback;
172
+ /** Camina la cadena de owners hasta la instancia registrada más cercana. */
173
+ private _resolveParent;
174
+ private _rollback;
175
+ private _makeSetupCtx;
176
+ /** Fases initializing+rendering: setup/onInit + render → this.renderable. */
177
+ private _initBody;
178
+ /** Corre `body` dentro del frame de contexto (snapshot o frame nuevo). */
179
+ private _withScope;
180
+ /**
181
+ * A.18 — hidratación: setup/onInit + render una sola vez, luego adopta el
182
+ * DOM SSR via ctx.render (que activa bindings dentro del owner de la
183
+ * instancia). En mismatch: rollback de la activación + remount por el mismo
184
+ * kernel REUSANDO el renderable — setup/onInit no se duplica.
185
+ */
186
+ _hydrate(ctx: {
187
+ parent: Node;
188
+ bounds: {
189
+ start: Comment;
190
+ end: Comment;
191
+ } | null;
192
+ render(value: unknown): unknown;
193
+ /** "throw" propaga el mismatch en vez de remontar (HydrateOptions). */
194
+ mismatch?: "throw" | "warn-remount" | "remount";
195
+ }): void;
196
+ /**
197
+ * A.17 — SSR: setup/onInit + onServerRender + serializar el renderable.
198
+ * NO corre onMount/onUnmount; el owner server-side se dispone al final
199
+ * (mata effects/computeds creados en setup).
200
+ */
201
+ _renderServer(sctx: {
202
+ markers?: boolean;
203
+ render(value: unknown, options?: {
204
+ markers?: boolean;
205
+ }): string | Promise<string>;
206
+ }): Promise<string>;
207
+ /**
208
+ * A.13 — crea el objeto LiveProps: propiedades readonly respaldadas por
209
+ * signals. OJO: destructurar props en setup crea snapshots no reactivos.
210
+ */
211
+ private _initProps;
212
+ /**
213
+ * A.13/A.15 — true si `inv` es la misma definición con la misma key:
214
+ * entonces el runtime debe actualizar props, no recrear el setup.
215
+ */
216
+ matches(inv: ComponentInvocation<any>): boolean;
217
+ /**
218
+ * A.13 — actualiza props sin recrear setup: escribe cada signal de prop.
219
+ * Props nuevas se añaden; props desaparecidas quedan en undefined.
220
+ */
221
+ updateProps(props: unknown): void;
222
+ }
223
+ /**
224
+ * A.16: burbujeo de errores por la cadena de instancias (padres reales del
225
+ * árbol de componentes). Devuelve la primera resolución manejada; si nadie
226
+ * maneja el error, `{ handled: false }` y el caller decide (re-lanzar o
227
+ * registrar).
228
+ */
229
+ export declare function reportError(from: ComponentInstance, info: ComponentErrorInfo): ErrorResolution;
230
+ /** Envuelve un ElurComponent de clase en el kernel unificado. */
231
+ export declare function adaptClassComponent(inst: ElurComponent): ComponentInstance;
232
+ export interface ComponentDefinition<P> {
233
+ (props?: P, slots?: Record<string, Slot>): ComponentInvocation<P>;
234
+ readonly setup: (props: P | undefined, ctx: SetupCtx) => unknown;
235
+ readonly _isComponentDefinition: true;
236
+ }
237
+ /** Invocación marcada: `Counter({ initial: 10 })` NO ejecuta setup — monta después. */
238
+ export declare class ComponentInvocation<P> {
239
+ readonly [ELUR_RENDER_PROTOCOL]: {
240
+ mountDom: (ctx: DomProtocolContext) => (() => void);
241
+ renderServer: (sctx: {
242
+ markers?: boolean;
243
+ render(value: unknown, options?: {
244
+ markers?: boolean;
245
+ }): string | Promise<string>;
246
+ }) => Promise<string>;
247
+ hydrateDom: (ctx: {
248
+ parent: Node;
249
+ bounds: {
250
+ start: Comment;
251
+ end: Comment;
252
+ } | null;
253
+ render(value: unknown): unknown;
254
+ }) => (() => void);
255
+ };
256
+ readonly definition: ComponentDefinition<P>;
257
+ readonly props: P | undefined;
258
+ /** A.14: slots declarados en la llamada — `Card(props, { default: slot(...) })`. */
259
+ readonly slots: Record<string, Slot> | undefined;
260
+ constructor(definition: ComponentDefinition<P>, props: P | undefined, slots?: Record<string, Slot>);
261
+ }
262
+ export declare function isComponentInvocation(v: unknown): v is ComponentInvocation<any>;
263
+ /**
264
+ * @internal — registra un frame de contexto para un owner raíz (mount de
265
+ * template con router, roots de app, etc).
266
+ */
267
+ export declare function _registerContextOwner(owner: OwnerLike, context: Map<unknown, unknown>): void;
268
+ /**
269
+ * Define un componente funcional de primera clase (A.5):
270
+ * `Counter(props)` retorna una invocación marcada; el runtime ejecuta el
271
+ * setup cuando monta la invocación.
272
+ */
273
+ export declare function defineComponent<P = Record<string, never>>(setup: (props: P | undefined, ctx: SetupCtx) => unknown): ComponentDefinition<P>;
274
+ /**
275
+ * Monta un componente (clase o invocación funcional) en `container` y
276
+ * devuelve el handle con `unmount()`. Todo el árbol reactivo muere con el
277
+ * unmount — sin fugas de effects/computeds.
278
+ */
279
+ export declare function mountComponent(value: ElurComponent | ComponentInvocation<any>, container: Element): {
280
+ unmount(): void;
281
+ instance: ComponentInstance;
282
+ };
283
+ export {};
@@ -0,0 +1,340 @@
1
+ import { Owner as e, getOwner as t, runWithOwner as n, signal as r } from "./reactivity.js";
2
+ import { ELUR_RENDER_PROTOCOL as i, isElurTemplate as a } from "../template/types.js";
3
+ import { _debugComponentMountEnd as o, _debugComponentMountStart as s, _debugComponentUnmount as c, isElurComponent as l } from "../../lifecycle.js";
4
+ import { _popComponentContext as u, _pushComponentContext as d, _pushContextScopeResolver as f, _withComponentContext as p } from "../../context.js";
5
+ //#region src/elur/next-2/component.ts
6
+ function m(e) {
7
+ return a(e) ? e : null;
8
+ }
9
+ function h(e) {
10
+ return typeof e == "object" && !!e && e.__isElurSlot === !0;
11
+ }
12
+ var g = 1, _ = class i {
13
+ id = g++;
14
+ kind;
15
+ state = "created";
16
+ owner = new e();
17
+ parent = null;
18
+ hooks = {};
19
+ renderable = null;
20
+ context = /* @__PURE__ */ new Map();
21
+ _inst = null;
22
+ _invocation = null;
23
+ _renderCleanup = null;
24
+ _mountCleanups = null;
25
+ _propSignals = null;
26
+ _liveProps = null;
27
+ _phase = "setup";
28
+ _mountParent = null;
29
+ _mountBefore = null;
30
+ _domNodes = null;
31
+ _controllers = null;
32
+ constructor(e) {
33
+ l(e) ? (this.kind = "class", this._inst = e) : (this.kind = "function", this._invocation = e), this.owner.onOwnerError = (e) => v(this, {
34
+ phase: "effect",
35
+ component: this,
36
+ cause: e
37
+ }).handled;
38
+ }
39
+ mount(e, r, a) {
40
+ if (this.state !== "created") throw Error(`[elur-next] ComponentInstance.mount(): estado inválido "${this.state}" (una instancia montada no puede montarse otra vez).`);
41
+ if (S.set(this.owner, this), C.set(this.owner, this.context), this._resolveParent(), this.owner.parent = a?.declOwner === void 0 ? t() : a.declOwner, a?.provides) for (let [e, t] of a.provides) this.context.set(e, t);
42
+ this._mountParent = e, this._mountBefore = r;
43
+ let c = !l(this._inst), u = this;
44
+ c && s(u);
45
+ let d = r ? Array.prototype.indexOf.call(e.childNodes, r) : e.childNodes.length;
46
+ try {
47
+ this.state = "initializing", n(this.owner, () => this._withScope(a?.ctxSnapshot, () => {
48
+ if (this._initBody(), this._inst?._controllers) for (let e of this._inst._controllers) this.addController(e);
49
+ if (this._controllers) for (let e of this._controllers) e.hostInit?.();
50
+ this._phase = "mount", this.state = "pending-mount", this._renderCleanup = this.renderable._render(e, r);
51
+ let t = r ? Array.prototype.indexOf.call(e.childNodes, r) : e.childNodes.length;
52
+ this._domNodes = Array.prototype.slice.call(e.childNodes, d, t);
53
+ })), this.state = "mounted";
54
+ let t = () => this._runOnMount();
55
+ a?.deferOnMount ? a.deferOnMount(t) : t();
56
+ } catch (t) {
57
+ this._rollback();
58
+ let n = v(this, {
59
+ phase: this._phase,
60
+ component: this,
61
+ cause: t
62
+ });
63
+ if (!n.handled) throw t;
64
+ "retry" in n && n.retry ? new i(this._inst ?? this._invocation).mount(e, r, a) : "fallback" in n && n.fallback !== void 0 && this._renderFallback(n.fallback, e, r);
65
+ } finally {
66
+ c && o(u);
67
+ }
68
+ }
69
+ addController(e) {
70
+ (this._controllers ??= []).push(e);
71
+ }
72
+ detach() {
73
+ if (this.state !== "mounted" || !this._domNodes) return;
74
+ let e = document.createDocumentFragment();
75
+ for (let t of this._domNodes) e.appendChild(t);
76
+ this.state = "deactivated", this._controllers && n(this.owner, () => {
77
+ for (let e of this._controllers) e.hostDeactivate?.();
78
+ });
79
+ }
80
+ attach(e, t) {
81
+ if (this.state !== "deactivated" || !this._domNodes) return;
82
+ let r = e ?? this._mountParent, i = t === void 0 ? this._mountBefore : t;
83
+ if (r) {
84
+ for (let e of this._domNodes) r.insertBefore(e, i);
85
+ this.state = "mounted", this._controllers && n(this.owner, () => {
86
+ for (let e of this._controllers) e.hostActivate?.();
87
+ });
88
+ }
89
+ }
90
+ unmount() {
91
+ if (this.state !== "created" && !(this.state === "disposing" || this.state === "disposed")) {
92
+ if (this.state === "failed") {
93
+ this.state = "disposed";
94
+ return;
95
+ }
96
+ this.state === "deactivated" && (this._domNodes = null), this.state = "disposing", l(this._inst) || c(this);
97
+ try {
98
+ n(this.owner, () => {
99
+ if (this.hooks.onUnmount?.call(this._inst ?? void 0), this._inst?.onUnmount?.(), this._controllers) for (let e of this._controllers) e.hostUnmount?.();
100
+ });
101
+ } catch (e) {
102
+ this._reportSwallowed(e, "unmount");
103
+ }
104
+ if (this._mountCleanups) {
105
+ for (let e of this._mountCleanups) try {
106
+ e();
107
+ } catch (e) {
108
+ this._reportSwallowed(e, "cleanup");
109
+ }
110
+ this._mountCleanups = null;
111
+ }
112
+ this.owner.dispose();
113
+ try {
114
+ this._renderCleanup?.();
115
+ } finally {
116
+ this._renderCleanup = null, this.state = "disposed";
117
+ }
118
+ }
119
+ }
120
+ dispose() {
121
+ this.unmount();
122
+ }
123
+ _runOnMount() {
124
+ if (this.state === "mounted") try {
125
+ let e = n(this.owner, () => {
126
+ let e = this.kind === "class" ? this._inst.onMount?.() : this.hooks.onMount?.();
127
+ if (this._controllers) for (let e of this._controllers) e.hostMounted?.();
128
+ return e;
129
+ });
130
+ typeof e == "function" && (this._mountCleanups ??= []).push(e);
131
+ } catch (e) {
132
+ this._rollback();
133
+ let t = v(this, {
134
+ phase: "mount",
135
+ component: this,
136
+ cause: e
137
+ });
138
+ if (!t.handled) throw e;
139
+ "fallback" in t && t.fallback !== void 0 && this._renderFallback(t.fallback, this._mountParent, this._mountBefore);
140
+ }
141
+ }
142
+ _handleError(e) {
143
+ if (this.kind === "function" && this.hooks.onError) {
144
+ let t = this.hooks.onError(e);
145
+ return t === void 0 ? { handled: !0 } : t;
146
+ }
147
+ return this.kind === "class" && this._inst?.onError ? (this._inst.onError(e.cause), { handled: !0 }) : null;
148
+ }
149
+ _reportSwallowed(e, t) {
150
+ v(this, {
151
+ phase: t,
152
+ component: this,
153
+ cause: e
154
+ }).handled || console.error("[elur-next] error en " + t + ":", e);
155
+ }
156
+ _renderFallback(e, t, n) {
157
+ let r = m(e);
158
+ if (r) r._render(t, n);
159
+ else if (typeof e == "string" || typeof e == "number") t.insertBefore(document.createTextNode(String(e)), n);
160
+ else if (Array.isArray(e)) for (let r of e) this._renderFallback(r, t, n);
161
+ else e && new i(e).mount(t, n);
162
+ }
163
+ _resolveParent() {
164
+ let e = t();
165
+ for (; e;) {
166
+ let t = S.get(e);
167
+ if (t) {
168
+ this.parent = t;
169
+ return;
170
+ }
171
+ e = e.parent;
172
+ }
173
+ }
174
+ _rollback() {
175
+ this.owner.dispose();
176
+ try {
177
+ this._renderCleanup?.();
178
+ } finally {
179
+ this._renderCleanup = null, this.state = "failed";
180
+ }
181
+ }
182
+ _makeSetupCtx() {
183
+ let e = this;
184
+ return {
185
+ owner: this.owner,
186
+ onMount(t) {
187
+ e.hooks.onMount = t;
188
+ },
189
+ onUnmount(t) {
190
+ e.hooks.onUnmount = t;
191
+ },
192
+ onError(t) {
193
+ e.hooks.onError = t;
194
+ },
195
+ onServerRender(t) {
196
+ e.hooks.onServerRender = t;
197
+ },
198
+ propSignal(t) {
199
+ return e._propSignals?.get(t);
200
+ },
201
+ slots: this._invocation?.slots,
202
+ slot(t = "default") {
203
+ return e._invocation?.slots?.[t];
204
+ }
205
+ };
206
+ }
207
+ _initBody() {
208
+ if (this.kind === "class") {
209
+ let e = this._inst;
210
+ this._phase = "init", e.onInit?.(), this._phase = "render", this.state = "rendering", this.renderable = m(e.render());
211
+ } else {
212
+ let e = this._invocation, t = this._makeSetupCtx();
213
+ this._phase = "setup", this.state = "rendering", this.renderable = m(e.definition.setup(this._initProps(e.props), t));
214
+ }
215
+ if (!this.renderable) throw Error(`[elur-next] El componente #${this.id} no produjo un template renderizable.`);
216
+ }
217
+ _withScope(e, t) {
218
+ if (e) p(e, t);
219
+ else {
220
+ d();
221
+ try {
222
+ t();
223
+ } finally {
224
+ u();
225
+ }
226
+ }
227
+ }
228
+ _hydrate(e) {
229
+ if (this.state !== "created") throw Error(`[elur-next] _hydrate(): estado inválido "${this.state}".`);
230
+ S.set(this.owner, this), C.set(this.owner, this.context), this._resolveParent(), this.owner.parent = t();
231
+ try {
232
+ this.state = "initializing";
233
+ let t;
234
+ n(this.owner, () => this._withScope(void 0, () => {
235
+ this._initBody(), this.state = "pending-mount", t = e.render(this.renderable);
236
+ })), this._renderCleanup = typeof t == "function" ? t : null, this.state = "mounted", this._runOnMount();
237
+ } catch (t) {
238
+ if (e.mismatch === "throw") throw t;
239
+ e.mismatch !== "remount" && console.warn("[elur] Hydration mismatch en componente; remounting:", t), this.owner.dispose();
240
+ let r = this.renderable;
241
+ this.state = "initializing", n(this.owner, () => this._withScope(void 0, () => {
242
+ r || this._initBody(), this.state = "pending-mount", this._renderCleanup = this.renderable._render(e.parent, e.bounds?.end ?? null);
243
+ })), this.state = "mounted", this._runOnMount();
244
+ }
245
+ }
246
+ async _renderServer(e) {
247
+ this.state = "initializing", S.set(this.owner, this), C.set(this.owner, this.context), this._resolveParent(), this.owner.parent = t(), n(this.owner, () => this._withScope(void 0, () => {
248
+ this._initBody(), this.kind === "class" ? this._inst.onServerRender?.() : this.hooks.onServerRender?.();
249
+ }));
250
+ try {
251
+ return await e.render(this.renderable, { markers: e.markers });
252
+ } finally {
253
+ this.owner.dispose(), this.state = "disposed";
254
+ }
255
+ }
256
+ _initProps(e) {
257
+ if (this._propSignals = /* @__PURE__ */ new Map(), this._liveProps = {}, typeof e == "object" && e) for (let [t, n] of Object.entries(e)) {
258
+ if (t === "key") continue;
259
+ let e = r(n);
260
+ this._propSignals.set(t, e), Object.defineProperty(this._liveProps, t, {
261
+ enumerable: !0,
262
+ get: () => e.value
263
+ });
264
+ }
265
+ return this._liveProps;
266
+ }
267
+ matches(e) {
268
+ if (this.kind !== "function" || !this._invocation) return !1;
269
+ let t = (e) => typeof e == "object" && e ? e.key : void 0;
270
+ return e.definition === this._invocation.definition && t(e.props) === t(this._invocation.props);
271
+ }
272
+ updateProps(e) {
273
+ if (!this._propSignals || !this._liveProps) return;
274
+ let t = /* @__PURE__ */ new Set();
275
+ if (typeof e == "object" && e) for (let [n, i] of Object.entries(e)) {
276
+ if (n === "key") continue;
277
+ t.add(n);
278
+ let e = this._propSignals.get(n);
279
+ if (e) e.value = i;
280
+ else {
281
+ let e = r(i);
282
+ this._propSignals.set(n, e), Object.defineProperty(this._liveProps, n, {
283
+ enumerable: !0,
284
+ get: () => e.value
285
+ });
286
+ }
287
+ }
288
+ for (let e of this._propSignals.keys()) t.has(e) || (this._propSignals.get(e).value = void 0);
289
+ }
290
+ };
291
+ function v(e, t) {
292
+ let n = e;
293
+ for (; n;) {
294
+ let e = n._handleError(t);
295
+ if (e !== null) return e;
296
+ n = n.parent;
297
+ }
298
+ return { handled: !1 };
299
+ }
300
+ function y(e) {
301
+ return new _(e);
302
+ }
303
+ var b = class {
304
+ [i] = {
305
+ mountDom: (e) => {
306
+ let t = new _(this);
307
+ return t.mount(e.parent, e.before), () => t.unmount();
308
+ },
309
+ renderServer: (e) => new _(this)._renderServer(e),
310
+ hydrateDom: (e) => {
311
+ let t = new _(this);
312
+ return t._hydrate(e), () => t.unmount();
313
+ }
314
+ };
315
+ definition;
316
+ props;
317
+ slots;
318
+ constructor(e, t, n) {
319
+ this.definition = e, this.props = t, this.slots = n;
320
+ }
321
+ };
322
+ function x(e) {
323
+ return e instanceof b;
324
+ }
325
+ var S = /* @__PURE__ */ new WeakMap(), C = /* @__PURE__ */ new WeakMap();
326
+ function w(e, t) {
327
+ C.set(e, t);
328
+ }
329
+ f(() => {
330
+ let e = [], n = t();
331
+ for (; n;) {
332
+ let t = C.get(n);
333
+ t && e.push(t), n = n.parent;
334
+ }
335
+ if (e.length !== 0) return e.reverse(), e;
336
+ });
337
+ //#endregion
338
+ export { _ as ComponentInstance, w as _registerContextOwner, y as adaptClassComponent, x as isComponentInvocation, h as isElurSlot };
339
+
340
+ //# sourceMappingURL=component.js.map