@elurjs/core 3.6.2 → 3.7.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) 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 +1 -1
  116. package/dist/lib/elur/router.cjs.map +1 -1
  117. package/dist/lib/elur/router.js +1 -1
  118. package/dist/lib/elur/server/index.cjs +1 -1
  119. package/dist/lib/elur/server/index.cjs.map +1 -1
  120. package/dist/lib/elur/server/index.js +175 -107
  121. package/dist/lib/elur/server/index.js.map +1 -1
  122. package/dist/lib/elur/store.cjs +1 -1
  123. package/dist/lib/elur/store.cjs.map +1 -1
  124. package/dist/lib/elur/store.js +1 -1
  125. package/dist/lib/elur/template/bindings.cjs +1 -1
  126. package/dist/lib/elur/template/bindings.cjs.map +1 -1
  127. package/dist/lib/elur/template/bindings.js +98 -84
  128. package/dist/lib/elur/template/bindings.js.map +1 -1
  129. package/dist/lib/elur/template/dom-write.d.cts +1 -5
  130. package/dist/lib/elur/template/dom-write.d.ts +1 -5
  131. package/dist/lib/elur/template/error-boundary.cjs +1 -1
  132. package/dist/lib/elur/template/error-boundary.cjs.map +1 -1
  133. package/dist/lib/elur/template/error-boundary.js +56 -50
  134. package/dist/lib/elur/template/error-boundary.js.map +1 -1
  135. package/dist/lib/elur/template/html.cjs +1 -1
  136. package/dist/lib/elur/template/html.cjs.map +1 -1
  137. package/dist/lib/elur/template/html.js +40 -37
  138. package/dist/lib/elur/template/html.js.map +1 -1
  139. package/dist/lib/elur/template/index.cjs +1 -1
  140. package/dist/lib/elur/template/index.d.cts +2 -1
  141. package/dist/lib/elur/template/index.d.ts +2 -1
  142. package/dist/lib/elur/template/index.js +13 -12
  143. package/dist/lib/elur/template/keyed-diff.d.cts +1 -32
  144. package/dist/lib/elur/template/keyed-diff.d.ts +1 -32
  145. package/dist/lib/elur/template/keyed.cjs +1 -1
  146. package/dist/lib/elur/template/keyed.cjs.map +1 -1
  147. package/dist/lib/elur/template/keyed.d.cts +10 -2
  148. package/dist/lib/elur/template/keyed.d.ts +10 -2
  149. package/dist/lib/elur/template/keyed.js +12 -1
  150. package/dist/lib/elur/template/keyed.js.map +1 -1
  151. package/dist/lib/elur/template/mount-helpers.d.cts +1 -29
  152. package/dist/lib/elur/template/mount-helpers.d.ts +1 -29
  153. package/dist/lib/elur/template/node-binding.d.cts +1 -6
  154. package/dist/lib/elur/template/node-binding.d.ts +1 -6
  155. package/dist/lib/elur/template/portal.cjs +1 -1
  156. package/dist/lib/elur/template/portal.cjs.map +1 -1
  157. package/dist/lib/elur/template/portal.js +1 -1
  158. package/dist/lib/elur/template/transitions.cjs +1 -1
  159. package/dist/lib/elur/template/transitions.cjs.map +1 -1
  160. package/dist/lib/elur/template/transitions.js +2 -2
  161. package/dist/lib/elur/template/types.cjs +1 -1
  162. package/dist/lib/elur/template/types.cjs.map +1 -1
  163. package/dist/lib/elur/template/types.d.cts +55 -0
  164. package/dist/lib/elur/template/types.d.ts +55 -0
  165. package/dist/lib/elur/template/types.js +5 -1
  166. package/dist/lib/elur/template/types.js.map +1 -1
  167. package/dist/lib/elur.cjs +1 -1
  168. package/dist/lib/elur.js +2 -2
  169. package/dist/lib/form.cjs +1 -1
  170. package/dist/lib/form.js +1 -1
  171. package/dist/lib/hydrate.cjs +1 -2
  172. package/dist/lib/hydrate.js +2 -410
  173. package/dist/lib/index.cjs +1 -1
  174. package/dist/lib/index.js +2 -2
  175. package/dist/lib/lifecycle.cjs +1 -1
  176. package/dist/lib/lifecycle.js +4 -0
  177. package/dist/lib/plugins.cjs +1 -1
  178. package/dist/lib/plugins.js +1 -1
  179. package/dist/lib/router.cjs +1 -1
  180. package/dist/lib/router.js +1 -1
  181. package/dist/lib/server.cjs +1 -1
  182. package/dist/lib/server.js +175 -107
  183. package/dist/lib/signals.cjs +1 -2
  184. package/dist/lib/signals.js +2 -218
  185. package/dist/lib/store.cjs +1 -1
  186. package/dist/lib/store.js +1 -1
  187. package/dist/lib/template.cjs +1 -1
  188. package/dist/lib/template.js +13 -12
  189. package/package.json +7 -9
  190. package/dist/lib/elur/component.cjs.map +0 -1
  191. package/dist/lib/elur/component.js.map +0 -1
  192. package/dist/lib/elur/hydrate/index.cjs.map +0 -1
  193. package/dist/lib/elur/hydrate/index.js.map +0 -1
  194. package/dist/lib/elur/reactivity.cjs.map +0 -1
  195. package/dist/lib/elur/reactivity.js.map +0 -1
  196. package/dist/lib/elur/template/dom-write.cjs +0 -2
  197. package/dist/lib/elur/template/dom-write.cjs.map +0 -1
  198. package/dist/lib/elur/template/dom-write.js +0 -16
  199. package/dist/lib/elur/template/dom-write.js.map +0 -1
  200. package/dist/lib/elur/template/keyed-diff.cjs +0 -2
  201. package/dist/lib/elur/template/keyed-diff.cjs.map +0 -1
  202. package/dist/lib/elur/template/keyed-diff.js +0 -100
  203. package/dist/lib/elur/template/keyed-diff.js.map +0 -1
  204. package/dist/lib/elur/template/mount-helpers.cjs +0 -2
  205. package/dist/lib/elur/template/mount-helpers.cjs.map +0 -1
  206. package/dist/lib/elur/template/mount-helpers.js +0 -132
  207. package/dist/lib/elur/template/mount-helpers.js.map +0 -1
  208. package/dist/lib/elur/template/node-binding.cjs +0 -2
  209. package/dist/lib/elur/template/node-binding.cjs.map +0 -1
  210. package/dist/lib/elur/template/node-binding.js +0 -95
  211. package/dist/lib/elur/template/node-binding.js.map +0 -1
@@ -1,29 +1 @@
1
- import { type ElurComponent } from "../lifecycle.js";
2
- import { _captureContextSnapshot } from "../context.js";
3
- /**
4
- * Renders a ElurComponent into the DOM and calls onMount immediately.
5
- * Propagates errors through onError (or re-throws if not present).
6
- * Returns a full cleanup function (onUnmount + mountCleanup + renderCleanup).
7
- */
8
- export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
9
- /**
10
- * Same as `_mountComponent` but silently swallows all lifecycle errors.
11
- * Used for transition content and error boundary fallbacks where errors
12
- * inside the fallback/transition itself must not propagate.
13
- */
14
- export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
15
- /**
16
- * Renders a ElurComponent using a captured context snapshot.
17
- * Used for dynamic/keyed rendering inside reactive effects, where the
18
- * provide/inject context must be inherited from the point of declaration.
19
- * Calls onMount immediately. Returns a full cleanup function.
20
- */
21
- export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
22
- /**
23
- * Renders a ElurComponent with *deferred* onMount — used inside `html` template
24
- * fragments where the DOM nodes are still in a DocumentFragment and onMount must
25
- * fire only after the fragment is inserted into the live document.
26
- *
27
- * Pushes the full cleanup into `disposes` and the onMount call into `postMountHooks`.
28
- */
29
- export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
1
+ export * from "../next-2/mount-helpers.js";
@@ -1,29 +1 @@
1
- import { type ElurComponent } from "../lifecycle.js";
2
- import { _captureContextSnapshot } from "../context.js";
3
- /**
4
- * Renders a ElurComponent into the DOM and calls onMount immediately.
5
- * Propagates errors through onError (or re-throws if not present).
6
- * Returns a full cleanup function (onUnmount + mountCleanup + renderCleanup).
7
- */
8
- export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
9
- /**
10
- * Same as `_mountComponent` but silently swallows all lifecycle errors.
11
- * Used for transition content and error boundary fallbacks where errors
12
- * inside the fallback/transition itself must not propagate.
13
- */
14
- export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
15
- /**
16
- * Renders a ElurComponent using a captured context snapshot.
17
- * Used for dynamic/keyed rendering inside reactive effects, where the
18
- * provide/inject context must be inherited from the point of declaration.
19
- * Calls onMount immediately. Returns a full cleanup function.
20
- */
21
- export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
22
- /**
23
- * Renders a ElurComponent with *deferred* onMount — used inside `html` template
24
- * fragments where the DOM nodes are still in a DocumentFragment and onMount must
25
- * fire only after the fragment is inserted into the live document.
26
- *
27
- * Pushes the full cleanup into `disposes` and the onMount call into `postMountHooks`.
28
- */
29
- export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
1
+ export * from "../next-2/mount-helpers.js";
@@ -1,6 +1 @@
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;
1
+ export * from "../next-2/node-binding.js";
@@ -1,6 +1 @@
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;
1
+ export * from "../next-2/node-binding.js";
@@ -1,2 +1,2 @@
1
- const e=require(`../../lifecycle.cjs`),t=require(`../../context.cjs`),n=require(`./mount-helpers.cjs`);function r(){return{__isPortalOutlet:!0,_container:null}}function i(e){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(t,n){let r=document.createElement(`div`);return r.setAttribute(`data-elur-outlet`,``),e._container=r,t.insertBefore(r,n),()=>{e._container=null,r.remove()}}}}function a(t,r=document.body){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(i,a){let o;return o=typeof r==`string`?document.querySelector(r)??document.body:r instanceof Element?r:`__isPortalOutlet`in r?r._container??document.body:r.el??document.body,e.isElurComponent(t)?n._mountComponent(t,o,null):t._render(o,null)}}}var o=t.createInjectionKey(`elur:portal-outlet`);function s(e){t.provide(o,e)}function c(){return t.inject(o)}exports.createPortalOutlet=r,exports.injectOutlet=c,exports.portal=a,exports.portalOutlet=i,exports.provideOutlet=s;
1
+ const e=require(`../../lifecycle.cjs`),t=require(`../../context.cjs`),n=require(`../next-2/mount-helpers.cjs`);function r(){return{__isPortalOutlet:!0,_container:null}}function i(e){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(t,n){let r=document.createElement(`div`);return r.setAttribute(`data-elur-outlet`,``),e._container=r,t.insertBefore(r,n),()=>{e._container=null,r.remove()}}}}function a(t,r=document.body){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(i,a){let o;return o=typeof r==`string`?document.querySelector(r)??document.body:r instanceof Element?r:`__isPortalOutlet`in r?r._container??document.body:r.el??document.body,e.isElurComponent(t)?n._mountComponent(t,o,null):t._render(o,null)}}}var o=t.createInjectionKey(`elur:portal-outlet`);function s(e){t.provide(o,e)}function c(){return t.inject(o)}exports.createPortalOutlet=r,exports.injectOutlet=c,exports.portal=a,exports.portalOutlet=i,exports.provideOutlet=s;
2
2
  //# sourceMappingURL=portal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"portal.cjs","names":[],"sources":["../../../../src/elur/template/portal.ts"],"sourcesContent":["import { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport { provide, inject, createInjectionKey } from \"../context.js\";\nimport type { ElurTemplate, ElurMountHandle, ElurRef, PortalOutlet } from \"./types.js\";\nimport { _mountComponent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- PortalOutlet ---\n// =============================================================================\n\n/** Creates a PortalOutlet token for decoupled portal targeting. */\nexport function createPortalOutlet(): PortalOutlet {\n return { __isPortalOutlet: true as const, _container: null };\n}\n\n/** Declares the DOM anchor for a PortalOutlet inside a template. */\nexport function portalOutlet(outlet: PortalOutlet): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n _render(parent: Node, before: Node | null): () => void {\n const el = document.createElement(\"div\");\n el.setAttribute(\"data-elur-outlet\", \"\");\n outlet._container = el;\n parent.insertBefore(el, before);\n return () => {\n outlet._container = null;\n el.remove();\n };\n },\n };\n}\n\n// =============================================================================\n// --- portal() ---\n// =============================================================================\n\n/**\n * Renders `content` into `target` instead of the current tree position.\n * Useful for modals, tooltips, and overlays that must escape overflow clipping.\n * Returns a ElurTemplate — works inside reactive conditionals.\n *\n * @param content Template or component to render.\n * @param target CSS selector, Element, PortalOutlet, or ElurRef. Defaults to `document.body`.\n */\nexport function portal(\n content: ElurTemplate | ElurComponent,\n target: Element | string | PortalOutlet | ElurRef<Element> = document.body\n): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(_parent: Node, _before: Node | null): () => void {\n let targetEl: Element;\n if (typeof target === \"string\") {\n targetEl = document.querySelector(target) ?? document.body;\n } else if (target instanceof Element) {\n targetEl = target;\n } else if (\"__isPortalOutlet\" in target) {\n targetEl = (target as PortalOutlet)._container ?? document.body;\n } else {\n targetEl = (target as ElurRef<Element>).el ?? document.body;\n }\n\n if (isElurComponent(content)) {\n return _mountComponent(content, targetEl, null);\n }\n\n return content._render(targetEl, null);\n },\n };\n}\n\n// =============================================================================\n// --- Portal outlet via provide/inject ---\n// =============================================================================\n\nconst _OUTLET_KEY = createInjectionKey<PortalOutlet>(\"elur:portal-outlet\");\n\n/** Provides a PortalOutlet to descendant components via dependency injection. */\nexport function provideOutlet(outlet: PortalOutlet): void {\n provide(_OUTLET_KEY, outlet);\n}\n\n/** Injects the nearest PortalOutlet provided by an ancestor. */\nexport function injectOutlet(): PortalOutlet | undefined {\n return inject(_OUTLET_KEY);\n}\n"],"mappings":"uGAWA,SAAgB,GAAmC,CAC/C,MAAO,CAAE,iBAAkB,GAAe,WAAY,KAAM,CAIhE,SAAgB,EAAa,EAAoC,CAC7D,MAAO,CACH,iBAAkB,GAClB,MAAM,EAA8C,CAChD,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,EAAI,SAAS,KAC/C,EAEV,MAAO,CAAE,QADO,KAAK,QAAQ,EAAI,KAAK,CACX,EAE/B,QAAQ,EAAc,EAAiC,CACnD,IAAM,EAAK,SAAS,cAAc,MAAM,CAIxC,OAHA,EAAG,aAAa,mBAAoB,GAAG,CACvC,EAAO,WAAa,EACpB,EAAO,aAAa,EAAI,EAAO,KAClB,CACT,EAAO,WAAa,KACpB,EAAG,QAAQ,GAGtB,CAeL,SAAgB,EACZ,EACA,EAA6D,SAAS,KAC1D,CACZ,MAAO,CACH,iBAAkB,GAElB,MAAM,EAA8C,CAChD,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,EAAI,SAAS,KAC/C,EAEV,MAAO,CAAE,QADO,KAAK,QAAQ,EAAI,KAAK,CACX,EAG/B,QAAQ,EAAe,EAAkC,CACrD,IAAI,EAeJ,MAdA,CAOI,EAPA,OAAO,GAAW,SACP,SAAS,cAAc,EAAO,EAAI,SAAS,KAC/C,aAAkB,QACd,EACJ,qBAAsB,EACjB,EAAwB,YAAc,SAAS,KAE/C,EAA4B,IAAM,SAAS,KAGvD,EAAA,gBAAgB,EAAQ,CACjB,EAAA,gBAAgB,EAAS,EAAU,KAAK,CAG5C,EAAQ,QAAQ,EAAU,KAAK,EAE7C,CAOL,IAAM,EAAc,EAAA,mBAAiC,qBAAqB,CAG1E,SAAgB,EAAc,EAA4B,CACtD,EAAA,QAAQ,EAAa,EAAO,CAIhC,SAAgB,GAAyC,CACrD,OAAO,EAAA,OAAO,EAAY"}
