@elurjs/core 3.5.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 (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -0
  3. package/dist/lib/async.cjs +16 -0
  4. package/dist/lib/async.js +123 -0
  5. package/dist/lib/component.cjs +2 -0
  6. package/dist/lib/component.js +66 -0
  7. package/dist/lib/context.cjs +2 -0
  8. package/dist/lib/context.js +52 -0
  9. package/dist/lib/devtools.cjs +59 -0
  10. package/dist/lib/devtools.js +419 -0
  11. package/dist/lib/elur/async.cjs +16 -0
  12. package/dist/lib/elur/async.cjs.map +1 -0
  13. package/dist/lib/elur/async.d.cts +32 -0
  14. package/dist/lib/elur/async.d.ts +32 -0
  15. package/dist/lib/elur/async.js +123 -0
  16. package/dist/lib/elur/async.js.map +1 -0
  17. package/dist/lib/elur/component.cjs +2 -0
  18. package/dist/lib/elur/component.cjs.map +1 -0
  19. package/dist/lib/elur/component.d.cts +17 -0
  20. package/dist/lib/elur/component.d.ts +17 -0
  21. package/dist/lib/elur/component.js +66 -0
  22. package/dist/lib/elur/component.js.map +1 -0
  23. package/dist/lib/elur/context.cjs +2 -0
  24. package/dist/lib/elur/context.cjs.map +1 -0
  25. package/dist/lib/elur/context.d.cts +29 -0
  26. package/dist/lib/elur/context.d.ts +29 -0
  27. package/dist/lib/elur/context.js +52 -0
  28. package/dist/lib/elur/context.js.map +1 -0
  29. package/dist/lib/elur/devtools.cjs +59 -0
  30. package/dist/lib/elur/devtools.cjs.map +1 -0
  31. package/dist/lib/elur/devtools.d.cts +24 -0
  32. package/dist/lib/elur/devtools.d.ts +24 -0
  33. package/dist/lib/elur/devtools.js +419 -0
  34. package/dist/lib/elur/devtools.js.map +1 -0
  35. package/dist/lib/elur/form.cjs +2 -0
  36. package/dist/lib/elur/form.cjs.map +1 -0
  37. package/dist/lib/elur/form.d.cts +283 -0
  38. package/dist/lib/elur/form.d.ts +283 -0
  39. package/dist/lib/elur/form.js +315 -0
  40. package/dist/lib/elur/form.js.map +1 -0
  41. package/dist/lib/elur/hydrate/index.cjs +2 -0
  42. package/dist/lib/elur/hydrate/index.cjs.map +1 -0
  43. package/dist/lib/elur/hydrate/index.d.cts +13 -0
  44. package/dist/lib/elur/hydrate/index.d.ts +13 -0
  45. package/dist/lib/elur/hydrate/index.js +410 -0
  46. package/dist/lib/elur/hydrate/index.js.map +1 -0
  47. package/dist/lib/elur/index.d.cts +19 -0
  48. package/dist/lib/elur/index.d.ts +19 -0
  49. package/dist/lib/elur/lifecycle.cjs +2 -0
  50. package/dist/lib/elur/lifecycle.cjs.map +1 -0
  51. package/dist/lib/elur/lifecycle.d.cts +45 -0
  52. package/dist/lib/elur/lifecycle.d.ts +45 -0
  53. package/dist/lib/elur/lifecycle.js +39 -0
  54. package/dist/lib/elur/lifecycle.js.map +1 -0
  55. package/dist/lib/elur/plugins.cjs +2 -0
  56. package/dist/lib/elur/plugins.cjs.map +1 -0
  57. package/dist/lib/elur/plugins.d.cts +48 -0
  58. package/dist/lib/elur/plugins.d.ts +48 -0
  59. package/dist/lib/elur/plugins.js +59 -0
  60. package/dist/lib/elur/plugins.js.map +1 -0
  61. package/dist/lib/elur/reactivity.cjs +2 -0
  62. package/dist/lib/elur/reactivity.cjs.map +1 -0
  63. package/dist/lib/elur/reactivity.d.cts +60 -0
  64. package/dist/lib/elur/reactivity.d.ts +60 -0
  65. package/dist/lib/elur/reactivity.js +188 -0
  66. package/dist/lib/elur/reactivity.js.map +1 -0
  67. package/dist/lib/elur/router.cjs +12 -0
  68. package/dist/lib/elur/router.cjs.map +1 -0
  69. package/dist/lib/elur/router.d.cts +137 -0
  70. package/dist/lib/elur/router.d.ts +137 -0
  71. package/dist/lib/elur/router.js +513 -0
  72. package/dist/lib/elur/router.js.map +1 -0
  73. package/dist/lib/elur/server/index.cjs +2 -0
  74. package/dist/lib/elur/server/index.cjs.map +1 -0
  75. package/dist/lib/elur/server/index.d.cts +44 -0
  76. package/dist/lib/elur/server/index.d.ts +44 -0
  77. package/dist/lib/elur/server/index.js +307 -0
  78. package/dist/lib/elur/server/index.js.map +1 -0
  79. package/dist/lib/elur/store.cjs +2 -0
  80. package/dist/lib/elur/store.cjs.map +1 -0
  81. package/dist/lib/elur/store.d.cts +137 -0
  82. package/dist/lib/elur/store.d.ts +137 -0
  83. package/dist/lib/elur/store.js +143 -0
  84. package/dist/lib/elur/store.js.map +1 -0
  85. package/dist/lib/elur/template/bindings.cjs +2 -0
  86. package/dist/lib/elur/template/bindings.cjs.map +1 -0
  87. package/dist/lib/elur/template/bindings.d.cts +40 -0
  88. package/dist/lib/elur/template/bindings.d.ts +40 -0
  89. package/dist/lib/elur/template/bindings.js +214 -0
  90. package/dist/lib/elur/template/bindings.js.map +1 -0
  91. package/dist/lib/elur/template/dom-write.cjs +2 -0
  92. package/dist/lib/elur/template/dom-write.cjs.map +1 -0
  93. package/dist/lib/elur/template/dom-write.d.cts +5 -0
  94. package/dist/lib/elur/template/dom-write.d.ts +5 -0
  95. package/dist/lib/elur/template/dom-write.js +16 -0
  96. package/dist/lib/elur/template/dom-write.js.map +1 -0
  97. package/dist/lib/elur/template/error-boundary.cjs +2 -0
  98. package/dist/lib/elur/template/error-boundary.cjs.map +1 -0
  99. package/dist/lib/elur/template/error-boundary.d.cts +7 -0
  100. package/dist/lib/elur/template/error-boundary.d.ts +7 -0
  101. package/dist/lib/elur/template/error-boundary.js +90 -0
  102. package/dist/lib/elur/template/error-boundary.js.map +1 -0
  103. package/dist/lib/elur/template/html.cjs +2 -0
  104. package/dist/lib/elur/template/html.cjs.map +1 -0
  105. package/dist/lib/elur/template/html.d.cts +8 -0
  106. package/dist/lib/elur/template/html.d.ts +8 -0
  107. package/dist/lib/elur/template/html.js +104 -0
  108. package/dist/lib/elur/template/html.js.map +1 -0
  109. package/dist/lib/elur/template/index.cjs +1 -0
  110. package/dist/lib/elur/template/index.d.cts +15 -0
  111. package/dist/lib/elur/template/index.d.ts +15 -0
  112. package/dist/lib/elur/template/index.js +13 -0
  113. package/dist/lib/elur/template/keyed-diff.cjs +2 -0
  114. package/dist/lib/elur/template/keyed-diff.cjs.map +1 -0
  115. package/dist/lib/elur/template/keyed-diff.d.cts +32 -0
  116. package/dist/lib/elur/template/keyed-diff.d.ts +32 -0
  117. package/dist/lib/elur/template/keyed-diff.js +100 -0
  118. package/dist/lib/elur/template/keyed-diff.js.map +1 -0
  119. package/dist/lib/elur/template/keyed.cjs +2 -0
  120. package/dist/lib/elur/template/keyed.cjs.map +1 -0
  121. package/dist/lib/elur/template/keyed.d.cts +27 -0
  122. package/dist/lib/elur/template/keyed.d.ts +27 -0
  123. package/dist/lib/elur/template/keyed.js +52 -0
  124. package/dist/lib/elur/template/keyed.js.map +1 -0
  125. package/dist/lib/elur/template/mount-helpers.cjs +2 -0
  126. package/dist/lib/elur/template/mount-helpers.cjs.map +1 -0
  127. package/dist/lib/elur/template/mount-helpers.d.cts +29 -0
  128. package/dist/lib/elur/template/mount-helpers.d.ts +29 -0
  129. package/dist/lib/elur/template/mount-helpers.js +132 -0
  130. package/dist/lib/elur/template/mount-helpers.js.map +1 -0
  131. package/dist/lib/elur/template/node-binding.cjs +2 -0
  132. package/dist/lib/elur/template/node-binding.cjs.map +1 -0
  133. package/dist/lib/elur/template/node-binding.d.cts +6 -0
  134. package/dist/lib/elur/template/node-binding.d.ts +6 -0
  135. package/dist/lib/elur/template/node-binding.js +95 -0
  136. package/dist/lib/elur/template/node-binding.js.map +1 -0
  137. package/dist/lib/elur/template/portal.cjs +2 -0
  138. package/dist/lib/elur/template/portal.cjs.map +1 -0
  139. package/dist/lib/elur/template/portal.d.cts +19 -0
  140. package/dist/lib/elur/template/portal.d.ts +19 -0
  141. package/dist/lib/elur/template/portal.js +49 -0
  142. package/dist/lib/elur/template/portal.js.map +1 -0
  143. package/dist/lib/elur/template/raw.cjs +2 -0
  144. package/dist/lib/elur/template/raw.cjs.map +1 -0
  145. package/dist/lib/elur/template/raw.d.cts +9 -0
  146. package/dist/lib/elur/template/raw.d.ts +9 -0
  147. package/dist/lib/elur/template/raw.js +29 -0
  148. package/dist/lib/elur/template/raw.js.map +1 -0
  149. package/dist/lib/elur/template/sanitize.cjs +2 -0
  150. package/dist/lib/elur/template/sanitize.cjs.map +1 -0
  151. package/dist/lib/elur/template/sanitize.d.cts +16 -0
  152. package/dist/lib/elur/template/sanitize.d.ts +16 -0
  153. package/dist/lib/elur/template/sanitize.js +29 -0
  154. package/dist/lib/elur/template/sanitize.js.map +1 -0
  155. package/dist/lib/elur/template/transitions.cjs +2 -0
  156. package/dist/lib/elur/template/transitions.cjs.map +1 -0
  157. package/dist/lib/elur/template/transitions.d.cts +43 -0
  158. package/dist/lib/elur/template/transitions.d.ts +43 -0
  159. package/dist/lib/elur/template/transitions.js +96 -0
  160. package/dist/lib/elur/template/transitions.js.map +1 -0
  161. package/dist/lib/elur/template/types.cjs +2 -0
  162. package/dist/lib/elur/template/types.cjs.map +1 -0
  163. package/dist/lib/elur/template/types.d.cts +114 -0
  164. package/dist/lib/elur/template/types.d.ts +114 -0
  165. package/dist/lib/elur/template/types.js +23 -0
  166. package/dist/lib/elur/template/types.js.map +1 -0
  167. package/dist/lib/elur.cjs +1 -0
  168. package/dist/lib/elur.js +18 -0
  169. package/dist/lib/form.cjs +2 -0
  170. package/dist/lib/form.js +315 -0
  171. package/dist/lib/hydrate.cjs +2 -0
  172. package/dist/lib/hydrate.js +410 -0
  173. package/dist/lib/index.cjs +1 -0
  174. package/dist/lib/index.d.cts +2 -0
  175. package/dist/lib/index.d.ts +2 -0
  176. package/dist/lib/index.js +18 -0
  177. package/dist/lib/lifecycle.cjs +2 -0
  178. package/dist/lib/lifecycle.js +39 -0
  179. package/dist/lib/plugins.cjs +2 -0
  180. package/dist/lib/plugins.js +59 -0
  181. package/dist/lib/router.cjs +12 -0
  182. package/dist/lib/router.js +513 -0
  183. package/dist/lib/server.cjs +2 -0
  184. package/dist/lib/server.js +307 -0
  185. package/dist/lib/signals.cjs +2 -0
  186. package/dist/lib/signals.js +188 -0
  187. package/dist/lib/store.cjs +2 -0
  188. package/dist/lib/store.js +143 -0
  189. package/dist/lib/template.cjs +1 -0
  190. package/dist/lib/template.js +13 -0
  191. package/package.json +216 -0
@@ -0,0 +1,214 @@
1
+ import { effect as e } from "../../signals.js";
2
+ import { queueDOMWrite as t } from "./dom-write.js";
3
+ import { activateNodeBinding as n } from "./node-binding.js";
4
+ import { isExecutableAttrName as r, isUrlAttrName as i, sanitizeUrl as a } from "./sanitize.js";
5
+ //#region src/elur/template/bindings.ts
6
+ function o(e, t) {
7
+ t ? e.style.display === "none" && (e.style.display = "") : e.style.display !== "none" && (e.style.display = "none");
8
+ }
9
+ function s(e) {
10
+ let t = e.lastIndexOf(">"), n = e.lastIndexOf("<");
11
+ if (n <= t) return { type: "node" };
12
+ let a = e.slice(n + 1), o = a.lastIndexOf("=");
13
+ if (o === -1) return { type: "node" };
14
+ let s = a.endsWith("\"") || a.endsWith("'") || a[a.length - 1] === "\"" || a[a.length - 1] === "'", c = o - 1;
15
+ for (; c >= 0 && /\S/.test(a[c]);) c--;
16
+ c++;
17
+ let l = a.slice(c, o);
18
+ if (l[0] === "@") {
19
+ let e = l.slice(1).split(".");
20
+ return {
21
+ type: "event",
22
+ eventName: e[0],
23
+ modifiers: e.slice(1),
24
+ hadOpenQuote: s
25
+ };
26
+ }
27
+ return {
28
+ type: "attr",
29
+ attrName: l,
30
+ hadOpenQuote: s,
31
+ url: i(l),
32
+ executable: r(l)
33
+ };
34
+ }
35
+ var c = {
36
+ enter: "Enter",
37
+ escape: "Escape",
38
+ space: " ",
39
+ tab: "Tab",
40
+ delete: "Delete",
41
+ backspace: "Backspace",
42
+ up: "ArrowUp",
43
+ down: "ArrowDown",
44
+ left: "ArrowLeft",
45
+ right: "ArrowRight"
46
+ }, l = new Set([
47
+ "click",
48
+ "dblclick",
49
+ "mousedown",
50
+ "mouseup",
51
+ "keydown",
52
+ "keyup",
53
+ "input",
54
+ "change",
55
+ "submit"
56
+ ]), u = /* @__PURE__ */ new Set();
57
+ function d(e, t, n) {
58
+ let r = e.target, i = e.stopPropagation, a = !1;
59
+ for (e.stopPropagation = () => {
60
+ a = !0, i.call(e);
61
+ }; r && r !== document;) {
62
+ let i = r[t];
63
+ if (i) {
64
+ let t = r[n];
65
+ if (t) {
66
+ if (t.includes("prevent") && e.preventDefault(), t.includes("stop") && e.stopPropagation(), t.includes("self") && e.target !== r) {
67
+ r = r.parentNode;
68
+ continue;
69
+ }
70
+ if ("key" in e) {
71
+ let n = e, i = !0;
72
+ for (let e of t) {
73
+ let t = c[e];
74
+ if (t !== void 0 && n.key !== t) {
75
+ i = !1;
76
+ break;
77
+ }
78
+ if (!t && e.length === 1 && n.key.toLowerCase() !== e) {
79
+ i = !1;
80
+ break;
81
+ }
82
+ }
83
+ if (!i) {
84
+ r = r.parentNode;
85
+ continue;
86
+ }
87
+ }
88
+ }
89
+ if (i(e), a) break;
90
+ }
91
+ r = r.parentNode;
92
+ }
93
+ e.stopPropagation = i;
94
+ }
95
+ var f = /* @__PURE__ */ new Map();
96
+ function p(e) {
97
+ if (!u.has(e)) {
98
+ let t = `__elur_${e}`, n = `__elur_${e}_mods`, r = (e) => d(e, t, n);
99
+ f.set(e, r), document.addEventListener(e, r), u.add(e);
100
+ }
101
+ }
102
+ function m(e, t, n, r) {
103
+ p(t);
104
+ let i = `__elur_${t}`, a = `__elur_${t}_mods`;
105
+ e[i] = r, n.length > 0 && (e[a] = n);
106
+ }
107
+ function h(e, t, n, r) {
108
+ m(e, t, n, r);
109
+ let i = `__elur_${t}`, a = `__elur_${t}_mods`;
110
+ return () => {
111
+ e[i] = null, e[a] = null;
112
+ };
113
+ }
114
+ function g(e) {
115
+ return l.has(e);
116
+ }
117
+ function _(e, t, n, r) {
118
+ let i = Array(t.length), a = -1;
119
+ for (let e = 0; e < t.length; e++) r[e] && r[e].nodeIndex > a && (a = r[e].nodeIndex);
120
+ let o = Array(a + 1);
121
+ if (o[0] = e, a > 0) {
122
+ let t = document.createTreeWalker(e, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT), n = 1, r;
123
+ for (; n <= a && (r = t.nextNode());) o[n++] = r;
124
+ }
125
+ for (let e = 0; e < t.length; e++) {
126
+ let t = r[e];
127
+ i[e] = t ? o[t.nodeIndex] : null;
128
+ }
129
+ return v(e, t, n, r, i);
130
+ }
131
+ function v(o, s, c, l, u) {
132
+ let d = [], f = [];
133
+ for (let o = 0; o < s.length; o++) {
134
+ let p = s[o], m = c[o], _ = l[o];
135
+ if (!_) continue;
136
+ let v = u[o];
137
+ if (p.type === "event") {
138
+ let e = _.name, t = m, n = p.modifiers;
139
+ if (g(e) && !n.includes("capture") && !n.includes("once")) d.push(h(v, e, n, t));
140
+ else {
141
+ let r = {
142
+ once: n.includes("once"),
143
+ capture: n.includes("capture"),
144
+ passive: n.includes("passive")
145
+ }, i = (e) => {
146
+ n.includes("prevent") && e.preventDefault(), n.includes("stop") && e.stopPropagation(), !(n.includes("self") && e.target !== e.currentTarget) && t(e);
147
+ };
148
+ v.addEventListener(e, i, r), d.push(() => v.removeEventListener(e, i, r));
149
+ }
150
+ continue;
151
+ }
152
+ if (p.type === "attr") {
153
+ let n = _.name, o = v;
154
+ if (n === "ref") {
155
+ m.el = o, d.push(() => {
156
+ m.el = null;
157
+ });
158
+ continue;
159
+ }
160
+ if (n === "show" || n === "hide") {
161
+ let r = o, i = null;
162
+ if (typeof m == "function") {
163
+ let a = !1, o = !1, s = !0, c = e(() => {
164
+ o = !!m();
165
+ let e = () => {
166
+ a = !1;
167
+ let e = n === "show" ? o : !o;
168
+ i === null && (i = r.style.display || ""), r.style.display = e ? i : "none";
169
+ };
170
+ s ? (s = !1, e()) : a || (a = !0, t(e));
171
+ });
172
+ d.push(c);
173
+ } else (n === "show" ? m : !m) || (r.style.display = "none");
174
+ continue;
175
+ }
176
+ (p.executable ?? r(n)) && console.warn(`[elur] Dynamic binding on executable attribute "${n}". Use @event for handlers; avoid binding untrusted values here.`);
177
+ let s = p.url ?? i(n), c = (n === "value" || n === "checked" || n === "selected") && n in o;
178
+ if (typeof m == "function") {
179
+ let r = !1, i, l = !0, u = e(() => {
180
+ i = m();
181
+ let e = () => {
182
+ r = !1;
183
+ let e = i;
184
+ if (c) o[n] = e ?? "";
185
+ else if (e == null || e === !1) o.removeAttribute(n);
186
+ else {
187
+ let t = String(e);
188
+ o.setAttribute(n, s ? a(t) : t);
189
+ }
190
+ };
191
+ l ? (l = !1, e()) : r || (r = !0, t(e));
192
+ });
193
+ d.push(u);
194
+ } else if (c) o[n] = m ?? "";
195
+ else if (m != null && m !== !1) {
196
+ let e = String(m);
197
+ o.setAttribute(n, s ? a(e) : e);
198
+ }
199
+ continue;
200
+ }
201
+ let y = v;
202
+ if (!y) continue;
203
+ let b = document.createTextNode("");
204
+ y.parentNode.replaceChild(b, y), n(b, m, d, f);
205
+ }
206
+ return {
207
+ disposes: d,
208
+ postMountHooks: f
209
+ };
210
+ }
211
+ //#endregion
212
+ export { v as _activateBindingsWithNodes, p as _ensureDelegatedEvent, m as _setDelegatedEvent, _ as activateBindings, h as activateDelegatedEvent, s as detectContext, g as isDelegableEvent, o as showWhen };
213
+
214
+ //# sourceMappingURL=bindings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindings.js","names":[],"sources":["../../../../src/elur/template/bindings.ts"],"sourcesContent":["import { effect } from \"../reactivity.js\";\nimport type { ElurRef, TemplateBindingContext } from \"./types.js\";\nimport { activateNodeBinding } from \"./node-binding.js\";\nimport { queueDOMWrite } from \"./dom-write.js\";\nimport { isUrlAttrName, isExecutableAttrName, sanitizeUrl } from \"./sanitize.js\";\n\n// =============================================================================\n// --- show / hide ---\n// =============================================================================\n\n/** Toggles element visibility via `display: none` without unmounting. */\nexport function showWhen(el: HTMLElement, condition: boolean): void {\n if (!condition) {\n if (el.style.display !== \"none\") el.style.display = \"none\";\n } else {\n if (el.style.display === \"none\") el.style.display = \"\";\n }\n}\n\n// =============================================================================\n// --- Binding context ---\n// =============================================================================\n\nexport type BindingContext = TemplateBindingContext;\n\n/**\n * Determines the binding context (node, event, or attribute) for an interpolated\n * value based on the preceding template string.\n */\nexport function detectContext(prevString: string): BindingContext {\n const lastClose = prevString.lastIndexOf(\">\");\n const lastOpen = prevString.lastIndexOf(\"<\");\n\n if (lastOpen <= lastClose) {\n return { type: \"node\" };\n }\n\n const tagContent = prevString.slice(lastOpen + 1);\n\n const eqIdx = tagContent.lastIndexOf(\"=\");\n if (eqIdx === -1) {\n return { type: \"node\" };\n }\n\n const hadOpenQuote =\n tagContent.endsWith('\"') ||\n tagContent.endsWith(\"'\") ||\n tagContent[tagContent.length - 1] === '\"' ||\n tagContent[tagContent.length - 1] === \"'\";\n\n let startIdx = eqIdx - 1;\n while (startIdx >= 0 && /\\S/.test(tagContent[startIdx])) {\n startIdx--;\n }\n startIdx++;\n\n const fullAttr = tagContent.slice(startIdx, eqIdx);\n\n if (fullAttr[0] === \"@\") {\n const parts = fullAttr.slice(1).split(\".\");\n return {\n type: \"event\",\n eventName: parts[0],\n modifiers: parts.slice(1),\n hadOpenQuote,\n };\n }\n\n return {\n type: \"attr\",\n attrName: fullAttr,\n hadOpenQuote,\n // Precomputed once per template (compile time). Read as a cheap boolean\n // in the render/update hot path.\n url: isUrlAttrName(fullAttr),\n executable: isExecutableAttrName(fullAttr),\n };\n}\n\n// =============================================================================\n// --- Keyboard modifier map ---\n// =============================================================================\n\nconst KEY_MAP: Readonly<Record<string, string>> = {\n enter: \"Enter\",\n escape: \"Escape\",\n space: \" \",\n tab: \"Tab\",\n delete: \"Delete\",\n backspace: \"Backspace\",\n up: \"ArrowUp\",\n down: \"ArrowDown\",\n left: \"ArrowLeft\",\n right: \"ArrowRight\",\n};\n\n// =============================================================================\n// --- Global Event Delegation ---\n// =============================================================================\n\nconst DELEGABLE_EVENTS = new Set([\n \"click\", \"dblclick\", \"mousedown\", \"mouseup\",\n \"keydown\", \"keyup\", \"input\", \"change\", \"submit\"\n]);\nconst _delegatedRegistry = new Set<string>();\n\nfunction _globalEventHandlerCore(e: Event, propName: string, modsName: string): void {\n let target = e.target as Node | null;\n\n const originalStop = e.stopPropagation;\n let stopped = false;\n e.stopPropagation = () => {\n stopped = true;\n originalStop.call(e);\n };\n\n while (target && target !== document) {\n const handler = (target as any)[propName] as EventListener | undefined;\n if (handler) {\n const mods = (target as any)[modsName] as string[] | undefined;\n if (mods) {\n if (mods.includes(\"prevent\")) e.preventDefault();\n if (mods.includes(\"stop\")) e.stopPropagation();\n if (mods.includes(\"self\") && e.target !== target) {\n target = target.parentNode;\n continue;\n }\n if (\"key\" in e) {\n const ke = e as KeyboardEvent;\n let keyMatch = true;\n for (const mod of mods) {\n const mapped = KEY_MAP[mod];\n if (mapped !== undefined && ke.key !== mapped) { keyMatch = false; break; }\n if (!mapped && mod.length === 1 && ke.key.toLowerCase() !== mod) { keyMatch = false; break; }\n }\n if (!keyMatch) {\n target = target.parentNode;\n continue;\n }\n }\n }\n handler(e);\n if (stopped) break;\n }\n target = target.parentNode;\n }\n\n e.stopPropagation = originalStop;\n}\n\n// NOTE: entries are intentionally permanent — delegated listeners on document\n// live for the application lifetime.\nconst _delegatedHandlers = new Map<string, (e: Event) => void>();\n\n/**\n * Activates a delegated event on an element, using the same global registry\n * as mount-time bindings. Used by both `activateBindings` (mount) and the\n * hydrator to ensure consistent event delegation.\n *\n * @returns A dispose function that removes the handler from the element.\n */\nexport function _ensureDelegatedEvent(eventName: string): void {\n if (!_delegatedRegistry.has(eventName)) {\n const propName = `__elur_${eventName}`;\n const modsName = `__elur_${eventName}_mods`;\n const boundHandler = (e: Event) => _globalEventHandlerCore(e, propName, modsName);\n _delegatedHandlers.set(eventName, boundHandler);\n document.addEventListener(eventName, boundHandler);\n _delegatedRegistry.add(eventName);\n }\n}\n\nexport function _setDelegatedEvent(\n el: Element,\n eventName: string,\n modifiers: readonly string[],\n rawHandler: EventListener,\n): void {\n _ensureDelegatedEvent(eventName);\n const nodePropName = `__elur_${eventName}`;\n const nodeModsName = `__elur_${eventName}_mods`;\n (el as any)[nodePropName] = rawHandler;\n if (modifiers.length > 0) (el as any)[nodeModsName] = modifiers;\n}\n\nexport function activateDelegatedEvent(\n el: Element,\n eventName: string,\n modifiers: readonly string[],\n rawHandler: EventListener,\n): () => void {\n _setDelegatedEvent(el, eventName, modifiers, rawHandler);\n const nodePropName = `__elur_${eventName}`;\n const nodeModsName = `__elur_${eventName}_mods`;\n return () => {\n (el as any)[nodePropName] = null;\n (el as any)[nodeModsName] = null;\n };\n}\n\n/** Returns true if an event name is in the delegable set. */\nexport function isDelegableEvent(eventName: string): boolean {\n return DELEGABLE_EVENTS.has(eventName);\n}\n\n// =============================================================================\n// --- Binding activation ---\n// =============================================================================\n\n/** Activates all bindings on the cloned fragment. Returns dispose/postMount. */\nexport function activateBindings(\n fragment: DocumentFragment,\n contexts: BindingContext[],\n values: unknown[],\n pathMap: Array<{ nodeIndex: number; name?: string } | null>,\n): { disposes: Array<() => void>; postMountHooks: Array<() => void> } {\n // PHASE 1: READ — single-pass TreeWalker O(N)\n const resolvedNodes = new Array<Node | null>(contexts.length);\n\n let maxNodeIndex = -1;\n for (let i = 0; i < contexts.length; i++) {\n if (pathMap[i] && pathMap[i]!.nodeIndex > maxNodeIndex) {\n maxNodeIndex = pathMap[i]!.nodeIndex;\n }\n }\n\n const flatNodes = new Array<Node>(maxNodeIndex + 1);\n flatNodes[0] = fragment;\n if (maxNodeIndex > 0) {\n const walker = document.createTreeWalker(fragment, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);\n let fi = 1;\n let currentNode: Node | null;\n while (fi <= maxNodeIndex && (currentNode = walker.nextNode())) {\n flatNodes[fi++] = currentNode;\n }\n }\n\n for (let i = 0; i < contexts.length; i++) {\n const info = pathMap[i];\n resolvedNodes[i] = info ? flatNodes[info.nodeIndex] : null;\n }\n\n // PHASE 2: MUTATE (delegated to _activateBindingsWithNodes)\n return _activateBindingsWithNodes(fragment, contexts, values, pathMap, resolvedNodes);\n}\n\n/**\n * Activates bindings using pre-resolved nodes — skips the TreeWalker phase.\n * Used by the compiler's __elurCompiledTemplate to eliminate the second TreeWalker.\n */\nexport function _activateBindingsWithNodes(\n _fragment: DocumentFragment,\n contexts: BindingContext[],\n values: unknown[],\n pathMap: Array<{ nodeIndex: number; name?: string } | null>,\n resolvedNodes: Array<Node | null>,\n): { disposes: Array<() => void>; postMountHooks: Array<() => void> } {\n const disposes: Array<() => void> = [];\n const postMountHooks: Array<() => void> = [];\n\n for (let i = 0; i < contexts.length; i++) {\n const ctx = contexts[i];\n const value = values[i];\n const info = pathMap[i];\n if (!info) continue;\n\n const el = resolvedNodes[i]!;\n\n // --- Events ---\n if (ctx.type === \"event\") {\n const eventName = info.name!;\n const rawHandler = value as EventListener;\n const mods = ctx.modifiers;\n\n const canDelegate =\n isDelegableEvent(eventName) &&\n !mods.includes(\"capture\") &&\n !mods.includes(\"once\");\n\n if (canDelegate) {\n disposes.push(activateDelegatedEvent(el as Element, eventName, mods, rawHandler));\n } else {\n const listenerOpts: AddEventListenerOptions = {\n once: mods.includes(\"once\"),\n capture: mods.includes(\"capture\"),\n passive: mods.includes(\"passive\")\n };\n const handler = (e: Event) => {\n if (mods.includes(\"prevent\")) e.preventDefault();\n if (mods.includes(\"stop\")) e.stopPropagation();\n if (mods.includes(\"self\") && e.target !== e.currentTarget) return;\n rawHandler(e);\n };\n el.addEventListener(eventName, handler, listenerOpts);\n disposes.push(() => el.removeEventListener(eventName, handler, listenerOpts));\n }\n continue;\n }\n\n // --- Attributes ---\n if (ctx.type === \"attr\") {\n const attrName = info.name!;\n const element = el as Element;\n\n if (attrName === \"ref\") {\n (value as ElurRef<Element>).el = element;\n disposes.push(() => { (value as ElurRef<Element>).el = null; });\n continue;\n }\n\n if (attrName === \"show\" || attrName === \"hide\") {\n const htmlEl = element as HTMLElement;\n let originalDisplay: string | null = null;\n\n if (typeof value === \"function\") {\n let queued = false;\n let pendingVisible = false;\n let isFirstRun = true;\n\n const dispose = effect(() => {\n pendingVisible = Boolean((value as () => unknown)());\n const update = () => {\n queued = false;\n const shouldShow = attrName === \"show\" ? pendingVisible : !pendingVisible;\n if (originalDisplay === null) {\n originalDisplay = htmlEl.style.display || \"\";\n }\n htmlEl.style.display = shouldShow ? originalDisplay : \"none\";\n };\n\n if (isFirstRun) {\n isFirstRun = false;\n update();\n } else if (!queued) {\n queued = true;\n queueDOMWrite(update);\n }\n });\n disposes.push(dispose);\n } else {\n const shouldShow = attrName === \"show\" ? Boolean(value) : !Boolean(value);\n if (!shouldShow) htmlEl.style.display = \"none\";\n }\n continue;\n }\n\n // on*/srcdoc bindings are non-idiomatic in Elur (events use @click) and\n // turn an untrusted value into executable code. Warn the developer but\n // do not block — the attribute name is developer-authored.\n if (ctx.executable ?? isExecutableAttrName(attrName)) {\n console.warn(\n `[elur] Dynamic binding on executable attribute \"${attrName}\". Use @event for handlers; avoid binding untrusted values here.`,\n );\n }\n\n // Precomputed at compile time. Only URL attributes pay the sanitizer;\n // class/style/aria-*/data-*/custom attributes skip it entirely.\n const isUrl = ctx.url ?? isUrlAttrName(attrName);\n\n const isDomProp = (attrName === \"value\" || attrName === \"checked\" || attrName === \"selected\") && attrName in element;\n\n if (typeof value === \"function\") {\n let queued = false;\n let pendingValue: unknown;\n let isFirstRun = true;\n\n const dispose = effect(() => {\n pendingValue = (value as () => unknown)();\n const update = () => {\n queued = false;\n const v = pendingValue;\n if (isDomProp) {\n (element as any)[attrName] = v ?? \"\";\n } else if (v == null || v === false) {\n element.removeAttribute(attrName);\n } else {\n const s = String(v);\n element.setAttribute(attrName, isUrl ? sanitizeUrl(s) : s);\n }\n };\n\n if (isFirstRun) {\n isFirstRun = false;\n update();\n } else if (!queued) {\n queued = true;\n queueDOMWrite(update);\n }\n });\n disposes.push(dispose);\n } else {\n if (isDomProp) {\n (element as any)[attrName] = value ?? \"\";\n } else if (value != null && value !== false) {\n const s = String(value);\n element.setAttribute(attrName, isUrl ? sanitizeUrl(s) : s);\n }\n }\n continue;\n }\n\n // --- Nodes — delegate to node-binding.ts ---\n const originalAnchor = el as Comment;\n if (!originalAnchor) continue;\n\n const anchor = document.createTextNode(\"\");\n originalAnchor.parentNode!.replaceChild(anchor, originalAnchor);\n\n activateNodeBinding(anchor, value, disposes, postMountHooks);\n }\n\n return { disposes, postMountHooks };\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var e=new Set,t=!1;function n(n){e.add(n),t||(t=!0,queueMicrotask(()=>{for(let t of e)try{t()}catch(e){console.error(`[Elur] Error in DOM write task:`,e)}e.clear(),t=!1}))}exports.queueDOMWrite=n;
2
+ //# sourceMappingURL=dom-write.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-write.cjs","names":[],"sources":["../../../../src/elur/template/dom-write.ts"],"sourcesContent":["// =============================================================================\n// --- DOM Write Batching (Microtask Queue) ---\n// =============================================================================\n\nconst _domWriteQueue = new Set<() => void>();\nlet _isDomWriteScheduled = false;\n\n/**\n * Queues a DOM mutation to run in the next microtask.\n * Avoids Layout Thrashing by grouping multiple writes into a single frame.\n */\nexport function queueDOMWrite(task: () => void): void {\n _domWriteQueue.add(task);\n if (!_isDomWriteScheduled) {\n _isDomWriteScheduled = true;\n queueMicrotask(() => {\n for (const t of _domWriteQueue) {\n try {\n t();\n } catch (e) {\n // Evitamos que un error rompa el hilo entero\n console.error(\"[Elur] Error in DOM write task:\", e);\n }\n }\n _domWriteQueue.clear();\n _isDomWriteScheduled = false;\n });\n }\n}\n"],"mappings":"AAIA,IAAM,EAAiB,IAAI,IACvB,EAAuB,GAM3B,SAAgB,EAAc,EAAwB,CAClD,EAAe,IAAI,EAAK,CACnB,IACD,EAAuB,GACvB,mBAAqB,CACjB,IAAK,IAAM,KAAK,EACZ,GAAI,CACA,GAAG,OACE,EAAG,CAER,QAAQ,MAAM,kCAAmC,EAAE,CAG3D,EAAe,OAAO,CACtB,EAAuB,IACzB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Queues a DOM mutation to run in the next microtask.
3
+ * Avoids Layout Thrashing by grouping multiple writes into a single frame.
4
+ */
5
+ export declare function queueDOMWrite(task: () => void): void;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Queues a DOM mutation to run in the next microtask.
3
+ * Avoids Layout Thrashing by grouping multiple writes into a single frame.
4
+ */
5
+ export declare function queueDOMWrite(task: () => void): void;
@@ -0,0 +1,16 @@
1
+ //#region src/elur/template/dom-write.ts
2
+ var e = /* @__PURE__ */ new Set(), t = !1;
3
+ function n(n) {
4
+ e.add(n), t || (t = !0, queueMicrotask(() => {
5
+ for (let t of e) try {
6
+ t();
7
+ } catch (e) {
8
+ console.error("[Elur] Error in DOM write task:", e);
9
+ }
10
+ e.clear(), t = !1;
11
+ }));
12
+ }
13
+ //#endregion
14
+ export { n as queueDOMWrite };
15
+
16
+ //# sourceMappingURL=dom-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-write.js","names":[],"sources":["../../../../src/elur/template/dom-write.ts"],"sourcesContent":["// =============================================================================\n// --- DOM Write Batching (Microtask Queue) ---\n// =============================================================================\n\nconst _domWriteQueue = new Set<() => void>();\nlet _isDomWriteScheduled = false;\n\n/**\n * Queues a DOM mutation to run in the next microtask.\n * Avoids Layout Thrashing by grouping multiple writes into a single frame.\n */\nexport function queueDOMWrite(task: () => void): void {\n _domWriteQueue.add(task);\n if (!_isDomWriteScheduled) {\n _isDomWriteScheduled = true;\n queueMicrotask(() => {\n for (const t of _domWriteQueue) {\n try {\n t();\n } catch (e) {\n // Evitamos que un error rompa el hilo entero\n console.error(\"[Elur] Error in DOM write task:\", e);\n }\n }\n _domWriteQueue.clear();\n _isDomWriteScheduled = false;\n });\n }\n}\n"],"mappings":";AAIA,IAAM,oBAAiB,IAAI,KAAiB,EACxC,IAAuB;AAM3B,SAAgB,EAAc,GAAwB;AAElD,CADA,EAAe,IAAI,EAAK,EACnB,MACD,IAAuB,IACvB,qBAAqB;AACjB,OAAK,IAAM,KAAK,EACZ,KAAI;AACA,MAAG;WACE,GAAG;AAER,WAAQ,MAAM,mCAAmC,EAAE;;AAI3D,EADA,EAAe,OAAO,EACtB,IAAuB;GACzB"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../signals.cjs`),t=require(`./types.cjs`),n=require(`../../lifecycle.cjs`),r=require(`../../context.cjs`),i=require(`./mount-helpers.cjs`);function a(a,o){return{__isElurTemplate:!0,mount(e){let t=typeof e==`string`?document.querySelector(e)??document.body:e;return{unmount:this._render(t,null)}},_render(s,c){let l=document.createComment(t.COMMENT.ERROR_BOUNDARY);s.insertBefore(l,c);let u=null,d=!1,f=!1,p,m=!1,h=t=>{let r=l.parentNode;if(!r)return;let a;try{a=typeof o==`function`&&!n.isElurComponent(o)?o(t):o}catch(e){console.error(`[elur] Error boundary fallback threw while producing the fallback UI:`,e),u=_(r,c);return}e._pushErrorHandler(g);try{u=n.isElurComponent(a)?i._mountComponentSilent(a,r,c):a._render(r,c)}catch(e){console.error(`[elur] Error boundary fallback threw during render:`,e),u?.(),u=_(r,c)}finally{e._popErrorHandler()}},g=e=>{console.error(`[elur] Error boundary fallback threw during a reactive update:`,e),u?.(),u=null;let t=l.parentNode;t&&(u=_(t,c))},_=(e,t)=>{let n=document.createElement(`div`);return n.setAttribute(`data-elur-error-boundary`,`fallback-failed`),n.textContent=`[elur] Error boundary fallback failed to render.`,e.insertBefore(n,t),()=>n.remove()};e._pushErrorHandler(e=>{d||(d=!0,f?(u?.(),u=null,h(e)):(p=e,m=!0))});try{if(n.isElurComponent(a)){r._pushComponentContext();try{try{a.onInit?.()}catch(e){if(a.onError)a.onError(e);else throw e}u=a.render()._render(s,c)}finally{r._popComponentContext()}if(!d)try{let e=a.onMount?.(),t=u;u=()=>{try{a.onUnmount?.()}catch{}if(typeof e==`function`)try{e()}catch{}t?.()}}catch(e){if(a.onError)a.onError(e);else throw e}}else u=a._render(s,c)}catch(e){d=!0,u?.(),u=null,p=e,m=!0}finally{e._popErrorHandler(),f=!0}return m&&(u?.(),u=null,h(p)),()=>{u?.(),l.remove()}}}}exports.createErrorBoundary=a;
2
+ //# sourceMappingURL=error-boundary.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-boundary.cjs","names":[],"sources":["../../../../src/elur/template/error-boundary.ts"],"sourcesContent":["import { _pushErrorHandler, _popErrorHandler } from \"../reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport { _pushComponentContext, _popComponentContext } from \"../context.js\";\nimport type { ElurTemplate, ElurMountHandle, ErrorFallback } from \"./types.js\";\nimport { COMMENT } from \"./types.js\";\nimport { _mountComponentSilent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- Error Boundary ---\n// =============================================================================\n\n/**\n * Wraps `content` in an error boundary. If rendering or a reactive update\n * throws, the boundary tears down the broken subtree and renders `fallback`.\n */\nexport function createErrorBoundary(\n content: ElurTemplate | ElurComponent,\n fallback: ErrorFallback\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 const marker = document.createComment(COMMENT.ERROR_BOUNDARY);\n parent.insertBefore(marker, before);\n\n let activeCleanup: (() => void) | null = null;\n let errored = false;\n let initialRenderDone = false;\n let deferredError: unknown = undefined;\n let hasDeferredError = false;\n\n // Renders the fallback outside the error handler window.\n // Uses marker.parentNode (not captured `parent`) because `parent` may be\n // a stale DocumentFragment that was already flushed to the live DOM.\n const renderFallback = (err: unknown): void => {\n const liveParent = marker.parentNode;\n if (!liveParent) return;\n\n let fb: ElurTemplate | ElurComponent;\n try {\n fb =\n typeof fallback === \"function\" && !isElurComponent(fallback as object)\n ? (fallback as (err: unknown) => ElurTemplate | ElurComponent)(err)\n : (fallback as ElurTemplate | ElurComponent);\n } catch (e) {\n console.error(\"[elur] Error boundary fallback threw while producing the fallback UI:\", e);\n activeCleanup = renderBrokenFallback(liveParent, before);\n return;\n }\n\n // Capture reactive errors from effects created inside the fallback.\n _pushErrorHandler(fallbackReactiveErrorHandler);\n try {\n if (isElurComponent(fb)) {\n activeCleanup = _mountComponentSilent(fb, liveParent, before);\n } else {\n activeCleanup = fb._render(liveParent, before);\n }\n } catch (e) {\n console.error(\"[elur] Error boundary fallback threw during render:\", e);\n activeCleanup?.();\n activeCleanup = renderBrokenFallback(liveParent, before);\n } finally {\n _popErrorHandler();\n }\n };\n\n const fallbackReactiveErrorHandler = (e: unknown): void => {\n console.error(\"[elur] Error boundary fallback threw during a reactive update:\", e);\n activeCleanup?.();\n activeCleanup = null;\n const liveParent = marker.parentNode;\n if (liveParent) {\n activeCleanup = renderBrokenFallback(liveParent, before);\n }\n };\n\n const renderBrokenFallback = (liveParent: Node, before: Node | null): (() => void) => {\n const el = document.createElement(\"div\");\n el.setAttribute(\"data-elur-error-boundary\", \"fallback-failed\");\n el.textContent = \"[elur] Error boundary fallback failed to render.\";\n liveParent.insertBefore(el, before);\n return () => el.remove();\n };\n\n // Called by effects inside `content` when they throw\n const handleReactiveError = (err: unknown): void => {\n if (errored) return;\n errored = true;\n if (initialRenderDone) {\n activeCleanup?.();\n activeCleanup = null;\n renderFallback(err);\n } else {\n deferredError = err;\n hasDeferredError = true;\n }\n };\n\n _pushErrorHandler(handleReactiveError);\n try {\n if (isElurComponent(content)) {\n _pushComponentContext();\n try {\n try { content.onInit?.(); } catch (e) {\n if (content.onError) content.onError(e); else throw e;\n }\n activeCleanup = content.render()._render(parent, before);\n } finally {\n _popComponentContext();\n }\n if (!errored) {\n try {\n const ret = content.onMount?.();\n const prev = activeCleanup;\n activeCleanup = () => {\n try { content.onUnmount?.(); } catch { /* ignore */ }\n if (typeof ret === \"function\") try { ret(); } catch { /* ignore */ }\n prev?.();\n };\n } catch (e) {\n if (content.onError) content.onError(e); else throw e;\n }\n }\n } else {\n activeCleanup = content._render(parent, before);\n }\n } catch (err) {\n errored = true;\n activeCleanup?.();\n activeCleanup = null;\n deferredError = err;\n hasDeferredError = true;\n } finally {\n _popErrorHandler();\n initialRenderDone = true;\n }\n\n if (hasDeferredError) {\n activeCleanup?.();\n activeCleanup = null;\n renderFallback(deferredError);\n }\n\n return () => {\n activeCleanup?.();\n marker.remove();\n };\n },\n };\n}\n"],"mappings":"+JAgBA,SAAgB,EACZ,EACA,EACY,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,EAAc,EAAiC,CACnD,IAAM,EAAS,SAAS,cAAc,EAAA,QAAQ,eAAe,CAC7D,EAAO,aAAa,EAAQ,EAAO,CAEnC,IAAI,EAAqC,KACrC,EAAU,GACV,EAAoB,GACpB,EACA,EAAmB,GAKjB,EAAkB,GAAuB,CAC3C,IAAM,EAAa,EAAO,WAC1B,GAAI,CAAC,EAAY,OAEjB,IAAI,EACJ,GAAI,CACA,EACI,OAAO,GAAa,YAAc,CAAC,EAAA,gBAAgB,EAAmB,CAC/D,EAA4D,EAAI,CAChE,QACN,EAAG,CACR,QAAQ,MAAM,wEAAyE,EAAE,CACzF,EAAgB,EAAqB,EAAY,EAAO,CACxD,OAIJ,EAAA,kBAAkB,EAA6B,CAC/C,GAAI,CACA,AAGI,EAHA,EAAA,gBAAgB,EAAG,CACH,EAAA,sBAAsB,EAAI,EAAY,EAAO,CAE7C,EAAG,QAAQ,EAAY,EAAO,OAE7C,EAAG,CACR,QAAQ,MAAM,sDAAuD,EAAE,CACvE,KAAiB,CACjB,EAAgB,EAAqB,EAAY,EAAO,QAClD,CACN,EAAA,kBAAkB,GAIpB,EAAgC,GAAqB,CACvD,QAAQ,MAAM,iEAAkE,EAAE,CAClF,KAAiB,CACjB,EAAgB,KAChB,IAAM,EAAa,EAAO,WACtB,IACA,EAAgB,EAAqB,EAAY,EAAO,GAI1D,GAAwB,EAAkB,IAAsC,CAClF,IAAM,EAAK,SAAS,cAAc,MAAM,CAIxC,OAHA,EAAG,aAAa,2BAA4B,kBAAkB,CAC9D,EAAG,YAAc,mDACjB,EAAW,aAAa,EAAI,EAAO,KACtB,EAAG,QAAQ,EAiB5B,EAAA,kBAb6B,GAAuB,CAC5C,IACJ,EAAU,GACN,GACA,KAAiB,CACjB,EAAgB,KAChB,EAAe,EAAI,GAEnB,EAAgB,EAChB,EAAmB,MAIW,CACtC,GAAI,CACA,GAAI,EAAA,gBAAgB,EAAQ,CAAE,CAC1B,EAAA,uBAAuB,CACvB,GAAI,CACA,GAAI,CAAE,EAAQ,UAAU,OAAW,EAAG,CAClC,GAAI,EAAQ,QAAS,EAAQ,QAAQ,EAAE,MAAO,MAAM,EAExD,EAAgB,EAAQ,QAAQ,CAAC,QAAQ,EAAQ,EAAO,QAClD,CACN,EAAA,sBAAsB,CAE1B,GAAI,CAAC,EACD,GAAI,CACA,IAAM,EAAM,EAAQ,WAAW,CACzB,EAAO,EACb,MAAsB,CAClB,GAAI,CAAE,EAAQ,aAAa,MAAU,EACrC,GAAI,OAAO,GAAQ,WAAY,GAAI,CAAE,GAAK,MAAU,EACpD,KAAQ,QAEP,EAAG,CACR,GAAI,EAAQ,QAAS,EAAQ,QAAQ,EAAE,MAAO,MAAM,QAI5D,EAAgB,EAAQ,QAAQ,EAAQ,EAAO,OAE9C,EAAK,CACV,EAAU,GACV,KAAiB,CACjB,EAAgB,KAChB,EAAgB,EAChB,EAAmB,UACb,CACN,EAAA,kBAAkB,CAClB,EAAoB,GASxB,OANI,IACA,KAAiB,CACjB,EAAgB,KAChB,EAAe,EAAc,MAGpB,CACT,KAAiB,CACjB,EAAO,QAAQ,GAG1B"}
@@ -0,0 +1,7 @@
1
+ import type { ElurComponent } from "../lifecycle.js";
2
+ import type { ElurTemplate, ErrorFallback } from "./types.js";
3
+ /**
4
+ * Wraps `content` in an error boundary. If rendering or a reactive update
5
+ * throws, the boundary tears down the broken subtree and renders `fallback`.
6
+ */
7
+ export declare function createErrorBoundary(content: ElurTemplate | ElurComponent, fallback: ErrorFallback): ElurTemplate;
@@ -0,0 +1,7 @@
1
+ import type { ElurComponent } from "../lifecycle.js";
2
+ import type { ElurTemplate, ErrorFallback } from "./types.js";
3
+ /**
4
+ * Wraps `content` in an error boundary. If rendering or a reactive update
5
+ * throws, the boundary tears down the broken subtree and renders `fallback`.
6
+ */
7
+ export declare function createErrorBoundary(content: ElurTemplate | ElurComponent, fallback: ErrorFallback): ElurTemplate;
@@ -0,0 +1,90 @@
1
+ import { _popErrorHandler as e, _pushErrorHandler as t } from "../../signals.js";
2
+ import { COMMENT as n } from "./types.js";
3
+ import { isElurComponent as r } from "../../lifecycle.js";
4
+ import { _popComponentContext as i, _pushComponentContext as a } from "../../context.js";
5
+ import { _mountComponentSilent as o } from "./mount-helpers.js";
6
+ //#region src/elur/template/error-boundary.ts
7
+ function s(s, c) {
8
+ return {
9
+ __isElurTemplate: !0,
10
+ mount(e) {
11
+ let t = typeof e == "string" ? document.querySelector(e) ?? document.body : e;
12
+ return { unmount: this._render(t, null) };
13
+ },
14
+ _render(l, u) {
15
+ let d = document.createComment(n.ERROR_BOUNDARY);
16
+ l.insertBefore(d, u);
17
+ let f = null, p = !1, m = !1, h, g = !1, _ = (n) => {
18
+ let i = d.parentNode;
19
+ if (!i) return;
20
+ let a;
21
+ try {
22
+ a = typeof c == "function" && !r(c) ? c(n) : c;
23
+ } catch (e) {
24
+ console.error("[elur] Error boundary fallback threw while producing the fallback UI:", e), f = y(i, u);
25
+ return;
26
+ }
27
+ t(v);
28
+ try {
29
+ f = r(a) ? o(a, i, u) : a._render(i, u);
30
+ } catch (e) {
31
+ console.error("[elur] Error boundary fallback threw during render:", e), f?.(), f = y(i, u);
32
+ } finally {
33
+ e();
34
+ }
35
+ }, v = (e) => {
36
+ console.error("[elur] Error boundary fallback threw during a reactive update:", e), f?.(), f = null;
37
+ let t = d.parentNode;
38
+ t && (f = y(t, u));
39
+ }, y = (e, t) => {
40
+ let n = document.createElement("div");
41
+ return n.setAttribute("data-elur-error-boundary", "fallback-failed"), n.textContent = "[elur] Error boundary fallback failed to render.", e.insertBefore(n, t), () => n.remove();
42
+ };
43
+ t((e) => {
44
+ p || (p = !0, m ? (f?.(), f = null, _(e)) : (h = e, g = !0));
45
+ });
46
+ try {
47
+ if (r(s)) {
48
+ a();
49
+ try {
50
+ try {
51
+ s.onInit?.();
52
+ } catch (e) {
53
+ if (s.onError) s.onError(e);
54
+ else throw e;
55
+ }
56
+ f = s.render()._render(l, u);
57
+ } finally {
58
+ i();
59
+ }
60
+ if (!p) try {
61
+ let e = s.onMount?.(), t = f;
62
+ f = () => {
63
+ try {
64
+ s.onUnmount?.();
65
+ } catch {}
66
+ if (typeof e == "function") try {
67
+ e();
68
+ } catch {}
69
+ t?.();
70
+ };
71
+ } catch (e) {
72
+ if (s.onError) s.onError(e);
73
+ else throw e;
74
+ }
75
+ } else f = s._render(l, u);
76
+ } catch (e) {
77
+ p = !0, f?.(), f = null, h = e, g = !0;
78
+ } finally {
79
+ e(), m = !0;
80
+ }
81
+ return g && (f?.(), f = null, _(h)), () => {
82
+ f?.(), d.remove();
83
+ };
84
+ }
85
+ };
86
+ }
87
+ //#endregion
88
+ export { s as createErrorBoundary };
89
+
90
+ //# sourceMappingURL=error-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-boundary.js","names":[],"sources":["../../../../src/elur/template/error-boundary.ts"],"sourcesContent":["import { _pushErrorHandler, _popErrorHandler } from \"../reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport type { ElurComponent } from \"../lifecycle.js\";\nimport { _pushComponentContext, _popComponentContext } from \"../context.js\";\nimport type { ElurTemplate, ElurMountHandle, ErrorFallback } from \"./types.js\";\nimport { COMMENT } from \"./types.js\";\nimport { _mountComponentSilent } from \"./mount-helpers.js\";\n\n// =============================================================================\n// --- Error Boundary ---\n// =============================================================================\n\n/**\n * Wraps `content` in an error boundary. If rendering or a reactive update\n * throws, the boundary tears down the broken subtree and renders `fallback`.\n */\nexport function createErrorBoundary(\n content: ElurTemplate | ElurComponent,\n fallback: ErrorFallback\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 const marker = document.createComment(COMMENT.ERROR_BOUNDARY);\n parent.insertBefore(marker, before);\n\n let activeCleanup: (() => void) | null = null;\n let errored = false;\n let initialRenderDone = false;\n let deferredError: unknown = undefined;\n let hasDeferredError = false;\n\n // Renders the fallback outside the error handler window.\n // Uses marker.parentNode (not captured `parent`) because `parent` may be\n // a stale DocumentFragment that was already flushed to the live DOM.\n const renderFallback = (err: unknown): void => {\n const liveParent = marker.parentNode;\n if (!liveParent) return;\n\n let fb: ElurTemplate | ElurComponent;\n try {\n fb =\n typeof fallback === \"function\" && !isElurComponent(fallback as object)\n ? (fallback as (err: unknown) => ElurTemplate | ElurComponent)(err)\n : (fallback as ElurTemplate | ElurComponent);\n } catch (e) {\n console.error(\"[elur] Error boundary fallback threw while producing the fallback UI:\", e);\n activeCleanup = renderBrokenFallback(liveParent, before);\n return;\n }\n\n // Capture reactive errors from effects created inside the fallback.\n _pushErrorHandler(fallbackReactiveErrorHandler);\n try {\n if (isElurComponent(fb)) {\n activeCleanup = _mountComponentSilent(fb, liveParent, before);\n } else {\n activeCleanup = fb._render(liveParent, before);\n }\n } catch (e) {\n console.error(\"[elur] Error boundary fallback threw during render:\", e);\n activeCleanup?.();\n activeCleanup = renderBrokenFallback(liveParent, before);\n } finally {\n _popErrorHandler();\n }\n };\n\n const fallbackReactiveErrorHandler = (e: unknown): void => {\n console.error(\"[elur] Error boundary fallback threw during a reactive update:\", e);\n activeCleanup?.();\n activeCleanup = null;\n const liveParent = marker.parentNode;\n if (liveParent) {\n activeCleanup = renderBrokenFallback(liveParent, before);\n }\n };\n\n const renderBrokenFallback = (liveParent: Node, before: Node | null): (() => void) => {\n const el = document.createElement(\"div\");\n el.setAttribute(\"data-elur-error-boundary\", \"fallback-failed\");\n el.textContent = \"[elur] Error boundary fallback failed to render.\";\n liveParent.insertBefore(el, before);\n return () => el.remove();\n };\n\n // Called by effects inside `content` when they throw\n const handleReactiveError = (err: unknown): void => {\n if (errored) return;\n errored = true;\n if (initialRenderDone) {\n activeCleanup?.();\n activeCleanup = null;\n renderFallback(err);\n } else {\n deferredError = err;\n hasDeferredError = true;\n }\n };\n\n _pushErrorHandler(handleReactiveError);\n try {\n if (isElurComponent(content)) {\n _pushComponentContext();\n try {\n try { content.onInit?.(); } catch (e) {\n if (content.onError) content.onError(e); else throw e;\n }\n activeCleanup = content.render()._render(parent, before);\n } finally {\n _popComponentContext();\n }\n if (!errored) {\n try {\n const ret = content.onMount?.();\n const prev = activeCleanup;\n activeCleanup = () => {\n try { content.onUnmount?.(); } catch { /* ignore */ }\n if (typeof ret === \"function\") try { ret(); } catch { /* ignore */ }\n prev?.();\n };\n } catch (e) {\n if (content.onError) content.onError(e); else throw e;\n }\n }\n } else {\n activeCleanup = content._render(parent, before);\n }\n } catch (err) {\n errored = true;\n activeCleanup?.();\n activeCleanup = null;\n deferredError = err;\n hasDeferredError = true;\n } finally {\n _popErrorHandler();\n initialRenderDone = true;\n }\n\n if (hasDeferredError) {\n activeCleanup?.();\n activeCleanup = null;\n renderFallback(deferredError);\n }\n\n return () => {\n activeCleanup?.();\n marker.remove();\n };\n },\n };\n}\n"],"mappings":";;;;;;AAgBA,SAAgB,EACZ,GACA,GACY;AACZ,QAAO;EACH,kBAAkB;EAElB,MAAM,GAA8C;GAChD,IAAM,IACF,OAAO,KAAc,WACd,SAAS,cAAc,EAAU,IAAI,SAAS,OAC/C;AAEV,UAAO,EAAE,SADO,KAAK,QAAQ,GAAI,KAAK,EACX;;EAG/B,QAAQ,GAAc,GAAiC;GACnD,IAAM,IAAS,SAAS,cAAc,EAAQ,eAAe;AAC7D,KAAO,aAAa,GAAQ,EAAO;GAEnC,IAAI,IAAqC,MACrC,IAAU,IACV,IAAoB,IACpB,GACA,IAAmB,IAKjB,KAAkB,MAAuB;IAC3C,IAAM,IAAa,EAAO;AAC1B,QAAI,CAAC,EAAY;IAEjB,IAAI;AACJ,QAAI;AACA,SACI,OAAO,KAAa,cAAc,CAAC,EAAgB,EAAmB,GAC/D,EAA4D,EAAI,GAChE;aACN,GAAG;AAER,KADA,QAAQ,MAAM,yEAAyE,EAAE,EACzF,IAAgB,EAAqB,GAAY,EAAO;AACxD;;AAIJ,MAAkB,EAA6B;AAC/C,QAAI;AACA,KAGI,IAHA,EAAgB,EAAG,GACH,EAAsB,GAAI,GAAY,EAAO,GAE7C,EAAG,QAAQ,GAAY,EAAO;aAE7C,GAAG;AAGR,KAFA,QAAQ,MAAM,uDAAuD,EAAE,EACvE,KAAiB,EACjB,IAAgB,EAAqB,GAAY,EAAO;cAClD;AACN,QAAkB;;MAIpB,KAAgC,MAAqB;AAGvD,IAFA,QAAQ,MAAM,kEAAkE,EAAE,EAClF,KAAiB,EACjB,IAAgB;IAChB,IAAM,IAAa,EAAO;AAC1B,IAAI,MACA,IAAgB,EAAqB,GAAY,EAAO;MAI1D,KAAwB,GAAkB,MAAsC;IAClF,IAAM,IAAK,SAAS,cAAc,MAAM;AAIxC,WAHA,EAAG,aAAa,4BAA4B,kBAAkB,EAC9D,EAAG,cAAc,oDACjB,EAAW,aAAa,GAAI,EAAO,QACtB,EAAG,QAAQ;;AAiB5B,MAb6B,MAAuB;AAC5C,UACJ,IAAU,IACN,KACA,KAAiB,EACjB,IAAgB,MAChB,EAAe,EAAI,KAEnB,IAAgB,GAChB,IAAmB;KAIW;AACtC,OAAI;AACA,QAAI,EAAgB,EAAQ,EAAE;AAC1B,QAAuB;AACvB,SAAI;AACA,UAAI;AAAE,SAAQ,UAAU;eAAW,GAAG;AAClC,WAAI,EAAQ,QAAS,GAAQ,QAAQ,EAAE;WAAO,OAAM;;AAExD,UAAgB,EAAQ,QAAQ,CAAC,QAAQ,GAAQ,EAAO;eAClD;AACN,SAAsB;;AAE1B,SAAI,CAAC,EACD,KAAI;MACA,IAAM,IAAM,EAAQ,WAAW,EACzB,IAAO;AACb,gBAAsB;AAClB,WAAI;AAAE,UAAQ,aAAa;eAAU;AACrC,WAAI,OAAO,KAAQ,WAAY,KAAI;AAAE,WAAK;eAAU;AACpD,YAAQ;;cAEP,GAAG;AACR,UAAI,EAAQ,QAAS,GAAQ,QAAQ,EAAE;UAAO,OAAM;;UAI5D,KAAgB,EAAQ,QAAQ,GAAQ,EAAO;YAE9C,GAAK;AAKV,IAJA,IAAU,IACV,KAAiB,EACjB,IAAgB,MAChB,IAAgB,GAChB,IAAmB;aACb;AAEN,IADA,GAAkB,EAClB,IAAoB;;AASxB,UANI,MACA,KAAiB,EACjB,IAAgB,MAChB,EAAe,EAAc,SAGpB;AAET,IADA,KAAiB,EACjB,EAAO,QAAQ;;;EAG1B"}
@@ -0,0 +1,2 @@
1
+ const e=require(`./types.cjs`),t=require(`./bindings.cjs`);function n(e,t){let n=new Uint8Array(e.length),r=``;for(let i=0;i<e.length;i++){let a=e[i];if(n[i]===1&&(a[0]===`"`||a[0]===`'`)&&(a=a.slice(1)),i<t.length){let e=t[i];if(e.type===`node`)r+=a+`<!--elur-${i}-->`;else if(e.type===`event`){let t=`@${e.modifiers.length?`${e.eventName}.${e.modifiers.join(`.`)}`:e.eventName}=`.length+ +!!e.hadOpenQuote;r+=a.slice(0,-t)+` data-elur-e-${i}="${e.eventName}"`,e.hadOpenQuote&&(n[i+1]=1)}else{let t=`${e.attrName}=`.length+ +!!e.hadOpenQuote;r+=a.slice(0,-t)+` data-elur-a-${i}="${e.attrName}"`,e.hadOpenQuote&&(n[i+1]=1)}}else r+=a}return r}var r=new WeakMap,i=new WeakMap;function a(a,...o){let s=r.get(a);if(!s){let e=[],n=``;for(let r=0;r<a.length-1;r++)n+=a[r],e.push(t.detectContext(n)),n+=`__elur__`;s={contexts:e},r.set(a,s)}let c=s.contexts,l={version:1,strings:a,values:o,contexts:c};function u(){let e=i.get(a);if(e)return e;if(typeof document>`u`)throw Error(`[elur] DOM rendering requires a document. Use elur/server on the server.`);let t=document.createElement(`template`);t.innerHTML=n(a,c);let r=Array(c.length).fill(null),o=t.content,s=document.createTreeWalker(o,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT),l=0,u;for(;u=s.nextNode();)if(l++,u.nodeType===8){let e=u.nodeValue;if(e&&e.startsWith(`elur-`)){let t=parseInt(e.slice(5),10);isNaN(t)||(r[t]={nodeIndex:l})}}else if(u.nodeType===1){let e=u,t=Array.from(e.attributes);for(let n=0;n<t.length;n++){let i=t[n],a=i.name;if(a.startsWith(`data-elur-e-`)){let t=parseInt(a.slice(12),10);isNaN(t)||(r[t]={nodeIndex:l,name:i.value}),e.removeAttribute(a);continue}if(a.startsWith(`data-elur-a-`)){let t=parseInt(a.slice(12),10);isNaN(t)||(r[t]={nodeIndex:l,name:i.value}),e.removeAttribute(a)}}}return e={tpl:t,pathMap:r},i.set(a,e),e}function d(e,n){let{tpl:r,pathMap:i}=u(),a=r.content.cloneNode(!0),{disposes:s,postMountHooks:l}=t.activateBindings(a,c,o,i),d=document.createTextNode(``),f=document.createTextNode(``);return e.insertBefore(d,n),e.insertBefore(a,n),e.insertBefore(f,n),l.forEach(e=>e()),()=>{for(let e=s.length-1;e>=0;e--)s[e]();let e=d.nextSibling;for(;e&&e!==f;){let t=e.nextSibling;e.parentNode?.removeChild(e),e=t}d.parentNode?.removeChild(d),f.parentNode?.removeChild(f)}}return{__isElurTemplate:!0,[e.ELUR_TEMPLATE_DESCRIPTOR]:l,_render:d,mount(e){let t=typeof e==`string`?document.querySelector(e):e;if(!t)throw Error(`[elur] mount: contenedor no encontrado: ${e}`);let n=d(t,null);return{unmount(){n()}}}}}exports.buildHTML=n,exports.html=a;
2
+ //# sourceMappingURL=html.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.cjs","names":[],"sources":["../../../../src/elur/template/html.ts"],"sourcesContent":["import { ELUR_TEMPLATE_DESCRIPTOR, type ElurTemplate, type ElurMountHandle, type TemplateDescriptor } from \"./types.js\";\nimport { detectContext, activateBindings } from \"./bindings.js\";\nimport type { BindingContext } from \"./bindings.js\";\n\n// =============================================================================\n// --- Static HTML construction with markers ---\n// =============================================================================\n\n/**\n * Builds the static HTML string, replacing each interpolated value with\n * a comment marker (node), data-elur-e-N (event), or data-elur-a-N (attribute).\n */\nexport function buildHTML(\n strings: readonly string[],\n contexts: BindingContext[]\n): string {\n const skipLeading = new Uint8Array(strings.length);\n let result = \"\";\n\n for (let i = 0; i < strings.length; i++) {\n let s = strings[i];\n\n if (skipLeading[i] === 1 && (s[0] === '\"' || s[0] === \"'\")) {\n s = s.slice(1);\n }\n\n if (i < contexts.length) {\n const ctx = contexts[i];\n\n if (ctx.type === \"node\") {\n result += s + `<!--elur-${i}-->`;\n } else if (ctx.type === \"event\") {\n const full = ctx.modifiers.length\n ? `${ctx.eventName}.${ctx.modifiers.join(\".\")}`\n : ctx.eventName;\n const cut = `@${full}=`.length + (ctx.hadOpenQuote ? 1 : 0);\n result += s.slice(0, -cut) + ` data-elur-e-${i}=\"${ctx.eventName}\"`;\n if (ctx.hadOpenQuote) skipLeading[i + 1] = 1;\n } else {\n const cut =\n `${ctx.attrName}=`.length + (ctx.hadOpenQuote ? 1 : 0);\n result += s.slice(0, -cut) + ` data-elur-a-${i}=\"${ctx.attrName}\"`;\n if (ctx.hadOpenQuote) skipLeading[i + 1] = 1;\n }\n } else {\n result += s;\n }\n }\n\n return result;\n}\n\n// =============================================================================\n// --- Template cache ---\n// =============================================================================\n\ninterface DescriptorCache {\n contexts: BindingContext[];\n}\n\ninterface TemplateCache {\n tpl: HTMLTemplateElement;\n pathMap: Array<{ nodeIndex: number; name?: string } | null>;\n}\n\nconst _descriptorCache = new WeakMap<TemplateStringsArray, DescriptorCache>();\nconst _templateCache = new WeakMap<TemplateStringsArray, TemplateCache>();\n\n// =============================================================================\n// --- html`` tag function ---\n// =============================================================================\n\nexport function html(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): ElurTemplate {\n // NOTE: Partial attribute interpolation (`class=\"btn ${size}\"`) is handled\n // at compile time by @elurjs/vite-plugin-elur. Without the plugin,\n // only full bindings (`class=${value}`) are supported.\n let descriptorCache = _descriptorCache.get(strings);\n if (!descriptorCache) {\n const contexts: BindingContext[] = [];\n let accumulated = \"\";\n for (let i = 0; i < strings.length - 1; i++) {\n accumulated += strings[i];\n contexts.push(detectContext(accumulated));\n accumulated += \"__elur__\";\n }\n descriptorCache = { contexts };\n _descriptorCache.set(strings, descriptorCache);\n }\n\n const contexts = descriptorCache.contexts;\n const descriptor: TemplateDescriptor = { version: 1, strings, values, contexts };\n\n function getTemplateCache(): TemplateCache {\n let cached = _templateCache.get(strings);\n if (cached) return cached;\n if (typeof document === \"undefined\") {\n throw new Error(\"[elur] DOM rendering requires a document. Use elur/server on the server.\");\n }\n\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = buildHTML(strings, contexts);\n const pathMap = new Array<{ nodeIndex: number; name?: string } | null>(contexts.length).fill(null);\n const root = tpl.content;\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);\n let nodeIndex = 0;\n let wNode: Node | null;\n\n while ((wNode = walker.nextNode())) {\n nodeIndex++;\n if (wNode.nodeType === 8) {\n const val = wNode.nodeValue;\n if (val && val.startsWith(\"elur-\")) {\n const idx = parseInt(val.slice(5), 10);\n if (!isNaN(idx)) pathMap[idx] = { nodeIndex };\n }\n } else if (wNode.nodeType === 1) {\n const el = wNode as Element;\n const attrs = Array.from(el.attributes);\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs[i];\n const name = attr.name;\n if (name.startsWith(\"data-elur-e-\")) {\n const idx = parseInt(name.slice(12), 10);\n if (!isNaN(idx)) pathMap[idx] = { nodeIndex, name: attr.value };\n el.removeAttribute(name);\n continue;\n }\n if (name.startsWith(\"data-elur-a-\")) {\n const idx = parseInt(name.slice(12), 10);\n if (!isNaN(idx)) pathMap[idx] = { nodeIndex, name: attr.value };\n el.removeAttribute(name);\n }\n }\n }\n }\n\n cached = { tpl, pathMap };\n _templateCache.set(strings, cached);\n return cached;\n }\n\n function _render(parent: Node, before: Node | null): () => void {\n const { tpl, pathMap } = getTemplateCache();\n const fragment = tpl.content.cloneNode(true) as DocumentFragment;\n\n const { disposes, postMountHooks } = activateBindings(\n fragment, contexts, values, pathMap\n );\n\n const startMarker = document.createTextNode(\"\");\n const endMarker = document.createTextNode(\"\")\n\n parent.insertBefore(startMarker, before);\n parent.insertBefore(fragment, before);\n parent.insertBefore(endMarker, before);\n\n postMountHooks.forEach((cb) => cb());\n\n return () => {\n for (let i = disposes.length - 1; i >= 0; i--) {\n disposes[i]();\n }\n let node = startMarker.nextSibling;\n while (node && node !== endMarker) {\n const next = node.nextSibling;\n node.parentNode?.removeChild(node);\n node = next;\n }\n startMarker.parentNode?.removeChild(startMarker);\n endMarker.parentNode?.removeChild(endMarker);\n };\n }\n\n const elurTemplate: ElurTemplate = {\n __isElurTemplate: true,\n [ELUR_TEMPLATE_DESCRIPTOR]: descriptor,\n\n _render,\n\n mount(container: Element | string): ElurMountHandle {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) as Element)\n : container;\n\n if (!el) {\n throw new Error(`[elur] mount: contenedor no encontrado: ${container}`);\n }\n\n const cleanup = _render(el, null);\n\n return {\n unmount() {\n cleanup();\n },\n };\n },\n };\n\n return elurTemplate;\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type ElurTemplate } from "./types.js";
2
+ import type { BindingContext } from "./bindings.js";
3
+ /**
4
+ * Builds the static HTML string, replacing each interpolated value with
5
+ * a comment marker (node), data-elur-e-N (event), or data-elur-a-N (attribute).
6
+ */
7
+ export declare function buildHTML(strings: readonly string[], contexts: BindingContext[]): string;
8
+ export declare function html(strings: TemplateStringsArray, ...values: unknown[]): ElurTemplate;
@@ -0,0 +1,8 @@
1
+ import { type ElurTemplate } from "./types.js";
2
+ import type { BindingContext } from "./bindings.js";
3
+ /**
4
+ * Builds the static HTML string, replacing each interpolated value with
5
+ * a comment marker (node), data-elur-e-N (event), or data-elur-a-N (attribute).
6
+ */
7
+ export declare function buildHTML(strings: readonly string[], contexts: BindingContext[]): string;
8
+ export declare function html(strings: TemplateStringsArray, ...values: unknown[]): ElurTemplate;
@@ -0,0 +1,104 @@
1
+ import { ELUR_TEMPLATE_DESCRIPTOR as e } from "./types.js";
2
+ import { activateBindings as t, detectContext as n } from "./bindings.js";
3
+ //#region src/elur/template/html.ts
4
+ function r(e, t) {
5
+ let n = new Uint8Array(e.length), r = "";
6
+ for (let i = 0; i < e.length; i++) {
7
+ let a = e[i];
8
+ if (n[i] === 1 && (a[0] === "\"" || a[0] === "'") && (a = a.slice(1)), i < t.length) {
9
+ let e = t[i];
10
+ if (e.type === "node") r += a + `<!--elur-${i}-->`;
11
+ else if (e.type === "event") {
12
+ let t = `@${e.modifiers.length ? `${e.eventName}.${e.modifiers.join(".")}` : e.eventName}=`.length + +!!e.hadOpenQuote;
13
+ r += a.slice(0, -t) + ` data-elur-e-${i}="${e.eventName}"`, e.hadOpenQuote && (n[i + 1] = 1);
14
+ } else {
15
+ let t = `${e.attrName}=`.length + +!!e.hadOpenQuote;
16
+ r += a.slice(0, -t) + ` data-elur-a-${i}="${e.attrName}"`, e.hadOpenQuote && (n[i + 1] = 1);
17
+ }
18
+ } else r += a;
19
+ }
20
+ return r;
21
+ }
22
+ var i = /* @__PURE__ */ new WeakMap(), a = /* @__PURE__ */ new WeakMap();
23
+ function o(o, ...s) {
24
+ let c = i.get(o);
25
+ if (!c) {
26
+ let e = [], t = "";
27
+ for (let r = 0; r < o.length - 1; r++) t += o[r], e.push(n(t)), t += "__elur__";
28
+ c = { contexts: e }, i.set(o, c);
29
+ }
30
+ let l = c.contexts, u = {
31
+ version: 1,
32
+ strings: o,
33
+ values: s,
34
+ contexts: l
35
+ };
36
+ function d() {
37
+ let e = a.get(o);
38
+ if (e) return e;
39
+ if (typeof document > "u") throw Error("[elur] DOM rendering requires a document. Use elur/server on the server.");
40
+ let t = document.createElement("template");
41
+ t.innerHTML = r(o, l);
42
+ let n = Array(l.length).fill(null), i = t.content, s = document.createTreeWalker(i, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT), c = 0, u;
43
+ for (; u = s.nextNode();) if (c++, u.nodeType === 8) {
44
+ let e = u.nodeValue;
45
+ if (e && e.startsWith("elur-")) {
46
+ let t = parseInt(e.slice(5), 10);
47
+ isNaN(t) || (n[t] = { nodeIndex: c });
48
+ }
49
+ } else if (u.nodeType === 1) {
50
+ let e = u, t = Array.from(e.attributes);
51
+ for (let r = 0; r < t.length; r++) {
52
+ let i = t[r], a = i.name;
53
+ if (a.startsWith("data-elur-e-")) {
54
+ let t = parseInt(a.slice(12), 10);
55
+ isNaN(t) || (n[t] = {
56
+ nodeIndex: c,
57
+ name: i.value
58
+ }), e.removeAttribute(a);
59
+ continue;
60
+ }
61
+ if (a.startsWith("data-elur-a-")) {
62
+ let t = parseInt(a.slice(12), 10);
63
+ isNaN(t) || (n[t] = {
64
+ nodeIndex: c,
65
+ name: i.value
66
+ }), e.removeAttribute(a);
67
+ }
68
+ }
69
+ }
70
+ return e = {
71
+ tpl: t,
72
+ pathMap: n
73
+ }, a.set(o, e), e;
74
+ }
75
+ function f(e, n) {
76
+ let { tpl: r, pathMap: i } = d(), a = r.content.cloneNode(!0), { disposes: o, postMountHooks: c } = t(a, l, s, i), u = document.createTextNode(""), f = document.createTextNode("");
77
+ return e.insertBefore(u, n), e.insertBefore(a, n), e.insertBefore(f, n), c.forEach((e) => e()), () => {
78
+ for (let e = o.length - 1; e >= 0; e--) o[e]();
79
+ let e = u.nextSibling;
80
+ for (; e && e !== f;) {
81
+ let t = e.nextSibling;
82
+ e.parentNode?.removeChild(e), e = t;
83
+ }
84
+ u.parentNode?.removeChild(u), f.parentNode?.removeChild(f);
85
+ };
86
+ }
87
+ return {
88
+ __isElurTemplate: !0,
89
+ [e]: u,
90
+ _render: f,
91
+ mount(e) {
92
+ let t = typeof e == "string" ? document.querySelector(e) : e;
93
+ if (!t) throw Error(`[elur] mount: contenedor no encontrado: ${e}`);
94
+ let n = f(t, null);
95
+ return { unmount() {
96
+ n();
97
+ } };
98
+ }
99
+ };
100
+ }
101
+ //#endregion
102
+ export { r as buildHTML, o as html };
103
+
104
+ //# sourceMappingURL=html.js.map