1
+ {"version":3,"file":"portal.cjs","names":[],"sources":["../../../../src/elur/template/portal.ts"],"sourcesContent":["import { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport { provide, inject, createInjectionKey } from \"../context.js\";\nimport type { ElurTemplate, ElurMountHandle, ElurRef, PortalOutlet } from \"./types.js\";\nimport { _mountComponent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- PortalOutlet ---\n// =============================================================================\n\n/** Creates a PortalOutlet token for decoupled portal targeting. */\nexport function createPortalOutlet(): PortalOutlet {\n return { __isPortalOutlet: true as const, _container: null };\n}\n\n/** Declares the DOM anchor for a PortalOutlet inside a template. */\nexport function portalOutlet(outlet: PortalOutlet): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n _render(parent: Node, before: Node | null): () => void {\n const el = document.createElement(\"div\");\n el.setAttribute(\"data-elur-outlet\", \"\");\n outlet._container = el;\n parent.insertBefore(el, before);\n return () => {\n outlet._container = null;\n el.remove();\n };\n },\n };\n}\n\n// =============================================================================\n// --- portal() ---\n// =============================================================================\n\n/**\n * Renders `content` into `target` instead of the current tree position.\n * Useful for modals, tooltips, and overlays that must escape overflow clipping.\n * Returns a ElurTemplate — works inside reactive conditionals.\n *\n * @param content Template or component to render.\n * @param target CSS selector, Element, PortalOutlet, or ElurRef. Defaults to `document.body`.\n */\nexport function portal(\n content: ElurTemplate | ElurComponent,\n target: Element | string | PortalOutlet | ElurRef<Element> = document.body\n): ElurTemplate {\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(_parent: Node, _before: Node | null): () => void {\n let targetEl: Element;\n if (typeof target === \"string\") {\n targetEl = document.querySelector(target) ?? document.body;\n } else if (target instanceof Element) {\n targetEl = target;\n } else if (\"__isPortalOutlet\" in target) {\n targetEl = (target as PortalOutlet)._container ?? document.body;\n } else {\n targetEl = (target as ElurRef<Element>).el ?? document.body;\n }\n\n if (isElurComponent(content)) {\n return _mountComponent(content, targetEl, null);\n }\n\n return content._render(targetEl, null);\n },\n };\n}\n\n// =============================================================================\n// --- Portal outlet via provide/inject ---\n// =============================================================================\n\nconst _OUTLET_KEY = createInjectionKey<PortalOutlet>(\"elur:portal-outlet\");\n\n/** Provides a PortalOutlet to descendant components via dependency injection. */\nexport function provideOutlet(outlet: PortalOutlet): void {\n provide(_OUTLET_KEY, outlet);\n}\n\n/** Injects the nearest PortalOutlet provided by an ancestor. */\nexport function injectOutlet(): PortalOutlet | undefined {\n return inject(_OUTLET_KEY);\n}\n"],"mappings":"+GAWA,SAAgB,GAAmC,CAC/C,MAAO,CAAE,iBAAkB,GAAe,WAAY,KAAM,CAIhE,SAAgB,EAAa,EAAoC,CAC7D,MAAO,CACH,iBAAkB,GAClB,MAAM,EAA8C,CAChD,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,EAAI,SAAS,KAC/C,EAEV,MAAO,CAAE,QADO,KAAK,QAAQ,EAAI,KAAK,CACX,EAE/B,QAAQ,EAAc,EAAiC,CACnD,IAAM,EAAK,SAAS,cAAc,MAAM,CAIxC,OAHA,EAAG,aAAa,mBAAoB,GAAG,CACvC,EAAO,WAAa,EACpB,EAAO,aAAa,EAAI,EAAO,KAClB,CACT,EAAO,WAAa,KACpB,EAAG,QAAQ,GAGtB,CAeL,SAAgB,EACZ,EACA,EAA6D,SAAS,KAC1D,CACZ,MAAO,CACH,iBAAkB,GAElB,MAAM,EAA8C,CAChD,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,EAAI,SAAS,KAC/C,EAEV,MAAO,CAAE,QADO,KAAK,QAAQ,EAAI,KAAK,CACX,EAG/B,QAAQ,EAAe,EAAkC,CACrD,IAAI,EAeJ,MAdA,CAOI,EAPA,OAAO,GAAW,SACP,SAAS,cAAc,EAAO,EAAI,SAAS,KAC/C,aAAkB,QACd,EACJ,qBAAsB,EACjB,EAAwB,YAAc,SAAS,KAE/C,EAA4B,IAAM,SAAS,KAGvD,EAAA,gBAAgB,EAAQ,CACjB,EAAA,gBAAgB,EAAS,EAAU,KAAK,CAG5C,EAAQ,QAAQ,EAAU,KAAK,EAE7C,CAOL,IAAM,EAAc,EAAA,mBAAiC,qBAAqB,CAG1E,SAAgB,EAAc,EAA4B,CACtD,EAAA,QAAQ,EAAa,EAAO,CAIhC,SAAgB,GAAyC,CACrD,OAAO,EAAA,OAAO,EAAY"}
@@ -1,6 +1,6 @@
1
1
  import { isElurComponent as e } from "../../lifecycle.js";
2
2
  import { createInjectionKey as t, inject as n, provide as r } from "../../context.js";
3
- import { _mountComponent as i } from "./mount-helpers.js";
3
+ import { _mountComponent as i } from "../next-2/mount-helpers.js";
4
4
  //#region src/elur/template/portal.ts
5
5
  function a() {
6
6
  return {
@@ -1,2 +1,2 @@
1
- const e=require(`../../signals.cjs`),t=require(`./types.cjs`),n=require(`../../lifecycle.cjs`),r=require(`./mount-helpers.cjs`);function i(e){let t=e.name??`elur`;return{enterFrom:e.enterFrom??`${t}-enter-from`,enterActive:e.enterActive??`${t}-enter-active`,enterTo:e.enterTo??`${t}-enter-to`,leaveFrom:e.leaveFrom??`${t}-leave-from`,leaveActive:e.leaveActive??`${t}-leave-active`,leaveTo:e.leaveTo??`${t}-leave-to`}}function a(e){return Math.max(0,...e.split(`,`).map(e=>parseFloat(e.trim())||0))}function o(e,t=0){return new Promise(n=>{let r=getComputedStyle(e),i=Math.max(a(r.transitionDuration||`0`),a(r.animationDuration||`0`))*1e3,o=i>0?i+100:t;if(o<=0){n();return}let s,c=t=>{t.target===e&&(clearTimeout(s),e.removeEventListener(`transitionend`,c),e.removeEventListener(`animationend`,c),n())};e.addEventListener(`transitionend`,c),e.addEventListener(`animationend`,c),s=setTimeout(()=>{e.removeEventListener(`transitionend`,c),e.removeEventListener(`animationend`,c),n()},o)})}function s(a,s={}){let c=i(s);return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(i,l){let u=document.createComment(t.COMMENT.TRANSITION);i.insertBefore(u,l);let d=null,f=null,p=0,m=!0,h=()=>{let e=u.nextSibling;for(;e&&e!==l;){if(e.nodeType===Node.ELEMENT_NODE)return e;e=e.nextSibling}return null};function g(e){return n.isElurComponent(e)?r._mountComponentSilent(e,i,l):e._render(i,l)}let _=(e,t=!1)=>{p++,f&&=(f(),null),d=g(e);let n=h();if(n&&(!m||s.appear)&&!t){let e=p;(async()=>{s.onBeforeEnter?.(n),n.classList.add(c.enterFrom,c.enterActive),n.getBoundingClientRect(),await new Promise(e=>requestAnimationFrame(()=>e())),p===e&&(n.classList.remove(c.enterFrom),n.classList.add(c.enterTo),await o(n,s.duration),p===e&&(n.classList.remove(c.enterActive,c.enterTo),s.onAfterEnter?.(n)))})().catch(()=>{})}m=!1},v=()=>{let e=d;d=null;let t=h();if(!t){e?.();return}let n=++p;f=e??null,(async()=>{s.onBeforeLeave?.(t),t.classList.add(c.leaveFrom,c.leaveActive),t.getBoundingClientRect(),await new Promise(e=>requestAnimationFrame(()=>e())),p===n&&(t.classList.remove(c.leaveFrom),t.classList.add(c.leaveTo),await o(t,s.duration),p===n&&(t.classList.remove(c.leaveActive,c.leaveTo),s.onAfterLeave?.(t),f?.(),f=null))})().catch(()=>{})},y=null;if(typeof a==`function`&&!n.isElurComponent(a)){let t=a,n=null;y=e.effect(()=>{let e=t(),r=n===null,i=e===null;r&&!i?_(e):!r&&i?v():!r&&!i&&(p++,f?.(),f=null,d?.(),d=null,_(e,!0)),n=e}),m=!1}else _(a);return()=>{p++,y?.(),d?.(),f?.(),d=null,f=null,u.remove()}}}}exports.transition=s;
1
+ const e=require(`../next-2/reactivity.cjs`),t=require(`./types.cjs`),n=require(`../../lifecycle.cjs`),r=require(`../next-2/mount-helpers.cjs`);function i(e){let t=e.name??`elur`;return{enterFrom:e.enterFrom??`${t}-enter-from`,enterActive:e.enterActive??`${t}-enter-active`,enterTo:e.enterTo??`${t}-enter-to`,leaveFrom:e.leaveFrom??`${t}-leave-from`,leaveActive:e.leaveActive??`${t}-leave-active`,leaveTo:e.leaveTo??`${t}-leave-to`}}function a(e){return Math.max(0,...e.split(`,`).map(e=>parseFloat(e.trim())||0))}function o(e,t=0){return new Promise(n=>{let r=getComputedStyle(e),i=Math.max(a(r.transitionDuration||`0`),a(r.animationDuration||`0`))*1e3,o=i>0?i+100:t;if(o<=0){n();return}let s,c=t=>{t.target===e&&(clearTimeout(s),e.removeEventListener(`transitionend`,c),e.removeEventListener(`animationend`,c),n())};e.addEventListener(`transitionend`,c),e.addEventListener(`animationend`,c),s=setTimeout(()=>{e.removeEventListener(`transitionend`,c),e.removeEventListener(`animationend`,c),n()},o)})}function s(a,s={}){let c=i(s);return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(i,l){let u=document.createComment(t.COMMENT.TRANSITION);i.insertBefore(u,l);let d=null,f=null,p=0,m=!0,h=()=>{let e=u.nextSibling;for(;e&&e!==l;){if(e.nodeType===Node.ELEMENT_NODE)return e;e=e.nextSibling}return null};function g(e){return n.isElurComponent(e)?r._mountComponentSilent(e,i,l):e._render(i,l)}let _=(e,t=!1)=>{p++,f&&=(f(),null),d=g(e);let n=h();if(n&&(!m||s.appear)&&!t){let e=p;(async()=>{s.onBeforeEnter?.(n),n.classList.add(c.enterFrom,c.enterActive),n.getBoundingClientRect(),await new Promise(e=>requestAnimationFrame(()=>e())),p===e&&(n.classList.remove(c.enterFrom),n.classList.add(c.enterTo),await o(n,s.duration),p===e&&(n.classList.remove(c.enterActive,c.enterTo),s.onAfterEnter?.(n)))})().catch(()=>{})}m=!1},v=()=>{let e=d;d=null;let t=h();if(!t){e?.();return}let n=++p;f=e??null,(async()=>{s.onBeforeLeave?.(t),t.classList.add(c.leaveFrom,c.leaveActive),t.getBoundingClientRect(),await new Promise(e=>requestAnimationFrame(()=>e())),p===n&&(t.classList.remove(c.leaveFrom),t.classList.add(c.leaveTo),await o(t,s.duration),p===n&&(t.classList.remove(c.leaveActive,c.leaveTo),s.onAfterLeave?.(t),f?.(),f=null))})().catch(()=>{})},y=null;if(typeof a==`function`&&!n.isElurComponent(a)){let t=a,n=null;y=e.effect(()=>{let e=t(),r=n===null,i=e===null;r&&!i?_(e):!r&&i?v():!r&&!i&&(p++,f?.(),f=null,d?.(),d=null,_(e,!0)),n=e}),m=!1}else _(a);return()=>{p++,y?.(),d?.(),f?.(),d=null,f=null,u.remove()}}}}exports.transition=s;
2
2
  //# sourceMappingURL=transitions.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transitions.cjs","names":[],"sources":["../../../../src/elur/template/transitions.ts"],"sourcesContent":["import { effect } from \"../reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport type { ElurTemplate, ElurMountHandle, TransitionContent } from \"./types.js\";\nimport { COMMENT } from \"./types.js\";\nimport { _mountComponentSilent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- TransitionOptions ---\n// =============================================================================\n\n/**\n * Options for `transition()`. All class-name overrides are optional — by\n * default they are derived from `name` (default `\"elur\"`).\n *\n * | phase | from class | active class | to class |\n * |--------------|-------------------|---------------------|-----------------|\n * | enter | `{n}-enter-from` | `{n}-enter-active` | `{n}-enter-to` |\n * | leave | `{n}-leave-from` | `{n}-leave-active` | `{n}-leave-to` |\n */\nexport interface TransitionOptions {\n /**\n * Prefix for all generated CSS classes. Default `\"elur\"`.\n * e.g. `name: \"fade\"` generates `.fade-enter-from`, `.fade-leave-to`, …\n */\n name?: string;\n enterFrom?: string;\n enterActive?: string;\n enterTo?: string;\n leaveFrom?: string;\n leaveActive?: string;\n leaveTo?: string;\n /**\n * When `true` the enter transition also plays on the very first render\n * (similar to Vue's `appear`). Default `false`.\n */\n appear?: boolean;\n /**\n * Fallback duration in **milliseconds** used when no `transition-duration`\n * or `animation-duration` is found on the element via `getComputedStyle`.\n */\n duration?: number;\n onBeforeEnter?: (el: Element) => void;\n onAfterEnter?: (el: Element) => void;\n onBeforeLeave?: (el: Element) => void;\n onAfterLeave?: (el: Element) => void;\n}\n\n// =============================================================================\n// --- Internal transition helpers ---\n// =============================================================================\n\nfunction _resolveTransitionClasses(opts: TransitionOptions) {\n const n = opts.name ?? \"elur\";\n return {\n enterFrom: opts.enterFrom ?? `${n}-enter-from`,\n enterActive: opts.enterActive ?? `${n}-enter-active`,\n enterTo: opts.enterTo ?? `${n}-enter-to`,\n leaveFrom: opts.leaveFrom ?? `${n}-leave-from`,\n leaveActive: opts.leaveActive ?? `${n}-leave-active`,\n leaveTo: opts.leaveTo ?? `${n}-leave-to`,\n };\n}\n\nfunction _cssMaxDuration(cssValue: string): number {\n return Math.max(0, ...cssValue.split(\",\").map((s) => parseFloat(s.trim()) || 0));\n}\n\nfunction _waitTransitionEnd(el: Element, fallbackMs = 0): Promise<void> {\n return new Promise((resolve) => {\n const st = getComputedStyle(el);\n const ms =\n Math.max(\n _cssMaxDuration(st.transitionDuration || \"0\"),\n _cssMaxDuration(st.animationDuration || \"0\"),\n ) * 1000;\n const wait = ms > 0 ? ms + 100 : fallbackMs;\n\n if (wait <= 0) { resolve(); return; }\n\n let timerId: ReturnType<typeof setTimeout>;\n const done = (e: Event) => {\n if (e.target !== el) return;\n clearTimeout(timerId);\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n };\n el.addEventListener(\"transitionend\", done);\n el.addEventListener(\"animationend\", done);\n timerId = setTimeout(() => {\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n }, wait);\n });\n}\n\n// =============================================================================\n// --- transition() ---\n// =============================================================================\n\n/**\n * Wraps content with CSS class-based enter/leave transitions.\n * Static content plays enter on mount (only with `appear: true`).\n * Reactive `() => Template | null` auto-animates enter/leave on toggle.\n */\nexport function transition(\n content: TransitionContent,\n options: TransitionOptions = {},\n): ElurTemplate {\n const cls = _resolveTransitionClasses(options);\n\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(parent: Node, before: Node | null): () => void {\n const marker = document.createComment(COMMENT.TRANSITION);\n parent.insertBefore(marker, before);\n\n let contentCleanup: (() => void) | null = null;\n let leaveCleanup: (() => void) | null = null;\n let leaveGen = 0;\n let isFirstRender = true;\n\n /** Find first Element node between `marker` and `before`. */\n const getEl = (): Element | null => {\n let node: Node | null = marker.nextSibling;\n while (node && node !== before) {\n if (node.nodeType === Node.ELEMENT_NODE) return node as Element;\n node = node.nextSibling;\n }\n return null;\n };\n\n function mountContent(tpl: ElurTemplate | ElurComponent): () => void {\n if (isElurComponent(tpl)) {\n return _mountComponentSilent(tpl as ElurComponent, parent, before);\n }\n return (tpl as ElurTemplate)._render(parent, before);\n }\n\n /** Mount content and play enter animation (does NOT block). */\n const doEnter = (tpl: ElurTemplate | ElurComponent, skipAnim = false): void => {\n leaveGen++;\n if (leaveCleanup) {\n leaveCleanup();\n leaveCleanup = null;\n }\n\n contentCleanup = mountContent(tpl);\n\n const el = getEl();\n const shouldAnimate = el && (!isFirstRender || options.appear) && !skipAnim;\n if (shouldAnimate) {\n const gen = leaveGen;\n const doIt = async () => {\n options.onBeforeEnter?.(el);\n el.classList.add(cls.enterFrom, cls.enterActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterFrom);\n el.classList.add(cls.enterTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterActive, cls.enterTo);\n options.onAfterEnter?.(el);\n };\n doIt().catch(() => { /* ignore */ });\n }\n isFirstRender = false;\n };\n\n /** Remove current content after playing leave animation (does NOT block). */\n const doLeave = (): void => {\n const savedCleanup = contentCleanup;\n contentCleanup = null;\n const el = getEl();\n\n if (!el) { savedCleanup?.(); return; }\n\n const gen = ++leaveGen;\n leaveCleanup = savedCleanup ?? null;\n\n const doIt = async () => {\n options.onBeforeLeave?.(el);\n el.classList.add(cls.leaveFrom, cls.leaveActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveFrom);\n el.classList.add(cls.leaveTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveActive, cls.leaveTo);\n options.onAfterLeave?.(el);\n leaveCleanup?.();\n leaveCleanup = null;\n };\n doIt().catch(() => { /* ignore */ });\n };\n\n let disposeWatcher: (() => void) | null = null;\n\n if (typeof content === \"function\" && !isElurComponent(content as unknown)) {\n const getter = content as () => ElurTemplate | ElurComponent | null;\n let prevVal: ElurTemplate | ElurComponent | null = null;\n\n disposeWatcher = effect(() => {\n const val = getter();\n const wasNull = prevVal === null;\n const isNull = val === null;\n\n if (wasNull && !isNull) {\n doEnter(val!);\n } else if (!wasNull && isNull) {\n doLeave();\n } else if (!wasNull && !isNull) {\n leaveGen++;\n leaveCleanup?.();\n leaveCleanup = null;\n contentCleanup?.();\n contentCleanup = null;\n doEnter(val!, true);\n }\n prevVal = val;\n });\n isFirstRender = false;\n } else {\n doEnter(content as ElurTemplate | ElurComponent);\n }\n\n return () => {\n leaveGen++;\n disposeWatcher?.();\n contentCleanup?.();\n leaveCleanup?.();\n contentCleanup = null;\n leaveCleanup = null;\n marker.remove();\n };\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transitions.cjs","names":[],"sources":["../../../../src/elur/template/transitions.ts"],"sourcesContent":["import { effect } from \"../reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport type { ElurTemplate, ElurMountHandle, TransitionContent } from \"./types.js\";\nimport { COMMENT } from \"./types.js\";\nimport { _mountComponentSilent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- TransitionOptions ---\n// =============================================================================\n\n/**\n * Options for `transition()`. All class-name overrides are optional — by\n * default they are derived from `name` (default `\"elur\"`).\n *\n * | phase | from class | active class | to class |\n * |--------------|-------------------|---------------------|-----------------|\n * | enter | `{n}-enter-from` | `{n}-enter-active` | `{n}-enter-to` |\n * | leave | `{n}-leave-from` | `{n}-leave-active` | `{n}-leave-to` |\n */\nexport interface TransitionOptions {\n /**\n * Prefix for all generated CSS classes. Default `\"elur\"`.\n * e.g. `name: \"fade\"` generates `.fade-enter-from`, `.fade-leave-to`, …\n */\n name?: string;\n enterFrom?: string;\n enterActive?: string;\n enterTo?: string;\n leaveFrom?: string;\n leaveActive?: string;\n leaveTo?: string;\n /**\n * When `true` the enter transition also plays on the very first render\n * (similar to Vue's `appear`). Default `false`.\n */\n appear?: boolean;\n /**\n * Fallback duration in **milliseconds** used when no `transition-duration`\n * or `animation-duration` is found on the element via `getComputedStyle`.\n */\n duration?: number;\n onBeforeEnter?: (el: Element) => void;\n onAfterEnter?: (el: Element) => void;\n onBeforeLeave?: (el: Element) => void;\n onAfterLeave?: (el: Element) => void;\n}\n\n// =============================================================================\n// --- Internal transition helpers ---\n// =============================================================================\n\nfunction _resolveTransitionClasses(opts: TransitionOptions) {\n const n = opts.name ?? \"elur\";\n return {\n enterFrom: opts.enterFrom ?? `${n}-enter-from`,\n enterActive: opts.enterActive ?? `${n}-enter-active`,\n enterTo: opts.enterTo ?? `${n}-enter-to`,\n leaveFrom: opts.leaveFrom ?? `${n}-leave-from`,\n leaveActive: opts.leaveActive ?? `${n}-leave-active`,\n leaveTo: opts.leaveTo ?? `${n}-leave-to`,\n };\n}\n\nfunction _cssMaxDuration(cssValue: string): number {\n return Math.max(0, ...cssValue.split(\",\").map((s) => parseFloat(s.trim()) || 0));\n}\n\nfunction _waitTransitionEnd(el: Element, fallbackMs = 0): Promise<void> {\n return new Promise((resolve) => {\n const st = getComputedStyle(el);\n const ms =\n Math.max(\n _cssMaxDuration(st.transitionDuration || \"0\"),\n _cssMaxDuration(st.animationDuration || \"0\"),\n ) * 1000;\n const wait = ms > 0 ? ms + 100 : fallbackMs;\n\n if (wait <= 0) { resolve(); return; }\n\n let timerId: ReturnType<typeof setTimeout>;\n const done = (e: Event) => {\n if (e.target !== el) return;\n clearTimeout(timerId);\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n };\n el.addEventListener(\"transitionend\", done);\n el.addEventListener(\"animationend\", done);\n timerId = setTimeout(() => {\n el.removeEventListener(\"transitionend\", done);\n el.removeEventListener(\"animationend\", done);\n resolve();\n }, wait);\n });\n}\n\n// =============================================================================\n// --- transition() ---\n// =============================================================================\n\n/**\n * Wraps content with CSS class-based enter/leave transitions.\n * Static content plays enter on mount (only with `appear: true`).\n * Reactive `() => Template | null` auto-animates enter/leave on toggle.\n */\nexport function transition(\n content: TransitionContent,\n options: TransitionOptions = {},\n): ElurTemplate {\n const cls = _resolveTransitionClasses(options);\n\n return {\n __isElurTemplate: true as const,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) ?? document.body)\n : container;\n const cleanup = this._render(el, null);\n return { unmount: cleanup };\n },\n\n _render(parent: Node, before: Node | null): () => void {\n const marker = document.createComment(COMMENT.TRANSITION);\n parent.insertBefore(marker, before);\n\n let contentCleanup: (() => void) | null = null;\n let leaveCleanup: (() => void) | null = null;\n let leaveGen = 0;\n let isFirstRender = true;\n\n /** Find first Element node between `marker` and `before`. */\n const getEl = (): Element | null => {\n let node: Node | null = marker.nextSibling;\n while (node && node !== before) {\n if (node.nodeType === Node.ELEMENT_NODE) return node as Element;\n node = node.nextSibling;\n }\n return null;\n };\n\n function mountContent(tpl: ElurTemplate | ElurComponent): () => void {\n if (isElurComponent(tpl)) {\n return _mountComponentSilent(tpl as ElurComponent, parent, before);\n }\n return (tpl as ElurTemplate)._render(parent, before);\n }\n\n /** Mount content and play enter animation (does NOT block). */\n const doEnter = (tpl: ElurTemplate | ElurComponent, skipAnim = false): void => {\n leaveGen++;\n if (leaveCleanup) {\n leaveCleanup();\n leaveCleanup = null;\n }\n\n contentCleanup = mountContent(tpl);\n\n const el = getEl();\n const shouldAnimate = el && (!isFirstRender || options.appear) && !skipAnim;\n if (shouldAnimate) {\n const gen = leaveGen;\n const doIt = async () => {\n options.onBeforeEnter?.(el);\n el.classList.add(cls.enterFrom, cls.enterActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterFrom);\n el.classList.add(cls.enterTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.enterActive, cls.enterTo);\n options.onAfterEnter?.(el);\n };\n doIt().catch(() => { /* ignore */ });\n }\n isFirstRender = false;\n };\n\n /** Remove current content after playing leave animation (does NOT block). */\n const doLeave = (): void => {\n const savedCleanup = contentCleanup;\n contentCleanup = null;\n const el = getEl();\n\n if (!el) { savedCleanup?.(); return; }\n\n const gen = ++leaveGen;\n leaveCleanup = savedCleanup ?? null;\n\n const doIt = async () => {\n options.onBeforeLeave?.(el);\n el.classList.add(cls.leaveFrom, cls.leaveActive);\n void el.getBoundingClientRect();\n await new Promise<void>((r) => requestAnimationFrame(() => r()));\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveFrom);\n el.classList.add(cls.leaveTo);\n await _waitTransitionEnd(el, options.duration);\n if (leaveGen !== gen) return;\n el.classList.remove(cls.leaveActive, cls.leaveTo);\n options.onAfterLeave?.(el);\n leaveCleanup?.();\n leaveCleanup = null;\n };\n doIt().catch(() => { /* ignore */ });\n };\n\n let disposeWatcher: (() => void) | null = null;\n\n if (typeof content === \"function\" && !isElurComponent(content as unknown)) {\n const getter = content as () => ElurTemplate | ElurComponent | null;\n let prevVal: ElurTemplate | ElurComponent | null = null;\n\n disposeWatcher = effect(() => {\n const val = getter();\n const wasNull = prevVal === null;\n const isNull = val === null;\n\n if (wasNull && !isNull) {\n doEnter(val!);\n } else if (!wasNull && isNull) {\n doLeave();\n } else if (!wasNull && !isNull) {\n leaveGen++;\n leaveCleanup?.();\n leaveCleanup = null;\n contentCleanup?.();\n contentCleanup = null;\n doEnter(val!, true);\n }\n prevVal = val;\n });\n isFirstRender = false;\n } else {\n doEnter(content as ElurTemplate | ElurComponent);\n }\n\n return () => {\n leaveGen++;\n disposeWatcher?.();\n contentCleanup?.();\n leaveCleanup?.();\n contentCleanup = null;\n leaveCleanup = null;\n marker.remove();\n };\n },\n };\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { effect as e } from "../../signals.js";
1
+ import { effect as e } from "../next-2/reactivity.js";
2
2
  import { COMMENT as t } from "./types.js";
3
3
  import { isElurComponent as n } from "../../lifecycle.js";
4
- import { _mountComponentSilent as r } from "./mount-helpers.js";
4
+ import { _mountComponentSilent as r } from "../next-2/mount-helpers.js";
5
5
  //#region src/elur/template/transitions.ts
6
6
  function i(e) {
7
7
  let t = e.name ?? "elur";
@@ -1,2 +1,2 @@
1
- var e=Symbol.for(`@elurjs/core/template-descriptor`),t=Symbol.for(`@elurjs/core/render-protocol`),n={partialAttributeInterpolation:!1};function r(){return{el:null}}var i={SCOPE:`elur-scope`,ERROR_BOUNDARY:`elur-eb`,TRANSITION:`elur-t`,KEYED_START:`elur-ks`,KEYED_END:`elur-ke`,KEYED_ZONE:`elur-kz`};function a(e){return typeof e==`object`&&!!e&&e.__isElurTemplate===!0}function o(e){return typeof e==`object`&&!!e&&e.__isKeyedList===!0}exports.COMMENT=i,exports.ELUR_RENDER_PROTOCOL=t,exports.ELUR_TEMPLATE_DESCRIPTOR=e,exports.isElurTemplate=a,exports.isKeyedList=o,exports.ref=r,exports.templateFeatures=n;
1
+ var e=Symbol.for(`@elurjs/core/template-descriptor`),t=Symbol.for(`@elurjs/core/render-protocol`),n={partialAttributeInterpolation:!1};function r(){return{el:null}}var i={SCOPE:`elur-scope`,ERROR_BOUNDARY:`elur-eb`,TRANSITION:`elur-t`,KEYED_START:`elur-ks`,KEYED_END:`elur-ke`,KEYED_ZONE:`elur-kz`};function a(e){return typeof e==`object`&&!!e&&e.__isElurTemplate===!0}function o(e){return typeof e==`object`&&!!e&&e.__isKeyedList===!0}var s=Symbol.for(`elur.derived`);function c(e){return typeof e==`object`&&!!e&&e[s]===!0}exports.COMMENT=i,exports.ELUR_RENDER_PROTOCOL=t,exports.ELUR_TEMPLATE_DESCRIPTOR=e,exports.isDerivedBinding=c,exports.isElurTemplate=a,exports.isKeyedList=o,exports.ref=r,exports.templateFeatures=n;
2
2
  //# sourceMappingURL=types.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.cjs","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n"],"mappings":"AA6CA,IAAa,EAA2B,OAAO,IAAI,mCAAmC,CACzE,EAAuB,OAAO,IAAI,+BAA+B,CAUjE,EAAmB,CAE5B,8BAA+B,GAClC,CAsBD,SAAgB,GAA+C,CAC3D,MAAO,CAAE,GAAI,KAAM,CAoCvB,IAAa,EAAU,CACnB,MAAO,aACP,eAAgB,UAChB,WAAY,SACZ,YAAa,UACb,UAAW,UACX,WAAY,UACf,CAMD,SAAgB,EAAe,EAA+B,CAC1D,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,mBAAqB,GAI5D,SAAgB,EAAY,EAA4B,CACpD,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,gBAAkB"}
1
+ {"version":3,"file":"types.cjs","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n /**\n * C.13: hidratación compilada — el codegen emite una función que activa\n * los bindings por posición (access paths) en vez de un scan global de\n * markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)\n * siguen marcados en el HTML; `data-elur-*` no se emiten.\n * `bounds` se pasa cuando el descriptor es anidado dentro de otro\n * binding. Devuelve cleanup.\n */\n readonly hydrate?: (\n root: ParentNode,\n values: readonly unknown[],\n options?: unknown,\n bounds?: { start: Comment; end: Comment } | null,\n ) => (() => void) | void;\n /**\n * C.12 fase 2: renderer SSR especializado — el codegen emite una función\n * generadora que secuencia los chunks con los strings ya cortados\n * (`attr=`/comillas pre-resueltos en build). Toda la semántica\n * (resolución de valores, sanitización, markers, abort) sigue en los\n * helpers `emit.*` del core — el artefacto compilado y el descriptor\n * genérico producen exactamente el mismo HTML.\n */\n readonly ssr?: (\n emit: SsrEmit,\n values: readonly unknown[],\n ) => AsyncGenerator<SsrChunk, void, unknown>;\n}\n\n/** Chunk producido por el renderer SSR especializado (descriptor.ssr). */\nexport interface SsrChunk {\n readonly type: \"markup\" | \"boundary-start\" | \"boundary-end\" | \"error\" | \"done\";\n readonly value: string;\n readonly index: number;\n}\n\n/** Ops que el core expone al renderer SSR especializado. */\nexport interface SsrEmit {\n /** Static markup, ya cortado en build. */\n m(value: string): SsrChunk;\n /** Binding node: boundaries + resolución + renderValueChunks. */\n node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;\n /** Binding attr: prefix + `name=\"v\"` serializada + marker opcional. */\n attr(\n prefix: string,\n index: number,\n attrName: string,\n url: boolean,\n executable: boolean,\n value: unknown,\n ): Promise<SsrChunk[]>;\n /** Binding event: marker data-elur-e o prefix recortado. */\n event(index: number, prefix: string, eventName: string): SsrChunk;\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n /**\n * C.16.4: item que originó la entry — permite detectar\n * \"misma key, objeto nuevo\" y re-montarla in-place. Opcional porque\n * algunos paths (adopción vieja, internals) no lo registran.\n */\n item?: unknown;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n\n/** Marca del pack de binding derivado T2 emitido por el compilador. */\nexport const ELUR_DERIVED = Symbol.for(\"elur.derived\");\n\nexport interface ElurDerivedBinding {\n deps: unknown[];\n get: () => unknown;\n}\n\n/**\n * Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for\n * permite detección cross-module (plugin runtime vs core hydrate/SSR).\n */\nexport function isDerivedBinding(v: unknown): v is ElurDerivedBinding {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<symbol, unknown>)[ELUR_DERIVED] === true\n );\n}\n"],"mappings":"AAiGA,IAAa,EAA2B,OAAO,IAAI,mCAAmC,CACzE,EAAuB,OAAO,IAAI,+BAA+B,CAUjE,EAAmB,CAE5B,8BAA+B,GAClC,CAsBD,SAAgB,GAA+C,CAC3D,MAAO,CAAE,GAAI,KAAM,CA0CvB,IAAa,EAAU,CACnB,MAAO,aACP,eAAgB,UAChB,WAAY,SACZ,YAAa,UACb,UAAW,UACX,WAAY,UACf,CAMD,SAAgB,EAAe,EAA+B,CAC1D,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,mBAAqB,GAI5D,SAAgB,EAAY,EAA4B,CACpD,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,gBAAkB,GAKzD,IAAa,EAAe,OAAO,IAAI,eAAe,CAWtD,SAAgB,EAAiB,EAAqC,CAClE,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,KAAkB"}
@@ -17,6 +17,44 @@ export interface TemplateDescriptor {
17
17
  readonly strings: readonly string[];
18
18
  readonly values: readonly unknown[];
19
19
  readonly contexts: readonly TemplateBindingContext[];
20
+ /**
21
+ * C.13: hidratación compilada — el codegen emite una función que activa
22
+ * los bindings por posición (access paths) en vez de un scan global de
23
+ * markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)
24
+ * siguen marcados en el HTML; `data-elur-*` no se emiten.
25
+ * `bounds` se pasa cuando el descriptor es anidado dentro de otro
26
+ * binding. Devuelve cleanup.
27
+ */
28
+ readonly hydrate?: (root: ParentNode, values: readonly unknown[], options?: unknown, bounds?: {
29
+ start: Comment;
30
+ end: Comment;
31
+ } | null) => (() => void) | void;
32
+ /**
33
+ * C.12 fase 2: renderer SSR especializado — el codegen emite una función
34
+ * generadora que secuencia los chunks con los strings ya cortados
35
+ * (`attr=`/comillas pre-resueltos en build). Toda la semántica
36
+ * (resolución de valores, sanitización, markers, abort) sigue en los
37
+ * helpers `emit.*` del core — el artefacto compilado y el descriptor
38
+ * genérico producen exactamente el mismo HTML.
39
+ */
40
+ readonly ssr?: (emit: SsrEmit, values: readonly unknown[]) => AsyncGenerator<SsrChunk, void, unknown>;
41
+ }
42
+ /** Chunk producido por el renderer SSR especializado (descriptor.ssr). */
43
+ export interface SsrChunk {
44
+ readonly type: "markup" | "boundary-start" | "boundary-end" | "error" | "done";
45
+ readonly value: string;
46
+ readonly index: number;
47
+ }
48
+ /** Ops que el core expone al renderer SSR especializado. */
49
+ export interface SsrEmit {
50
+ /** Static markup, ya cortado en build. */
51
+ m(value: string): SsrChunk;
52
+ /** Binding node: boundaries + resolución + renderValueChunks. */
53
+ node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;
54
+ /** Binding attr: prefix + `name="v"` serializada + marker opcional. */
55
+ attr(prefix: string, index: number, attrName: string, url: boolean, executable: boolean, value: unknown): Promise<SsrChunk[]>;
56
+ /** Binding event: marker data-elur-e o prefix recortado. */
57
+ event(index: number, prefix: string, eventName: string): SsrChunk;
20
58
  }
21
59
  export interface ServerRenderProtocolContext {
22
60
  readonly markers: boolean;
@@ -91,6 +129,12 @@ export interface KEntry {
91
129
  start: Comment;
92
130
  end: Comment;
93
131
  cleanup: () => void;
132
+ /**
133
+ * C.16.4: item que originó la entry — permite detectar
134
+ * "misma key, objeto nuevo" y re-montarla in-place. Opcional porque
135
+ * algunos paths (adopción vieja, internals) no lo registran.
136
+ */
137
+ item?: unknown;
94
138
  }
95
139
  /** Opaque token for a named portal target. */
96
140
  export interface PortalOutlet {
@@ -112,3 +156,14 @@ export declare const COMMENT: {
112
156
  };
113
157
  export declare function isElurTemplate(v: unknown): v is ElurTemplate;
114
158
  export declare function isKeyedList(v: unknown): v is KeyedList;
159
+ /** Marca del pack de binding derivado T2 emitido por el compilador. */
160
+ export declare const ELUR_DERIVED: unique symbol;
161
+ export interface ElurDerivedBinding {
162
+ deps: unknown[];
163
+ get: () => unknown;
164
+ }
165
+ /**
166
+ * Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for
167
+ * permite detección cross-module (plugin runtime vs core hydrate/SSR).
168
+ */
169
+ export declare function isDerivedBinding(v: unknown): v is ElurDerivedBinding;
@@ -17,6 +17,44 @@ export interface TemplateDescriptor {
17
17
  readonly strings: readonly string[];
18
18
  readonly values: readonly unknown[];
19
19
  readonly contexts: readonly TemplateBindingContext[];
20
+ /**
21
+ * C.13: hidratación compilada — el codegen emite una función que activa
22
+ * los bindings por posición (access paths) en vez de un scan global de
23
+ * markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)
24
+ * siguen marcados en el HTML; `data-elur-*` no se emiten.
25
+ * `bounds` se pasa cuando el descriptor es anidado dentro de otro
26
+ * binding. Devuelve cleanup.
27
+ */
28
+ readonly hydrate?: (root: ParentNode, values: readonly unknown[], options?: unknown, bounds?: {
29
+ start: Comment;
30
+ end: Comment;
31
+ } | null) => (() => void) | void;
32
+ /**
33
+ * C.12 fase 2: renderer SSR especializado — el codegen emite una función
34
+ * generadora que secuencia los chunks con los strings ya cortados
35
+ * (`attr=`/comillas pre-resueltos en build). Toda la semántica
36
+ * (resolución de valores, sanitización, markers, abort) sigue en los
37
+ * helpers `emit.*` del core — el artefacto compilado y el descriptor
38
+ * genérico producen exactamente el mismo HTML.
39
+ */
40
+ readonly ssr?: (emit: SsrEmit, values: readonly unknown[]) => AsyncGenerator<SsrChunk, void, unknown>;
41
+ }
42
+ /** Chunk producido por el renderer SSR especializado (descriptor.ssr). */
43
+ export interface SsrChunk {
44
+ readonly type: "markup" | "boundary-start" | "boundary-end" | "error" | "done";
45
+ readonly value: string;
46
+ readonly index: number;
47
+ }
48
+ /** Ops que el core expone al renderer SSR especializado. */
49
+ export interface SsrEmit {
50
+ /** Static markup, ya cortado en build. */
51
+ m(value: string): SsrChunk;
52
+ /** Binding node: boundaries + resolución + renderValueChunks. */
53
+ node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;
54
+ /** Binding attr: prefix + `name="v"` serializada + marker opcional. */
55
+ attr(prefix: string, index: number, attrName: string, url: boolean, executable: boolean, value: unknown): Promise<SsrChunk[]>;
56
+ /** Binding event: marker data-elur-e o prefix recortado. */
57
+ event(index: number, prefix: string, eventName: string): SsrChunk;
20
58
  }
21
59
  export interface ServerRenderProtocolContext {
22
60
  readonly markers: boolean;
@@ -91,6 +129,12 @@ export interface KEntry {
91
129
  start: Comment;
92
130
  end: Comment;
93
131
  cleanup: () => void;
132
+ /**
133
+ * C.16.4: item que originó la entry — permite detectar
134
+ * "misma key, objeto nuevo" y re-montarla in-place. Opcional porque
135
+ * algunos paths (adopción vieja, internals) no lo registran.
136
+ */
137
+ item?: unknown;
94
138
  }
95
139
  /** Opaque token for a named portal target. */
96
140
  export interface PortalOutlet {
@@ -112,3 +156,14 @@ export declare const COMMENT: {
112
156
  };
113
157
  export declare function isElurTemplate(v: unknown): v is ElurTemplate;
114
158
  export declare function isKeyedList(v: unknown): v is KeyedList;
159
+ /** Marca del pack de binding derivado T2 emitido por el compilador. */
160
+ export declare const ELUR_DERIVED: unique symbol;
161
+ export interface ElurDerivedBinding {
162
+ deps: unknown[];
163
+ get: () => unknown;
164
+ }
165
+ /**
166
+ * Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for
167
+ * permite detección cross-module (plugin runtime vs core hydrate/SSR).
168
+ */
169
+ export declare function isDerivedBinding(v: unknown): v is ElurDerivedBinding;
@@ -17,7 +17,11 @@ function a(e) {
17
17
  function o(e) {
18
18
  return typeof e == "object" && !!e && e.__isKeyedList === !0;
19
19
  }
20
+ var s = Symbol.for("elur.derived");
21
+ function c(e) {
22
+ return typeof e == "object" && !!e && e[s] === !0;
23
+ }
20
24
  //#endregion
21
- export { i as COMMENT, t as ELUR_RENDER_PROTOCOL, e as ELUR_TEMPLATE_DESCRIPTOR, a as isElurTemplate, o as isKeyedList, r as ref, n as templateFeatures };
25
+ export { i as COMMENT, t as ELUR_RENDER_PROTOCOL, e as ELUR_TEMPLATE_DESCRIPTOR, c as isDerivedBinding, a as isElurTemplate, o as isKeyedList, r as ref, n as templateFeatures };
22
26
 
23
27
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n"],"mappings":";AA6CA,IAAa,IAA2B,OAAO,IAAI,mCAAmC,EACzE,IAAuB,OAAO,IAAI,+BAA+B,EAUjE,IAAmB,EAE5B,+BAA+B,IAClC;AAsBD,SAAgB,IAA+C;AAC3D,QAAO,EAAE,IAAI,MAAM;;AAoCvB,IAAa,IAAU;CACnB,OAAO;CACP,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,WAAW;CACX,YAAY;CACf;AAMD,SAAgB,EAAe,GAA+B;AAC1D,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,qBAAqB;;AAI5D,SAAgB,EAAY,GAA4B;AACpD,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,kBAAkB"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../src/elur/template/types.ts"],"sourcesContent":["// =============================================================================\n// --- Public types ---\n// =============================================================================\n\nexport type TemplateBindingContext =\n | { type: \"node\" }\n | { type: \"event\"; eventName: string; modifiers: string[]; hadOpenQuote: boolean }\n | { type: \"attr\"; attrName: string; hadOpenQuote: boolean; url?: boolean; executable?: boolean };\n\nexport interface TemplateDescriptor {\n readonly version: 1;\n readonly strings: readonly string[];\n readonly values: readonly unknown[];\n readonly contexts: readonly TemplateBindingContext[];\n /**\n * C.13: hidratación compilada — el codegen emite una función que activa\n * los bindings por posición (access paths) en vez de un scan global de\n * markers. Sólo los boundaries de contenido dinámico (`<!--elur-N-->`)\n * siguen marcados en el HTML; `data-elur-*` no se emiten.\n * `bounds` se pasa cuando el descriptor es anidado dentro de otro\n * binding. Devuelve cleanup.\n */\n readonly hydrate?: (\n root: ParentNode,\n values: readonly unknown[],\n options?: unknown,\n bounds?: { start: Comment; end: Comment } | null,\n ) => (() => void) | void;\n /**\n * C.12 fase 2: renderer SSR especializado — el codegen emite una función\n * generadora que secuencia los chunks con los strings ya cortados\n * (`attr=`/comillas pre-resueltos en build). Toda la semántica\n * (resolución de valores, sanitización, markers, abort) sigue en los\n * helpers `emit.*` del core — el artefacto compilado y el descriptor\n * genérico producen exactamente el mismo HTML.\n */\n readonly ssr?: (\n emit: SsrEmit,\n values: readonly unknown[],\n ) => AsyncGenerator<SsrChunk, void, unknown>;\n}\n\n/** Chunk producido por el renderer SSR especializado (descriptor.ssr). */\nexport interface SsrChunk {\n readonly type: \"markup\" | \"boundary-start\" | \"boundary-end\" | \"error\" | \"done\";\n readonly value: string;\n readonly index: number;\n}\n\n/** Ops que el core expone al renderer SSR especializado. */\nexport interface SsrEmit {\n /** Static markup, ya cortado en build. */\n m(value: string): SsrChunk;\n /** Binding node: boundaries + resolución + renderValueChunks. */\n node(index: number, value: unknown): AsyncGenerator<SsrChunk, void, unknown>;\n /** Binding attr: prefix + `name=\"v\"` serializada + marker opcional. */\n attr(\n prefix: string,\n index: number,\n attrName: string,\n url: boolean,\n executable: boolean,\n value: unknown,\n ): Promise<SsrChunk[]>;\n /** Binding event: marker data-elur-e o prefix recortado. */\n event(index: number, prefix: string, eventName: string): SsrChunk;\n}\n\nexport interface ServerRenderProtocolContext {\n readonly markers: boolean;\n readonly signal?: AbortSignal;\n readonly context?: unknown;\n render(value: unknown, options?: { markers?: boolean }): Promise<string>;\n}\n\n/** Context passed to a custom value's `mountDom` protocol during client-side mount. */\nexport interface DomProtocolContext {\n readonly parent: Node;\n readonly before: Node | null;\n readonly context?: unknown;\n}\n\n/** Context passed to a custom value's `hydrateDom` protocol during hydration. */\nexport interface HydrationProtocolContext {\n readonly parent: Node;\n readonly bounds: { start: Comment; end: Comment } | null;\n readonly context?: unknown;\n /** Remounts a value inside the current bounds (used as fallback). */\n render(value: unknown): unknown;\n}\n\nexport interface ElurRenderProtocol {\n renderServer?(context: ServerRenderProtocolContext): string | Promise<string>;\n mountDom?(context: DomProtocolContext): (() => void) | void;\n hydrateDom?(context: HydrationProtocolContext): (() => void) | void;\n}\n\nexport const ELUR_TEMPLATE_DESCRIPTOR = Symbol.for(\"@elurjs/core/template-descriptor\");\nexport const ELUR_RENDER_PROTOCOL = Symbol.for(\"@elurjs/core/render-protocol\");\n\n/**\n * Runtime feature capabilities, for tooling to detect support without\n * inferring it from version strings.\n *\n * NOTE: Partial attribute interpolation is now handled at compile time by\n * @elurjs/vite-plugin-elur. The core runtime does not support it natively.\n * Use the Vite plugin for partial interpolation support.\n */\nexport const templateFeatures = {\n /** Partial attribute interpolation (`class=\"btn ${size}\"`) is supported. */\n partialAttributeInterpolation: false,\n} as const;\n\nexport interface ElurTemplate {\n readonly __isElurTemplate: true;\n readonly [ELUR_TEMPLATE_DESCRIPTOR]?: TemplateDescriptor;\n readonly [ELUR_RENDER_PROTOCOL]?: ElurRenderProtocol;\n /** Mounts the template into a container element (public / root API). */\n mount(container: Element | string): ElurMountHandle;\n /** @internal Renders before `before` node (or appends to `parent`). Returns cleanup. */\n _render(parent: Node, before: Node | null): () => void;\n}\n\nexport interface ElurMountHandle {\n unmount(): void;\n}\n\n/** Direct reference to a DOM element, assigned on mount and cleared on unmount. */\nexport interface ElurRef<T extends Element = Element> {\n el: T | null;\n}\n\n/** Creates an empty `ElurRef`. Use as `ref` attribute value in templates. */\nexport function ref<T extends Element = Element>(): ElurRef<T> {\n return { el: null };\n}\n\n/** Keyed list result for efficient DOM diffing via `repeat()`. */\nexport interface KeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderFn: (item: T, index: number) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent;\n}\n\nexport interface KEntry {\n start: Comment;\n end: Comment;\n cleanup: () => void;\n /**\n * C.16.4: item que originó la entry — permite detectar\n * \"misma key, objeto nuevo\" y re-montarla in-place. Opcional porque\n * algunos paths (adopción vieja, internals) no lo registran.\n */\n item?: unknown;\n}\n\n/** Opaque token for a named portal target. */\nexport interface PortalOutlet {\n readonly __isPortalOutlet: true;\n /** @internal */\n _container: Element | null;\n}\n\n/** Fallback: a static template/component, or a factory receiving the error. */\nexport type ErrorFallback =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | ((err: unknown) => ElurTemplate | import(\"../lifecycle.js\").ElurComponent);\n\n/** Content that can be wrapped with `transition()`. */\nexport type TransitionContent =\n | ElurTemplate\n | import(\"../lifecycle.js\").ElurComponent\n | (() => ElurTemplate | import(\"../lifecycle.js\").ElurComponent | null);\n\nexport const COMMENT = {\n SCOPE: \"elur-scope\",\n ERROR_BOUNDARY: \"elur-eb\",\n TRANSITION: \"elur-t\",\n KEYED_START: \"elur-ks\",\n KEYED_END: \"elur-ke\",\n KEYED_ZONE: \"elur-kz\",\n} as const;\n\n// =============================================================================\n// --- DOM inspection helpers ---\n// =============================================================================\n\nexport function isElurTemplate(v: unknown): v is ElurTemplate {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurTemplate === true\n );\n}\n\nexport function isKeyedList(v: unknown): v is KeyedList {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isKeyedList === true\n );\n}\n\n/** Marca del pack de binding derivado T2 emitido por el compilador. */\nexport const ELUR_DERIVED = Symbol.for(\"elur.derived\");\n\nexport interface ElurDerivedBinding {\n deps: unknown[];\n get: () => unknown;\n}\n\n/**\n * Detecta el pack `__elurDerive(dep…, getter)` del compilador. Symbol.for\n * permite detección cross-module (plugin runtime vs core hydrate/SSR).\n */\nexport function isDerivedBinding(v: unknown): v is ElurDerivedBinding {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<symbol, unknown>)[ELUR_DERIVED] === true\n );\n}\n"],"mappings":";AAiGA,IAAa,IAA2B,OAAO,IAAI,mCAAmC,EACzE,IAAuB,OAAO,IAAI,+BAA+B,EAUjE,IAAmB,EAE5B,+BAA+B,IAClC;AAsBD,SAAgB,IAA+C;AAC3D,QAAO,EAAE,IAAI,MAAM;;AA0CvB,IAAa,IAAU;CACnB,OAAO;CACP,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,WAAW;CACX,YAAY;CACf;AAMD,SAAgB,EAAe,GAA+B;AAC1D,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,qBAAqB;;AAI5D,SAAgB,EAAY,GAA4B;AACpD,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,kBAAkB;;AAKzD,IAAa,IAAe,OAAO,IAAI,eAAe;AAWtD,SAAgB,EAAiB,GAAqC;AAClE,QAEI,OAAO,KAAM,cADb,KAEC,EAA8B,OAAkB"}
package/dist/lib/elur.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./signals.cjs`),t=require(`./elur/template/types.cjs`),n=require(`./lifecycle.cjs`),r=require(`./context.cjs`),i=require(`./elur/template/keyed.cjs`),a=require(`./elur/template/bindings.cjs`),o=require(`./elur/template/html.cjs`),s=require(`./elur/template/raw.cjs`),c=require(`./elur/template/transitions.cjs`),l=require(`./elur/template/portal.cjs`),u=require(`./elur/template/error-boundary.cjs`),d=require(`./elur/router-registry.cjs`),f=require(`./component.cjs`),p=require(`./store.cjs`),m=require(`./plugins.cjs`),h=require(`./router.cjs`),g=require(`./async.cjs`),_=require(`./form.cjs`);exports.ELUR_RENDER_PROTOCOL=t.ELUR_RENDER_PROTOCOL,exports.ELUR_TEMPLATE_DESCRIPTOR=t.ELUR_TEMPLATE_DESCRIPTOR,exports.ElurComponent=n.ElurComponent,exports.Link=h.Link,exports.RouterKey=d.RouterKey,exports.RouterView=h.RouterView,exports.Signal=e.Signal,exports._hasActiveRouter=h._hasActiveRouter,exports.batch=e.batch,exports.bridgePlugin=m.bridgePlugin,exports.computed=e.computed,exports.createErrorBoundary=u.createErrorBoundary,exports.createForm=_.createForm,exports.createInjectionKey=r.createInjectionKey,exports.createPortalOutlet=l.createPortalOutlet,exports.createRouter=h.createRouter,exports.createStore=p.createStore,exports.createValidator=_.createValidator,exports.effect=e.effect,exports.elurField=_.elurField,exports.elurFieldArray=_.elurFieldArray,exports.elurRouter=h.elurRouter,exports.email=_.email,exports.extendValidators=_.extendValidators,exports.guardPlugin=m.guardPlugin,exports.html=o.html,exports.inject=r.inject,exports.injectOutlet=l.injectOutlet,exports.lazy=g.lazy,exports.loggerPlugin=m.loggerPlugin,exports.max=_.max,exports.maxLength=_.maxLength,exports.min=_.min,exports.minLength=_.minLength,exports.mount=f.mount,exports.nextTick=e.nextTick,exports.pattern=_.pattern,exports.persistPlugin=m.persistPlugin,exports.portal=l.portal,exports.portalOutlet=l.portalOutlet,exports.provide=r.provide,exports.provideOutlet=l.provideOutlet,exports.raw=s.raw,exports.ref=t.ref,exports.repeat=i.repeat,exports.required=_.required,exports.showWhen=a.showWhen,exports.signal=e.signal,exports.suspend=g.suspend,exports.templateFeatures=t.templateFeatures,exports.transition=c.transition,exports.untrack=e.untrack,exports.validators=_.validators,exports.watch=e.watch;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./elur/next-2/reactivity.cjs`),t=require(`./elur/template/types.cjs`),n=require(`./lifecycle.cjs`),r=require(`./context.cjs`),i=require(`./elur/template/keyed.cjs`),a=require(`./elur/template/bindings.cjs`),o=require(`./elur/template/html.cjs`),s=require(`./elur/template/raw.cjs`),c=require(`./elur/template/transitions.cjs`),l=require(`./elur/template/portal.cjs`),u=require(`./elur/template/error-boundary.cjs`),d=require(`./elur/router-registry.cjs`),f=require(`./elur/next-2/mount.cjs`),p=require(`./store.cjs`),m=require(`./plugins.cjs`),h=require(`./router.cjs`),g=require(`./async.cjs`),_=require(`./form.cjs`);exports.ELUR_RENDER_PROTOCOL=t.ELUR_RENDER_PROTOCOL,exports.ELUR_TEMPLATE_DESCRIPTOR=t.ELUR_TEMPLATE_DESCRIPTOR,exports.ElurComponent=n.ElurComponent,exports.Link=h.Link,exports.RouterKey=d.RouterKey,exports.RouterView=h.RouterView,exports.Signal=e.Signal,exports._hasActiveRouter=h._hasActiveRouter,exports.batch=e.batch,exports.bridgePlugin=m.bridgePlugin,exports.computed=e.computed,exports.createErrorBoundary=u.createErrorBoundary,exports.createForm=_.createForm,exports.createInjectionKey=r.createInjectionKey,exports.createPortalOutlet=l.createPortalOutlet,exports.createRouter=h.createRouter,exports.createStore=p.createStore,exports.createValidator=_.createValidator,exports.effect=e.effect,exports.elurField=_.elurField,exports.elurFieldArray=_.elurFieldArray,exports.elurRouter=h.elurRouter,exports.email=_.email,exports.extendValidators=_.extendValidators,exports.guardPlugin=m.guardPlugin,exports.html=o.html,exports.inject=r.inject,exports.injectOutlet=l.injectOutlet,exports.lazy=g.lazy,exports.loggerPlugin=m.loggerPlugin,exports.max=_.max,exports.maxLength=_.maxLength,exports.min=_.min,exports.minLength=_.minLength,exports.mount=f.mount,exports.nextTick=e.nextTick,exports.pattern=_.pattern,exports.persistPlugin=m.persistPlugin,exports.portal=l.portal,exports.portalOutlet=l.portalOutlet,exports.provide=r.provide,exports.provideOutlet=l.provideOutlet,exports.raw=s.raw,exports.ref=t.ref,exports.repeat=i.repeat,exports.required=_.required,exports.showWhen=a.showWhen,exports.signal=e.signal,exports.suspend=g.suspend,exports.templateFeatures=t.templateFeatures,exports.transition=c.transition,exports.untrack=e.untrack,exports.validators=_.validators,exports.watch=e.watch;
package/dist/lib/elur.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Signal as e, batch as t, computed as n, effect as r, nextTick as i, signal as a, untrack as o, watch as s } from "./signals.js";
1
+ import { Signal as e, batch as t, computed as n, effect as r, nextTick as i, signal as a, untrack as o, watch as s } from "./elur/next-2/reactivity.js";
2
2
  import { ELUR_RENDER_PROTOCOL as c, ELUR_TEMPLATE_DESCRIPTOR as l, ref as u, templateFeatures as d } from "./elur/template/types.js";
3
3
  import { ElurComponent as f } from "./lifecycle.js";
4
4
  import { createInjectionKey as p, inject as m, provide as h } from "./context.js";
@@ -10,7 +10,7 @@ import { transition as b } from "./elur/template/transitions.js";
10
10
  import { createPortalOutlet as x, injectOutlet as S, portal as C, portalOutlet as w, provideOutlet as T } from "./elur/template/portal.js";
11
11
  import { createErrorBoundary as E } from "./elur/template/error-boundary.js";
12
12
  import { RouterKey as D } from "./elur/router-registry.js";
13
- import { mount as O } from "./component.js";
13
+ import { mount as O } from "./elur/next-2/mount.js";
14
14
  import { createStore as k } from "./store.js";
15
15
  import { bridgePlugin as A, guardPlugin as j, loggerPlugin as M, persistPlugin as N } from "./plugins.js";
16
16
  import { Link as P, RouterView as F, _hasActiveRouter as I, createRouter as L, elurRouter as R } from "./router.js";
package/dist/lib/form.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./signals.cjs`);function t(e=`Required`){return t=>t==null||t===``||Array.isArray(t)&&t.length===0?e:null}function n(e,t){return n=>typeof n==`string`&&n.length<e?t??`Minimum ${e} characters`:null}function r(e,t){return n=>typeof n==`string`&&n.length>e?t??`Maximum ${e} characters`:null}function i(e,t=`Invalid format`){return n=>typeof n==`string`&&!e.test(n)?t:null}function a(e=`Invalid email`){return i(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,e)}function o(e,t){return n=>typeof n==`number`&&n<e?t??`Minimum value is ${e}`:null}function s(e,t){return n=>typeof n==`number`&&n>e?t??`Maximum value is ${e}`:null}function c(e){return e}var l={required:t,minLength:n,maxLength:r,email:a,pattern:i,min:o,max:s};function u(e,t){return{...e,...t}}function d(t,n=[],r=`blur`,i){let a=e.signal(t),o=e.signal(!1),s=e.signal(!1),c=e.signal(null),l=e.signal(!1),u=t,d=!0,f=e.effect(()=>{if(a.value,d){d=!1;return}c.peek()!==null&&(c.value=null)}),p=e.computed(()=>{if(c.value)return c.value;let e=i?.();for(let t of n){let n=t(a.value,e);if(n)return n}return null}),m=e.computed(()=>(r===`input`?s.value||o.value:r===`submit`?l.value:o.value)?p.value:null);function h(e){return e.type===`checkbox`||e.type===`radio`}function g(e){if(!e||!(`value`in e))return t;let n=e,r=n.value;return typeof t==`boolean`?n.checked===!0?!0:h(n)?!1:r===`true`||r===`1`?!0:r===`false`||r===`0`||r===``?!1:t:typeof t==`number`?r===``?NaN:Number(r):r}let _=e=>{a.value=g(e.target),s.value=!0},v=()=>{o.value=!0};function y(){e.batch(()=>{a.value=u,o.value=!1,s.value=!1,c.value=null,l.value=!1})}function b(t,n={}){let{shouldTouch:r=!1,shouldDirty:i=!0,shouldValidate:c=!0}=n;e.batch(()=>{a.value=t,i&&(s.value=!0),r&&(o.value=!0),c&&(l.value=!0)})}function x(e){c.value=e,e&&(o.value=!0)}function S(){o.value=!0,l.value=!0}function C(e){u=e}function w(){f(),m.dispose(),p.dispose()}return{value:a,error:m,rawError:p,touched:o,dirty:s,onInput:_,onBlur:v,reset:y,setValue:b,_setExternalError:x,_forceVisible:S,_setInitialValue:C,_dispose:w}}function f(t,n={},r=`blur`){function i(e){let t={};for(let i in e){let a=n[i]??[];t[i]=d(e[i],a,r)}return t}let a=e.signal(t.map(i)),o=t,s=e.computed(()=>a.value.length);function c(e){a.value=[...a.value,i(e)]}function l(e){let t=a.value;if(!(e<0||e>=t.length)){for(let n in t[e])t[e][n]._dispose();a.value=t.filter((t,n)=>n!==e)}}function u(e,t){let n=[...a.value];if(e<0||e>=n.length||t<0||t>=n.length||e===t)return;let[r]=n.splice(e,1);n.splice(t,0,r),a.value=n}function f(e,t){let n=[...a.value];if(!(e<0||e>=n.length)){for(let t in n[e])n[e][t]._dispose();n[e]=i(t),a.value=n}}function p(e){for(let e of a.value)for(let t in e)e[t]._dispose();a.value=e.map(i)}function m(e){let t=[...a.value];for(let n=0;n<e.length;n++){let r=e[n];if(n>=t.length){t.push(i(r));continue}let a=t[n];for(let[e,t]of Object.entries(r))a[e]&&a[e].setValue(t,{shouldDirty:!1,shouldTouch:!1,shouldValidate:!1})}a.value=t}function h(e){e&&(o=e);for(let e of a.value)for(let t in e)e[t]._dispose();a.value=o.map(i)}function g(){for(let e of a.value)for(let t in e)e[t]._dispose();s.dispose()}return{fields:a,append:c,remove:l,move:u,replace:f,length:s,setValues:p,patchValues:m,reset:h,_dispose:g}}function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e,t=``,n=[]){for(let[r,i]of Object.entries(e)){let e=t?`${t}.${r}`:r;if(p(i)&&Object.keys(i).length>0){m(i,e,n);continue}n.push([e,i])}return n}function h(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e],n=i[t];p(n)||(i[t]={}),i=i[t]}i[r[r.length-1]]=n}function g(t,n={}){let r=n.validateOn??`blur`,i={},a=n.validators;function o(){let e={};for(let t in i)h(e,t,i[t].value.value);return e}for(let[e,n]of m(t))i[e]=d(n,a?.[e]??[],r,o);let s=e.signal(!1),c=e.signal(0),l=e.computed(()=>o()),u=e.computed(()=>{let e={};for(let t in i){let n=i[t].error.value;n&&(e[t]=n)}return e}),f=e.computed(()=>{for(let e in i)if(i[e].rawError.value)return!1;return!0}),p=e.computed(()=>{for(let e in i)if(i[e].error.value)return!1;return!0}),g=e.computed(()=>{for(let e in i)if(i[e].dirty.value)return!0;return!1}),_=e.computed(()=>{for(let e in i)if(i[e].touched.value)return!0;return!1});function v(e){for(let t in e)i[t]?._setExternalError(e[t]??null)}function y(e,t,n={}){let r=i[e];r&&r.setValue(t,n)}function b(t,n={}){let{keepDirty:r=!1,keepTouched:a=!1,keepErrors:o=!0}=n;e.batch(()=>{for(let[e,n]of m(t)){let t=i[e];t&&(t.setValue(n,{shouldDirty:!r,shouldTouch:!1,shouldValidate:!o}),a||(t.touched.value=!1))}})}function x(e){if(e)for(let[t,n]of m(e)){let e=i[t];e&&e._setInitialValue(n)}for(let e in i)i[e].reset();s.value=!1,c.value=0}function S(){l.dispose(),u.dispose(),f.dispose(),p.dispose(),g.dispose(),_.dispose();for(let e in i)i[e]._dispose()}function C(e){return t=>{t.preventDefault(),c.value++;for(let e in i)i[e]._forceVisible();let r=l.value;if(n.validate){let e=n.validate(r);if(e){let t={},n=!1;for(let r in e){let i=e[r],a=Array.isArray(i)?i[0]??null:i??null;a&&(t[r]=a,n=!0)}if(n){v(t);return}}}for(let e in i)if(i[e].rawError.value)return;let a=e(r);a instanceof Promise&&(s.value=!0,a.finally(()=>{s.value=!1}).catch(()=>{}))}}return{fields:i,values:l,errors:u,canSubmit:f,valid:p,dirty:g,touched:_,isSubmitting:s,submitCount:c,handleSubmit:C,reset:x,setValue:y,setValues:b,setErrors:v,dispose:S}}exports.createForm=g,exports.createValidator=c,exports.elurField=d,exports.elurFieldArray=f,exports.email=a,exports.extendValidators=u,exports.max=s,exports.maxLength=r,exports.min=o,exports.minLength=n,exports.pattern=i,exports.required=t,exports.validators=l;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./elur/next-2/reactivity.cjs`);function t(e=`Required`){return t=>t==null||t===``||Array.isArray(t)&&t.length===0?e:null}function n(e,t){return n=>typeof n==`string`&&n.length<e?t??`Minimum ${e} characters`:null}function r(e,t){return n=>typeof n==`string`&&n.length>e?t??`Maximum ${e} characters`:null}function i(e,t=`Invalid format`){return n=>typeof n==`string`&&!e.test(n)?t:null}function a(e=`Invalid email`){return i(/^[^\s@]+@[^\s@]+\.[^\s@]+$/,e)}function o(e,t){return n=>typeof n==`number`&&n<e?t??`Minimum value is ${e}`:null}function s(e,t){return n=>typeof n==`number`&&n>e?t??`Maximum value is ${e}`:null}function c(e){return e}var l={required:t,minLength:n,maxLength:r,email:a,pattern:i,min:o,max:s};function u(e,t){return{...e,...t}}function d(t,n=[],r=`blur`,i){let a=e.signal(t),o=e.signal(!1),s=e.signal(!1),c=e.signal(null),l=e.signal(!1),u=t,d=!0,f=e.effect(()=>{if(a.value,d){d=!1;return}c.peek()!==null&&(c.value=null)}),p=e.computed(()=>{if(c.value)return c.value;let e=i?.();for(let t of n){let n=t(a.value,e);if(n)return n}return null}),m=e.computed(()=>(r===`input`?s.value||o.value:r===`submit`?l.value:o.value)?p.value:null);function h(e){return e.type===`checkbox`||e.type===`radio`}function g(e){if(!e||!(`value`in e))return t;let n=e,r=n.value;return typeof t==`boolean`?n.checked===!0?!0:h(n)?!1:r===`true`||r===`1`?!0:r===`false`||r===`0`||r===``?!1:t:typeof t==`number`?r===``?NaN:Number(r):r}let _=e=>{a.value=g(e.target),s.value=!0},v=()=>{o.value=!0};function y(){e.batch(()=>{a.value=u,o.value=!1,s.value=!1,c.value=null,l.value=!1})}function b(t,n={}){let{shouldTouch:r=!1,shouldDirty:i=!0,shouldValidate:c=!0}=n;e.batch(()=>{a.value=t,i&&(s.value=!0),r&&(o.value=!0),c&&(l.value=!0)})}function x(e){c.value=e,e&&(o.value=!0)}function S(){o.value=!0,l.value=!0}function C(e){u=e}function w(){f(),m.dispose(),p.dispose()}return{value:a,error:m,rawError:p,touched:o,dirty:s,onInput:_,onBlur:v,reset:y,setValue:b,_setExternalError:x,_forceVisible:S,_setInitialValue:C,_dispose:w}}function f(t,n={},r=`blur`){function i(e){let t={};for(let i in e){let a=n[i]??[];t[i]=d(e[i],a,r)}return t}let a=e.signal(t.map(i)),o=t,s=e.computed(()=>a.value.length);function c(e){a.value=[...a.value,i(e)]}function l(e){let t=a.value;if(!(e<0||e>=t.length)){for(let n in t[e])t[e][n]._dispose();a.value=t.filter((t,n)=>n!==e)}}function u(e,t){let n=[...a.value];if(e<0||e>=n.length||t<0||t>=n.length||e===t)return;let[r]=n.splice(e,1);n.splice(t,0,r),a.value=n}function f(e,t){let n=[...a.value];if(!(e<0||e>=n.length)){for(let t in n[e])n[e][t]._dispose();n[e]=i(t),a.value=n}}function p(e){for(let e of a.value)for(let t in e)e[t]._dispose();a.value=e.map(i)}function m(e){let t=[...a.value];for(let n=0;n<e.length;n++){let r=e[n];if(n>=t.length){t.push(i(r));continue}let a=t[n];for(let[e,t]of Object.entries(r))a[e]&&a[e].setValue(t,{shouldDirty:!1,shouldTouch:!1,shouldValidate:!1})}a.value=t}function h(e){e&&(o=e);for(let e of a.value)for(let t in e)e[t]._dispose();a.value=o.map(i)}function g(){for(let e of a.value)for(let t in e)e[t]._dispose();s.dispose()}return{fields:a,append:c,remove:l,move:u,replace:f,length:s,setValues:p,patchValues:m,reset:h,_dispose:g}}function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e,t=``,n=[]){for(let[r,i]of Object.entries(e)){let e=t?`${t}.${r}`:r;if(p(i)&&Object.keys(i).length>0){m(i,e,n);continue}n.push([e,i])}return n}function h(e,t,n){let r=t.split(`.`),i=e;for(let e=0;e<r.length-1;e++){let t=r[e],n=i[t];p(n)||(i[t]={}),i=i[t]}i[r[r.length-1]]=n}function g(t,n={}){let r=n.validateOn??`blur`,i={},a=n.validators;function o(){let e={};for(let t in i)h(e,t,i[t].value.value);return e}for(let[e,n]of m(t))i[e]=d(n,a?.[e]??[],r,o);let s=e.signal(!1),c=e.signal(0),l=e.computed(()=>o()),u=e.computed(()=>{let e={};for(let t in i){let n=i[t].error.value;n&&(e[t]=n)}return e}),f=e.computed(()=>{for(let e in i)if(i[e].rawError.value)return!1;return!0}),p=e.computed(()=>{for(let e in i)if(i[e].error.value)return!1;return!0}),g=e.computed(()=>{for(let e in i)if(i[e].dirty.value)return!0;return!1}),_=e.computed(()=>{for(let e in i)if(i[e].touched.value)return!0;return!1});function v(e){for(let t in e)i[t]?._setExternalError(e[t]??null)}function y(e,t,n={}){let r=i[e];r&&r.setValue(t,n)}function b(t,n={}){let{keepDirty:r=!1,keepTouched:a=!1,keepErrors:o=!0}=n;e.batch(()=>{for(let[e,n]of m(t)){let t=i[e];t&&(t.setValue(n,{shouldDirty:!r,shouldTouch:!1,shouldValidate:!o}),a||(t.touched.value=!1))}})}function x(e){if(e)for(let[t,n]of m(e)){let e=i[t];e&&e._setInitialValue(n)}for(let e in i)i[e].reset();s.value=!1,c.value=0}function S(){l.dispose(),u.dispose(),f.dispose(),p.dispose(),g.dispose(),_.dispose();for(let e in i)i[e]._dispose()}function C(e){return t=>{t.preventDefault(),c.value++;for(let e in i)i[e]._forceVisible();let r=l.value;if(n.validate){let e=n.validate(r);if(e){let t={},n=!1;for(let r in e){let i=e[r],a=Array.isArray(i)?i[0]??null:i??null;a&&(t[r]=a,n=!0)}if(n){v(t);return}}}for(let e in i)if(i[e].rawError.value)return;let a=e(r);a instanceof Promise&&(s.value=!0,a.finally(()=>{s.value=!1}).catch(()=>{}))}}return{fields:i,values:l,errors:u,canSubmit:f,valid:p,dirty:g,touched:_,isSubmitting:s,submitCount:c,handleSubmit:C,reset:x,setValue:y,setValues:b,setErrors:v,dispose:S}}exports.createForm=g,exports.createValidator=c,exports.elurField=d,exports.elurFieldArray=f,exports.email=a,exports.extendValidators=u,exports.max=s,exports.maxLength=r,exports.min=o,exports.minLength=n,exports.pattern=i,exports.required=t,exports.validators=l;
2
2
  //# sourceMappingURL=form.cjs.map
package/dist/lib/form.js CHANGED
@@ -1,4 +1,4 @@
1
- import { batch as e, computed as t, effect as n, signal as r } from "./signals.js";
1
+ import { batch as e, computed as t, effect as n, signal as r } from "./elur/next-2/reactivity.js";
2
2
  //#region src/elur/form.ts
3
3
  function i(e = "Required") {
4
4
  return (t) => t == null || t === "" || Array.isArray(t) && t.length === 0 ? e : null;
@@ -1,2 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./signals.cjs`),t=require(`./elur/template/types.cjs`),n=require(`./lifecycle.cjs`),r=require(`./context.cjs`),i=require(`./elur/template/keyed.cjs`),a=require(`./elur/template/keyed-diff.cjs`),o=require(`./elur/template/sanitize.cjs`),s=require(`./elur/template/bindings.cjs`);function c(e,r,i={}){try{if(n.isElurComponent(e))return l(e,r,i);let a=e[t.ELUR_TEMPLATE_DESCRIPTOR];return a||S(i,-1,`descriptor`,`Template has no hydration descriptor`),{unmount:u(a,r,i)}}catch(t){if(i.mismatch===`throw`)throw t;return i.mismatch!==`remount`&&console.warn(`[elur] Hydration mismatch; remounting root:`,t),r.replaceChildren(),{unmount:n.isElurComponent(e)?e.render()._render(r,null):e._render(r,null)}}}function l(e,n,i){r._pushComponentContext();let a=()=>{};try{try{e.onInit?.()}catch(t){if(e.onError)e.onError(t);else throw t}let r=e.render()[t.ELUR_TEMPLATE_DESCRIPTOR];r||S(i,-1,`descriptor`,`Component template has no hydration descriptor`),a=u(r,n,i)}finally{r._popComponentContext()}let o=e.onMount?.();return{unmount(){e.onUnmount?.(),typeof o==`function`&&o(),a()}}}function u(e,t,n,r){let i=d(t,r),a=[];for(let t=0;t<e.contexts.length;t++){let r=e.contexts[t],o=e.values[t];if(r.type===`event`){let e=i.events.get(t);e||S(n,t,`event`,`Missing event marker ${t}`),e.removeAttribute(`data-elur-e-${t}`),a.push(p(e,r.eventName,r.modifiers,o));continue}if(r.type===`attr`){let e=i.attributes.get(t);e||S(n,t,`attribute`,`Missing attribute marker ${t}`),e.removeAttribute(`data-elur-a-${t}`),a.push(m(e,r.attrName,r.url===!0,o));continue}let s=i.nodes.get(t);s||S(n,t,`node`,`Missing node marker ${t}`);let c=h(s,o,n,i.keyed.get(t),i.arrayItems.get(t));c&&a.push(c)}return()=>{for(let e=a.length-1;e>=0;e--)a[e]()}}function d(e,t){let n=new Map,r=new Map,i=new Map,a=new Map,o=new Map,s=new Map,c=[],l=[],u=[],d=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT),p;for(;p=d.nextNode();){if(t&&!f(p,t))continue;if(p.nodeType===Node.COMMENT_NODE){let e=p,t=/^elur-(\d+)$/.exec(e.data);if(t){let n=Number(t[1]);c.length===0&&r.set(n,e),c.push(n);continue}let i=/^elur-end-(\d+)$/.exec(e.data);if(i){let t=Number(i[1]);if(c.pop()===t&&c.length===0){let i=r.get(t);i&&n.set(t,{start:i,end:e})}continue}let a=/^elur-ki:(.+)$/.exec(e.data);if(a){let t=a[1];l.length===0&&c.length===1?l.push({start:e,serializedKey:t,parentIndex:c[c.length-1]}):l.push({start:e,serializedKey:t,parentIndex:-1});continue}if(e.data===`elur-ke`){let t=l.pop();if(t){if(t.parentIndex>=0){let n=o.get(t.parentIndex)??[];n.push({start:t.start,end:e,serializedKey:t.serializedKey}),o.set(t.parentIndex,n)}}else throw Error(`[elur] Hydration marker mismatch: orphan keyed end marker (elur-ke)`);continue}if(e.data===`elur-ai`){u.length===0&&c.length===1?u.push({start:e,parentIndex:c[c.length-1]}):u.push({start:e,parentIndex:-1});continue}if(e.data===`elur-aiend`){let t=u.pop();if(t&&t.parentIndex>=0){let n=s.get(t.parentIndex)??[];n.push({start:t.start,end:e}),s.set(t.parentIndex,n)}continue}continue}if(c.length>0)continue;let e=p;for(let t of Array.from(e.attributes)){let n=/^data-elur-e-(\d+)$/.exec(t.name);n&&a.set(Number(n[1]),e);let r=/^data-elur-a-(\d+)$/.exec(t.name);r&&i.set(Number(r[1]),e)}}return{nodes:n,attributes:i,events:a,keyed:o,arrayItems:s}}function f(e,t){let n=document.createRange();return n.setStartAfter(t.start),n.setEndBefore(t.end),n.intersectsNode(e)}function p(e,t,n,r){if(typeof r!=`function`)throw TypeError(`Event "${t}" requires a function`);let i=r;if(s.isDelegableEvent(t)&&!n.includes(`capture`)&&!n.includes(`once`)&&document.body.contains(e))return s.activateDelegatedEvent(e,t,n,i);let a={once:n.includes(`once`),capture:n.includes(`capture`),passive:n.includes(`passive`)},o=e=>{n.includes(`prevent`)&&e.preventDefault(),n.includes(`stop`)&&e.stopPropagation(),!(n.includes(`self`)&&e.target!==e.currentTarget)&&i(e)};return e.addEventListener(t,o,a),()=>e.removeEventListener(t,o,a)}function m(t,n,r,i){if(n===`ref`){let e=i;return e.el=t,()=>{e.el=null}}let a=(n===`value`||n===`checked`||n===`selected`)&&n in t,s=!0,c=!1,l=e=>{if(a)if(!s)t[n]=e??``;else{let r=t[n];if(String(r)!==String(e??``)&&!c){c=!0;let e=n===`checked`||n===`selected`?`change`:`input`;queueMicrotask(()=>{c=!1,t.dispatchEvent(new Event(e,{bubbles:!0}))})}}else if(e==null||e===!1)t.removeAttribute(n);else{let i=r?o.sanitizeUrl(String(e)):String(e);t.setAttribute(n,i)}s=!1};return typeof i==`function`?e.effect(()=>l(i())):(l(i),()=>{})}function h(n,i,o,s,c){if(typeof i!=`function`)return g(n,i,o,s,c);let l=!0,u,d=b(n),f=null,p=r._captureContextSnapshot(),m=a.createKeyedMount(p),h=e=>{console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`)},v=e.effect(()=>{let e=i();if(t.isKeyedList(e)){if(l&&!f){let t=_(e,s,o);f={state:t.state,prevOrder:t.prevOrder},u=t.cleanup,a.reconcileKeyedList({zoneStart:n.start,anchor:n.end,state:f.state,prevOrder:f.prevOrder,list:e,mount:m,ctxSnapshot:p,onDuplicateKey:h}),d=null,l=!1;return}f||(u?.(),x(n),f={state:new Map,prevOrder:[]},u=()=>{for(let e of f.state.values())e.cleanup()}),a.reconcileKeyedList({zoneStart:n.start,anchor:n.end,state:f.state,prevOrder:f.prevOrder,list:e,mount:m,ctxSnapshot:p,onDuplicateKey:h}),d=null,l=!1;return}f&&(u?.(),x(n),f=null,u=void 0),typeof e==`string`||typeof e==`number`||typeof e==`bigint`?d?d.nodeValue!==String(e)&&(d.nodeValue=String(e)):(d=document.createTextNode(String(e)),n.end.parentNode.insertBefore(d,n.end)):l?u=g(n,e,o,s,c):(u?.(),x(n),u=y(n,e),d=b(n)),l=!1});return()=>{v(),u?.()}}function g(e,i,o,s,c){if(t.isKeyedList(i)){let t=r._captureContextSnapshot(),n=_(i,s,o);return a.reconcileKeyedList({zoneStart:e.start,anchor:e.end,state:n.state,prevOrder:n.prevOrder,list:i,mount:a.createKeyedMount(t),ctxSnapshot:t,onDuplicateKey:e=>{console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`)}}),n.cleanup}if(Array.isArray(i)){let t=[],n=c!==void 0&&c.length>0;for(let r=0;r<i.length;r++){let a=i[r],s=c?.[r];if(n&&s){let e=g(s,a,o);e&&t.push(e)}else if(n){let n=y(e,a);n&&t.push(n)}else{let n=g(e,a,o);n&&t.push(n)}}return t.length?()=>{for(let e=t.length-1;e>=0;e--)t[e]()}:void 0}if(t.isElurTemplate(i)){let n=i[t.ELUR_TEMPLATE_DESCRIPTOR];return n||S(o,-1,`descriptor`,`Nested template has no hydration descriptor`),u(n,e.start.parentNode,o,e)}if(n.isElurComponent(i)){r._pushComponentContext();let n;try{try{i.onInit?.()}catch(e){if(i.onError)i.onError(e);else throw e}let r=i.render()[t.ELUR_TEMPLATE_DESCRIPTOR];r||S(o,-1,`descriptor`,`Nested component has no hydration descriptor`);let a=u(r,e.start.parentNode,o,e),s=i.onMount?.();n=()=>{i.onUnmount?.(),typeof s==`function`&&s(),a()}}finally{r._popComponentContext()}return n}if(typeof i==`object`&&i){let n=i[t.ELUR_RENDER_PROTOCOL];if(n?.hydrateDom)return n.hydrateDom({parent:e.start.parentNode,bounds:e,context:o.context,render:t=>g(e,t,o)})??void 0}}function _(e,t,n){let r=new Map,a=[];if(!t||t.length===0)return{state:r,prevOrder:a,cleanup:()=>{}};let o=new Map;for(let t=0;t<e.items.length;t++){let n=i.normalizeRepeatKey(e.keyFn(e.items[t],t),t),r=i.serializeRepeatKey(n);o.has(r)&&console.warn(`[elur] repeat(): duplicate client key "${n}" during hydration. Keys must be unique; entries after the first leak.`),o.set(r,t)}for(let s of t){let t=o.get(s.serializedKey);if(t===void 0){v(s);continue}let c=e.items[t],l=i.normalizeRepeatKey(e.keyFn(c,t),t);if(i.serializeRepeatKey(l)!==s.serializedKey&&console.warn(`[elur] repeat(): hydration key mismatch at index ${t} (${i.deserializeRepeatKey(s.serializedKey)} != ${l}). The SSR item is adopted by position.`),r.has(l)){console.warn(`[elur] repeat(): duplicate key "${l}" during hydration; removing duplicate SSR node.`),v(s);continue}let u=e.renderFn(c,t),d=g({start:s.start,end:s.end},u,n);r.set(l,{start:s.start,end:s.end,cleanup:d??(()=>{})}),a.push(l)}return{state:r,prevOrder:a,cleanup:()=>{for(let e of r.values())e.cleanup()}}}function v(e){let t=e.start.nextSibling;for(;t&&t!==e.end;){let e=t.nextSibling;t.parentNode?.removeChild(t),t=e}e.start.parentNode?.removeChild(e.start),e.end.parentNode?.removeChild(e.end)}function y(e,r){if(r==null||r===!1||r===!0)return;if(Array.isArray(r)){let t=[];for(let n of r){let r=y(e,n);r&&t.push(r)}return t.length?()=>{for(let e=t.length-1;e>=0;e--)t[e]()}:void 0}if(t.isElurTemplate(r))return r._render(e.end.parentNode,e.end);if(n.isElurComponent(r))return r.render()._render(e.end.parentNode,e.end);let i=document.createTextNode(String(r));return e.end.parentNode.insertBefore(i,e.end),()=>i.parentNode?.removeChild(i)}function b(e){let t=e.start.nextSibling;for(;t&&t!==e.end;){if(t.nodeType===Node.TEXT_NODE)return t;t=t.nextSibling}return null}function x(e){let t=e.start.nextSibling;for(;t&&t!==e.end;){let e=t.nextSibling;t.parentNode?.removeChild(t),t=e}}function S(e,t,n,r){let i={index:t,kind:n,message:r};e.onMismatch?.(i);let a=Error(`[elur] Hydration marker mismatch: ${r}`);throw Object.assign(a,{mismatch:i}),a}exports.hydrate=c;
2
- //# sourceMappingURL=hydrate.cjs.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./elur/next-2/hydrate.cjs`);exports._hydrateNodeRange=e._hydrateNodeRange,exports.hydrate=e.hydrate;