@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.
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/lib/async.cjs +16 -0
- package/dist/lib/async.js +123 -0
- package/dist/lib/component.cjs +2 -0
- package/dist/lib/component.js +66 -0
- package/dist/lib/context.cjs +2 -0
- package/dist/lib/context.js +52 -0
- package/dist/lib/devtools.cjs +59 -0
- package/dist/lib/devtools.js +419 -0
- package/dist/lib/elur/async.cjs +16 -0
- package/dist/lib/elur/async.cjs.map +1 -0
- package/dist/lib/elur/async.d.cts +32 -0
- package/dist/lib/elur/async.d.ts +32 -0
- package/dist/lib/elur/async.js +123 -0
- package/dist/lib/elur/async.js.map +1 -0
- package/dist/lib/elur/component.cjs +2 -0
- package/dist/lib/elur/component.cjs.map +1 -0
- package/dist/lib/elur/component.d.cts +17 -0
- package/dist/lib/elur/component.d.ts +17 -0
- package/dist/lib/elur/component.js +66 -0
- package/dist/lib/elur/component.js.map +1 -0
- package/dist/lib/elur/context.cjs +2 -0
- package/dist/lib/elur/context.cjs.map +1 -0
- package/dist/lib/elur/context.d.cts +29 -0
- package/dist/lib/elur/context.d.ts +29 -0
- package/dist/lib/elur/context.js +52 -0
- package/dist/lib/elur/context.js.map +1 -0
- package/dist/lib/elur/devtools.cjs +59 -0
- package/dist/lib/elur/devtools.cjs.map +1 -0
- package/dist/lib/elur/devtools.d.cts +24 -0
- package/dist/lib/elur/devtools.d.ts +24 -0
- package/dist/lib/elur/devtools.js +419 -0
- package/dist/lib/elur/devtools.js.map +1 -0
- package/dist/lib/elur/form.cjs +2 -0
- package/dist/lib/elur/form.cjs.map +1 -0
- package/dist/lib/elur/form.d.cts +283 -0
- package/dist/lib/elur/form.d.ts +283 -0
- package/dist/lib/elur/form.js +315 -0
- package/dist/lib/elur/form.js.map +1 -0
- package/dist/lib/elur/hydrate/index.cjs +2 -0
- package/dist/lib/elur/hydrate/index.cjs.map +1 -0
- package/dist/lib/elur/hydrate/index.d.cts +13 -0
- package/dist/lib/elur/hydrate/index.d.ts +13 -0
- package/dist/lib/elur/hydrate/index.js +410 -0
- package/dist/lib/elur/hydrate/index.js.map +1 -0
- package/dist/lib/elur/index.d.cts +19 -0
- package/dist/lib/elur/index.d.ts +19 -0
- package/dist/lib/elur/lifecycle.cjs +2 -0
- package/dist/lib/elur/lifecycle.cjs.map +1 -0
- package/dist/lib/elur/lifecycle.d.cts +45 -0
- package/dist/lib/elur/lifecycle.d.ts +45 -0
- package/dist/lib/elur/lifecycle.js +39 -0
- package/dist/lib/elur/lifecycle.js.map +1 -0
- package/dist/lib/elur/plugins.cjs +2 -0
- package/dist/lib/elur/plugins.cjs.map +1 -0
- package/dist/lib/elur/plugins.d.cts +48 -0
- package/dist/lib/elur/plugins.d.ts +48 -0
- package/dist/lib/elur/plugins.js +59 -0
- package/dist/lib/elur/plugins.js.map +1 -0
- package/dist/lib/elur/reactivity.cjs +2 -0
- package/dist/lib/elur/reactivity.cjs.map +1 -0
- package/dist/lib/elur/reactivity.d.cts +60 -0
- package/dist/lib/elur/reactivity.d.ts +60 -0
- package/dist/lib/elur/reactivity.js +188 -0
- package/dist/lib/elur/reactivity.js.map +1 -0
- package/dist/lib/elur/router.cjs +12 -0
- package/dist/lib/elur/router.cjs.map +1 -0
- package/dist/lib/elur/router.d.cts +137 -0
- package/dist/lib/elur/router.d.ts +137 -0
- package/dist/lib/elur/router.js +513 -0
- package/dist/lib/elur/router.js.map +1 -0
- package/dist/lib/elur/server/index.cjs +2 -0
- package/dist/lib/elur/server/index.cjs.map +1 -0
- package/dist/lib/elur/server/index.d.cts +44 -0
- package/dist/lib/elur/server/index.d.ts +44 -0
- package/dist/lib/elur/server/index.js +307 -0
- package/dist/lib/elur/server/index.js.map +1 -0
- package/dist/lib/elur/store.cjs +2 -0
- package/dist/lib/elur/store.cjs.map +1 -0
- package/dist/lib/elur/store.d.cts +137 -0
- package/dist/lib/elur/store.d.ts +137 -0
- package/dist/lib/elur/store.js +143 -0
- package/dist/lib/elur/store.js.map +1 -0
- package/dist/lib/elur/template/bindings.cjs +2 -0
- package/dist/lib/elur/template/bindings.cjs.map +1 -0
- package/dist/lib/elur/template/bindings.d.cts +40 -0
- package/dist/lib/elur/template/bindings.d.ts +40 -0
- package/dist/lib/elur/template/bindings.js +214 -0
- package/dist/lib/elur/template/bindings.js.map +1 -0
- package/dist/lib/elur/template/dom-write.cjs +2 -0
- package/dist/lib/elur/template/dom-write.cjs.map +1 -0
- package/dist/lib/elur/template/dom-write.d.cts +5 -0
- package/dist/lib/elur/template/dom-write.d.ts +5 -0
- package/dist/lib/elur/template/dom-write.js +16 -0
- package/dist/lib/elur/template/dom-write.js.map +1 -0
- package/dist/lib/elur/template/error-boundary.cjs +2 -0
- package/dist/lib/elur/template/error-boundary.cjs.map +1 -0
- package/dist/lib/elur/template/error-boundary.d.cts +7 -0
- package/dist/lib/elur/template/error-boundary.d.ts +7 -0
- package/dist/lib/elur/template/error-boundary.js +90 -0
- package/dist/lib/elur/template/error-boundary.js.map +1 -0
- package/dist/lib/elur/template/html.cjs +2 -0
- package/dist/lib/elur/template/html.cjs.map +1 -0
- package/dist/lib/elur/template/html.d.cts +8 -0
- package/dist/lib/elur/template/html.d.ts +8 -0
- package/dist/lib/elur/template/html.js +104 -0
- package/dist/lib/elur/template/html.js.map +1 -0
- package/dist/lib/elur/template/index.cjs +1 -0
- package/dist/lib/elur/template/index.d.cts +15 -0
- package/dist/lib/elur/template/index.d.ts +15 -0
- package/dist/lib/elur/template/index.js +13 -0
- package/dist/lib/elur/template/keyed-diff.cjs +2 -0
- package/dist/lib/elur/template/keyed-diff.cjs.map +1 -0
- package/dist/lib/elur/template/keyed-diff.d.cts +32 -0
- package/dist/lib/elur/template/keyed-diff.d.ts +32 -0
- package/dist/lib/elur/template/keyed-diff.js +100 -0
- package/dist/lib/elur/template/keyed-diff.js.map +1 -0
- package/dist/lib/elur/template/keyed.cjs +2 -0
- package/dist/lib/elur/template/keyed.cjs.map +1 -0
- package/dist/lib/elur/template/keyed.d.cts +27 -0
- package/dist/lib/elur/template/keyed.d.ts +27 -0
- package/dist/lib/elur/template/keyed.js +52 -0
- package/dist/lib/elur/template/keyed.js.map +1 -0
- package/dist/lib/elur/template/mount-helpers.cjs +2 -0
- package/dist/lib/elur/template/mount-helpers.cjs.map +1 -0
- package/dist/lib/elur/template/mount-helpers.d.cts +29 -0
- package/dist/lib/elur/template/mount-helpers.d.ts +29 -0
- package/dist/lib/elur/template/mount-helpers.js +132 -0
- package/dist/lib/elur/template/mount-helpers.js.map +1 -0
- package/dist/lib/elur/template/node-binding.cjs +2 -0
- package/dist/lib/elur/template/node-binding.cjs.map +1 -0
- package/dist/lib/elur/template/node-binding.d.cts +6 -0
- package/dist/lib/elur/template/node-binding.d.ts +6 -0
- package/dist/lib/elur/template/node-binding.js +95 -0
- package/dist/lib/elur/template/node-binding.js.map +1 -0
- package/dist/lib/elur/template/portal.cjs +2 -0
- package/dist/lib/elur/template/portal.cjs.map +1 -0
- package/dist/lib/elur/template/portal.d.cts +19 -0
- package/dist/lib/elur/template/portal.d.ts +19 -0
- package/dist/lib/elur/template/portal.js +49 -0
- package/dist/lib/elur/template/portal.js.map +1 -0
- package/dist/lib/elur/template/raw.cjs +2 -0
- package/dist/lib/elur/template/raw.cjs.map +1 -0
- package/dist/lib/elur/template/raw.d.cts +9 -0
- package/dist/lib/elur/template/raw.d.ts +9 -0
- package/dist/lib/elur/template/raw.js +29 -0
- package/dist/lib/elur/template/raw.js.map +1 -0
- package/dist/lib/elur/template/sanitize.cjs +2 -0
- package/dist/lib/elur/template/sanitize.cjs.map +1 -0
- package/dist/lib/elur/template/sanitize.d.cts +16 -0
- package/dist/lib/elur/template/sanitize.d.ts +16 -0
- package/dist/lib/elur/template/sanitize.js +29 -0
- package/dist/lib/elur/template/sanitize.js.map +1 -0
- package/dist/lib/elur/template/transitions.cjs +2 -0
- package/dist/lib/elur/template/transitions.cjs.map +1 -0
- package/dist/lib/elur/template/transitions.d.cts +43 -0
- package/dist/lib/elur/template/transitions.d.ts +43 -0
- package/dist/lib/elur/template/transitions.js +96 -0
- package/dist/lib/elur/template/transitions.js.map +1 -0
- package/dist/lib/elur/template/types.cjs +2 -0
- package/dist/lib/elur/template/types.cjs.map +1 -0
- package/dist/lib/elur/template/types.d.cts +114 -0
- package/dist/lib/elur/template/types.d.ts +114 -0
- package/dist/lib/elur/template/types.js +23 -0
- package/dist/lib/elur/template/types.js.map +1 -0
- package/dist/lib/elur.cjs +1 -0
- package/dist/lib/elur.js +18 -0
- package/dist/lib/form.cjs +2 -0
- package/dist/lib/form.js +315 -0
- package/dist/lib/hydrate.cjs +2 -0
- package/dist/lib/hydrate.js +410 -0
- package/dist/lib/index.cjs +1 -0
- package/dist/lib/index.d.cts +2 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +18 -0
- package/dist/lib/lifecycle.cjs +2 -0
- package/dist/lib/lifecycle.js +39 -0
- package/dist/lib/plugins.cjs +2 -0
- package/dist/lib/plugins.js +59 -0
- package/dist/lib/router.cjs +12 -0
- package/dist/lib/router.js +513 -0
- package/dist/lib/server.cjs +2 -0
- package/dist/lib/server.js +307 -0
- package/dist/lib/signals.cjs +2 -0
- package/dist/lib/signals.js +188 -0
- package/dist/lib/store.cjs +2 -0
- package/dist/lib/store.js +143 -0
- package/dist/lib/template.cjs +1 -0
- package/dist/lib/template.js +13 -0
- package/package.json +216 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import { effect as e } from "./signals.js";
|
|
2
|
+
import { ELUR_RENDER_PROTOCOL as t, ELUR_TEMPLATE_DESCRIPTOR as n, isElurTemplate as r, isKeyedList as i } from "./elur/template/types.js";
|
|
3
|
+
import { isElurComponent as a } from "./lifecycle.js";
|
|
4
|
+
import { _captureContextSnapshot as o, _popComponentContext as s, _pushComponentContext as c } from "./context.js";
|
|
5
|
+
import { deserializeRepeatKey as l, normalizeRepeatKey as u, serializeRepeatKey as d } from "./elur/template/keyed.js";
|
|
6
|
+
import { createKeyedMount as f, reconcileKeyedList as p } from "./elur/template/keyed-diff.js";
|
|
7
|
+
import { sanitizeUrl as m } from "./elur/template/sanitize.js";
|
|
8
|
+
import { activateDelegatedEvent as h, isDelegableEvent as g } from "./elur/template/bindings.js";
|
|
9
|
+
//#region src/elur/hydrate/index.ts
|
|
10
|
+
function _(e, t, r = {}) {
|
|
11
|
+
try {
|
|
12
|
+
if (a(e)) return v(e, t, r);
|
|
13
|
+
let i = e[n];
|
|
14
|
+
return i || j(r, -1, "descriptor", "Template has no hydration descriptor"), { unmount: y(i, t, r) };
|
|
15
|
+
} catch (n) {
|
|
16
|
+
if (r.mismatch === "throw") throw n;
|
|
17
|
+
return r.mismatch !== "remount" && console.warn("[elur] Hydration mismatch; remounting root:", n), t.replaceChildren(), { unmount: a(e) ? e.render()._render(t, null) : e._render(t, null) };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function v(e, t, r) {
|
|
21
|
+
c();
|
|
22
|
+
let i = () => {};
|
|
23
|
+
try {
|
|
24
|
+
try {
|
|
25
|
+
e.onInit?.();
|
|
26
|
+
} catch (t) {
|
|
27
|
+
if (e.onError) e.onError(t);
|
|
28
|
+
else throw t;
|
|
29
|
+
}
|
|
30
|
+
let a = e.render()[n];
|
|
31
|
+
a || j(r, -1, "descriptor", "Component template has no hydration descriptor"), i = y(a, t, r);
|
|
32
|
+
} finally {
|
|
33
|
+
s();
|
|
34
|
+
}
|
|
35
|
+
let a = e.onMount?.();
|
|
36
|
+
return { unmount() {
|
|
37
|
+
e.onUnmount?.(), typeof a == "function" && a(), i();
|
|
38
|
+
} };
|
|
39
|
+
}
|
|
40
|
+
function y(e, t, n, r) {
|
|
41
|
+
let i = b(t, r), a = [];
|
|
42
|
+
for (let t = 0; t < e.contexts.length; t++) {
|
|
43
|
+
let r = e.contexts[t], o = e.values[t];
|
|
44
|
+
if (r.type === "event") {
|
|
45
|
+
let e = i.events.get(t);
|
|
46
|
+
e || j(n, t, "event", `Missing event marker ${t}`), e.removeAttribute(`data-elur-e-${t}`), a.push(S(e, r.eventName, r.modifiers, o));
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (r.type === "attr") {
|
|
50
|
+
let e = i.attributes.get(t);
|
|
51
|
+
e || j(n, t, "attribute", `Missing attribute marker ${t}`), e.removeAttribute(`data-elur-a-${t}`), a.push(C(e, r.attrName, r.url === !0, o));
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
let s = i.nodes.get(t);
|
|
55
|
+
s || j(n, t, "node", `Missing node marker ${t}`);
|
|
56
|
+
let c = w(s, o, n, i.keyed.get(t), i.arrayItems.get(t));
|
|
57
|
+
c && a.push(c);
|
|
58
|
+
}
|
|
59
|
+
return () => {
|
|
60
|
+
for (let e = a.length - 1; e >= 0; e--) a[e]();
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function b(e, t) {
|
|
64
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = [], l = [], u = [], d = document.createTreeWalker(e, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT), f;
|
|
65
|
+
for (; f = d.nextNode();) {
|
|
66
|
+
if (t && !x(f, t)) continue;
|
|
67
|
+
if (f.nodeType === Node.COMMENT_NODE) {
|
|
68
|
+
let e = f, t = /^elur-(\d+)$/.exec(e.data);
|
|
69
|
+
if (t) {
|
|
70
|
+
let n = Number(t[1]);
|
|
71
|
+
c.length === 0 && r.set(n, e), c.push(n);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
let i = /^elur-end-(\d+)$/.exec(e.data);
|
|
75
|
+
if (i) {
|
|
76
|
+
let t = Number(i[1]);
|
|
77
|
+
if (c.pop() === t && c.length === 0) {
|
|
78
|
+
let i = r.get(t);
|
|
79
|
+
i && n.set(t, {
|
|
80
|
+
start: i,
|
|
81
|
+
end: e
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
let a = /^elur-ki:(.+)$/.exec(e.data);
|
|
87
|
+
if (a) {
|
|
88
|
+
let t = a[1];
|
|
89
|
+
l.length === 0 && c.length === 1 ? l.push({
|
|
90
|
+
start: e,
|
|
91
|
+
serializedKey: t,
|
|
92
|
+
parentIndex: c[c.length - 1]
|
|
93
|
+
}) : l.push({
|
|
94
|
+
start: e,
|
|
95
|
+
serializedKey: t,
|
|
96
|
+
parentIndex: -1
|
|
97
|
+
});
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (e.data === "elur-ke") {
|
|
101
|
+
let t = l.pop();
|
|
102
|
+
if (t) {
|
|
103
|
+
if (t.parentIndex >= 0) {
|
|
104
|
+
let n = o.get(t.parentIndex) ?? [];
|
|
105
|
+
n.push({
|
|
106
|
+
start: t.start,
|
|
107
|
+
end: e,
|
|
108
|
+
serializedKey: t.serializedKey
|
|
109
|
+
}), o.set(t.parentIndex, n);
|
|
110
|
+
}
|
|
111
|
+
} else throw Error("[elur] Hydration marker mismatch: orphan keyed end marker (elur-ke)");
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (e.data === "elur-ai") {
|
|
115
|
+
u.length === 0 && c.length === 1 ? u.push({
|
|
116
|
+
start: e,
|
|
117
|
+
parentIndex: c[c.length - 1]
|
|
118
|
+
}) : u.push({
|
|
119
|
+
start: e,
|
|
120
|
+
parentIndex: -1
|
|
121
|
+
});
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (e.data === "elur-aiend") {
|
|
125
|
+
let t = u.pop();
|
|
126
|
+
if (t && t.parentIndex >= 0) {
|
|
127
|
+
let n = s.get(t.parentIndex) ?? [];
|
|
128
|
+
n.push({
|
|
129
|
+
start: t.start,
|
|
130
|
+
end: e
|
|
131
|
+
}), s.set(t.parentIndex, n);
|
|
132
|
+
}
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (c.length > 0) continue;
|
|
138
|
+
let e = f;
|
|
139
|
+
for (let t of Array.from(e.attributes)) {
|
|
140
|
+
let n = /^data-elur-e-(\d+)$/.exec(t.name);
|
|
141
|
+
n && a.set(Number(n[1]), e);
|
|
142
|
+
let r = /^data-elur-a-(\d+)$/.exec(t.name);
|
|
143
|
+
r && i.set(Number(r[1]), e);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
nodes: n,
|
|
148
|
+
attributes: i,
|
|
149
|
+
events: a,
|
|
150
|
+
keyed: o,
|
|
151
|
+
arrayItems: s
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function x(e, t) {
|
|
155
|
+
let n = document.createRange();
|
|
156
|
+
return n.setStartAfter(t.start), n.setEndBefore(t.end), n.intersectsNode(e);
|
|
157
|
+
}
|
|
158
|
+
function S(e, t, n, r) {
|
|
159
|
+
if (typeof r != "function") throw TypeError(`Event "${t}" requires a function`);
|
|
160
|
+
let i = r;
|
|
161
|
+
if (g(t) && !n.includes("capture") && !n.includes("once") && document.body.contains(e)) return h(e, t, n, i);
|
|
162
|
+
let a = {
|
|
163
|
+
once: n.includes("once"),
|
|
164
|
+
capture: n.includes("capture"),
|
|
165
|
+
passive: n.includes("passive")
|
|
166
|
+
}, o = (e) => {
|
|
167
|
+
n.includes("prevent") && e.preventDefault(), n.includes("stop") && e.stopPropagation(), !(n.includes("self") && e.target !== e.currentTarget) && i(e);
|
|
168
|
+
};
|
|
169
|
+
return e.addEventListener(t, o, a), () => e.removeEventListener(t, o, a);
|
|
170
|
+
}
|
|
171
|
+
function C(t, n, r, i) {
|
|
172
|
+
if (n === "ref") {
|
|
173
|
+
let e = i;
|
|
174
|
+
return e.el = t, () => {
|
|
175
|
+
e.el = null;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
let a = (n === "value" || n === "checked" || n === "selected") && n in t, o = !0, s = !1, c = (e) => {
|
|
179
|
+
if (a) if (!o) t[n] = e ?? "";
|
|
180
|
+
else {
|
|
181
|
+
let r = t[n];
|
|
182
|
+
if (String(r) !== String(e ?? "") && !s) {
|
|
183
|
+
s = !0;
|
|
184
|
+
let e = n === "checked" || n === "selected" ? "change" : "input";
|
|
185
|
+
queueMicrotask(() => {
|
|
186
|
+
s = !1, t.dispatchEvent(new Event(e, { bubbles: !0 }));
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (e == null || e === !1) t.removeAttribute(n);
|
|
191
|
+
else {
|
|
192
|
+
let i = r ? m(String(e)) : String(e);
|
|
193
|
+
t.setAttribute(n, i);
|
|
194
|
+
}
|
|
195
|
+
o = !1;
|
|
196
|
+
};
|
|
197
|
+
return typeof i == "function" ? e(() => c(i())) : (c(i), () => {});
|
|
198
|
+
}
|
|
199
|
+
function w(t, n, r, a, s) {
|
|
200
|
+
if (typeof n != "function") return T(t, n, r, a, s);
|
|
201
|
+
let c = !0, l, u = k(t), d = null, m = o(), h = f(m), g = (e) => {
|
|
202
|
+
console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);
|
|
203
|
+
}, _ = e(() => {
|
|
204
|
+
let e = n();
|
|
205
|
+
if (i(e)) {
|
|
206
|
+
if (c && !d) {
|
|
207
|
+
let n = E(e, a, r);
|
|
208
|
+
d = {
|
|
209
|
+
state: n.state,
|
|
210
|
+
prevOrder: n.prevOrder
|
|
211
|
+
}, l = n.cleanup, p({
|
|
212
|
+
zoneStart: t.start,
|
|
213
|
+
anchor: t.end,
|
|
214
|
+
state: d.state,
|
|
215
|
+
prevOrder: d.prevOrder,
|
|
216
|
+
list: e,
|
|
217
|
+
mount: h,
|
|
218
|
+
ctxSnapshot: m,
|
|
219
|
+
onDuplicateKey: g
|
|
220
|
+
}), u = null, c = !1;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
d || (l?.(), A(t), d = {
|
|
224
|
+
state: /* @__PURE__ */ new Map(),
|
|
225
|
+
prevOrder: []
|
|
226
|
+
}, l = () => {
|
|
227
|
+
for (let e of d.state.values()) e.cleanup();
|
|
228
|
+
}), p({
|
|
229
|
+
zoneStart: t.start,
|
|
230
|
+
anchor: t.end,
|
|
231
|
+
state: d.state,
|
|
232
|
+
prevOrder: d.prevOrder,
|
|
233
|
+
list: e,
|
|
234
|
+
mount: h,
|
|
235
|
+
ctxSnapshot: m,
|
|
236
|
+
onDuplicateKey: g
|
|
237
|
+
}), u = null, c = !1;
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
d && (l?.(), A(t), d = null, l = void 0), typeof e == "string" || typeof e == "number" || typeof e == "bigint" ? u ? u.nodeValue !== String(e) && (u.nodeValue = String(e)) : (u = document.createTextNode(String(e)), t.end.parentNode.insertBefore(u, t.end)) : c ? l = T(t, e, r, a, s) : (l?.(), A(t), l = O(t, e), u = k(t)), c = !1;
|
|
241
|
+
});
|
|
242
|
+
return () => {
|
|
243
|
+
_(), l?.();
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function T(e, l, u, d, m) {
|
|
247
|
+
if (i(l)) {
|
|
248
|
+
let t = o(), n = E(l, d, u);
|
|
249
|
+
return p({
|
|
250
|
+
zoneStart: e.start,
|
|
251
|
+
anchor: e.end,
|
|
252
|
+
state: n.state,
|
|
253
|
+
prevOrder: n.prevOrder,
|
|
254
|
+
list: l,
|
|
255
|
+
mount: f(t),
|
|
256
|
+
ctxSnapshot: t,
|
|
257
|
+
onDuplicateKey: (e) => {
|
|
258
|
+
console.warn(`[elur] repeat(): duplicate key "${e}". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);
|
|
259
|
+
}
|
|
260
|
+
}), n.cleanup;
|
|
261
|
+
}
|
|
262
|
+
if (Array.isArray(l)) {
|
|
263
|
+
let t = [], n = m !== void 0 && m.length > 0;
|
|
264
|
+
for (let r = 0; r < l.length; r++) {
|
|
265
|
+
let i = l[r], a = m?.[r];
|
|
266
|
+
if (n && a) {
|
|
267
|
+
let e = T(a, i, u);
|
|
268
|
+
e && t.push(e);
|
|
269
|
+
} else if (n) {
|
|
270
|
+
let n = O(e, i);
|
|
271
|
+
n && t.push(n);
|
|
272
|
+
} else {
|
|
273
|
+
let n = T(e, i, u);
|
|
274
|
+
n && t.push(n);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return t.length ? () => {
|
|
278
|
+
for (let e = t.length - 1; e >= 0; e--) t[e]();
|
|
279
|
+
} : void 0;
|
|
280
|
+
}
|
|
281
|
+
if (r(l)) {
|
|
282
|
+
let t = l[n];
|
|
283
|
+
return t || j(u, -1, "descriptor", "Nested template has no hydration descriptor"), y(t, e.start.parentNode, u, e);
|
|
284
|
+
}
|
|
285
|
+
if (a(l)) {
|
|
286
|
+
c();
|
|
287
|
+
let t;
|
|
288
|
+
try {
|
|
289
|
+
try {
|
|
290
|
+
l.onInit?.();
|
|
291
|
+
} catch (e) {
|
|
292
|
+
if (l.onError) l.onError(e);
|
|
293
|
+
else throw e;
|
|
294
|
+
}
|
|
295
|
+
let r = l.render()[n];
|
|
296
|
+
r || j(u, -1, "descriptor", "Nested component has no hydration descriptor");
|
|
297
|
+
let i = y(r, e.start.parentNode, u, e), a = l.onMount?.();
|
|
298
|
+
t = () => {
|
|
299
|
+
l.onUnmount?.(), typeof a == "function" && a(), i();
|
|
300
|
+
};
|
|
301
|
+
} finally {
|
|
302
|
+
s();
|
|
303
|
+
}
|
|
304
|
+
return t;
|
|
305
|
+
}
|
|
306
|
+
if (typeof l == "object" && l) {
|
|
307
|
+
let n = l[t];
|
|
308
|
+
if (n?.hydrateDom) return n.hydrateDom({
|
|
309
|
+
parent: e.start.parentNode,
|
|
310
|
+
bounds: e,
|
|
311
|
+
context: u.context,
|
|
312
|
+
render: (t) => T(e, t, u)
|
|
313
|
+
}) ?? void 0;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function E(e, t, n) {
|
|
317
|
+
let r = /* @__PURE__ */ new Map(), i = [];
|
|
318
|
+
if (!t || t.length === 0) return {
|
|
319
|
+
state: r,
|
|
320
|
+
prevOrder: i,
|
|
321
|
+
cleanup: () => {}
|
|
322
|
+
};
|
|
323
|
+
let a = /* @__PURE__ */ new Map();
|
|
324
|
+
for (let t = 0; t < e.items.length; t++) {
|
|
325
|
+
let n = u(e.keyFn(e.items[t], t), t), r = d(n);
|
|
326
|
+
a.has(r) && console.warn(`[elur] repeat(): duplicate client key "${n}" during hydration. Keys must be unique; entries after the first leak.`), a.set(r, t);
|
|
327
|
+
}
|
|
328
|
+
for (let o of t) {
|
|
329
|
+
let t = a.get(o.serializedKey);
|
|
330
|
+
if (t === void 0) {
|
|
331
|
+
D(o);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
let s = e.items[t], c = u(e.keyFn(s, t), t);
|
|
335
|
+
if (d(c) !== o.serializedKey && console.warn(`[elur] repeat(): hydration key mismatch at index ${t} (${l(o.serializedKey)} != ${c}). The SSR item is adopted by position.`), r.has(c)) {
|
|
336
|
+
console.warn(`[elur] repeat(): duplicate key "${c}" during hydration; removing duplicate SSR node.`), D(o);
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
let f = e.renderFn(s, t), p = T({
|
|
340
|
+
start: o.start,
|
|
341
|
+
end: o.end
|
|
342
|
+
}, f, n);
|
|
343
|
+
r.set(c, {
|
|
344
|
+
start: o.start,
|
|
345
|
+
end: o.end,
|
|
346
|
+
cleanup: p ?? (() => {})
|
|
347
|
+
}), i.push(c);
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
state: r,
|
|
351
|
+
prevOrder: i,
|
|
352
|
+
cleanup: () => {
|
|
353
|
+
for (let e of r.values()) e.cleanup();
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function D(e) {
|
|
358
|
+
let t = e.start.nextSibling;
|
|
359
|
+
for (; t && t !== e.end;) {
|
|
360
|
+
let e = t.nextSibling;
|
|
361
|
+
t.parentNode?.removeChild(t), t = e;
|
|
362
|
+
}
|
|
363
|
+
e.start.parentNode?.removeChild(e.start), e.end.parentNode?.removeChild(e.end);
|
|
364
|
+
}
|
|
365
|
+
function O(e, t) {
|
|
366
|
+
if (t == null || t === !1 || t === !0) return;
|
|
367
|
+
if (Array.isArray(t)) {
|
|
368
|
+
let n = [];
|
|
369
|
+
for (let r of t) {
|
|
370
|
+
let t = O(e, r);
|
|
371
|
+
t && n.push(t);
|
|
372
|
+
}
|
|
373
|
+
return n.length ? () => {
|
|
374
|
+
for (let e = n.length - 1; e >= 0; e--) n[e]();
|
|
375
|
+
} : void 0;
|
|
376
|
+
}
|
|
377
|
+
if (r(t)) return t._render(e.end.parentNode, e.end);
|
|
378
|
+
if (a(t)) return t.render()._render(e.end.parentNode, e.end);
|
|
379
|
+
let n = document.createTextNode(String(t));
|
|
380
|
+
return e.end.parentNode.insertBefore(n, e.end), () => n.parentNode?.removeChild(n);
|
|
381
|
+
}
|
|
382
|
+
function k(e) {
|
|
383
|
+
let t = e.start.nextSibling;
|
|
384
|
+
for (; t && t !== e.end;) {
|
|
385
|
+
if (t.nodeType === Node.TEXT_NODE) return t;
|
|
386
|
+
t = t.nextSibling;
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
function A(e) {
|
|
391
|
+
let t = e.start.nextSibling;
|
|
392
|
+
for (; t && t !== e.end;) {
|
|
393
|
+
let e = t.nextSibling;
|
|
394
|
+
t.parentNode?.removeChild(t), t = e;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function j(e, t, n, r) {
|
|
398
|
+
let i = {
|
|
399
|
+
index: t,
|
|
400
|
+
kind: n,
|
|
401
|
+
message: r
|
|
402
|
+
};
|
|
403
|
+
e.onMismatch?.(i);
|
|
404
|
+
let a = /* @__PURE__ */ Error(`[elur] Hydration marker mismatch: ${r}`);
|
|
405
|
+
throw Object.assign(a, { mismatch: i }), a;
|
|
406
|
+
}
|
|
407
|
+
//#endregion
|
|
408
|
+
export { _ as hydrate };
|
|
409
|
+
|
|
410
|
+
//# sourceMappingURL=hydrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrate.js","names":[],"sources":["../../src/elur/hydrate/index.ts"],"sourcesContent":["import { _captureContextSnapshot, _popComponentContext, _pushComponentContext } from \"../context.js\";\nimport { isElurComponent, type ElurComponent } from \"../lifecycle.js\";\nimport { effect } from \"../reactivity.js\";\nimport { sanitizeUrl } from \"../template/sanitize.js\";\nimport { activateDelegatedEvent, isDelegableEvent } from \"../template/bindings.js\";\nimport {\n isKeyedList,\n isElurTemplate,\n ELUR_RENDER_PROTOCOL,\n ELUR_TEMPLATE_DESCRIPTOR,\n type KEntry,\n type ElurMountHandle,\n type ElurRef,\n type ElurTemplate,\n type TemplateDescriptor,\n} from \"../template/types.js\";\nimport {\n deserializeRepeatKey,\n normalizeRepeatKey,\n serializeRepeatKey,\n type RepeatKey,\n} from \"../template/keyed.js\";\nimport { createKeyedMount, reconcileKeyedList } from \"../template/keyed-diff.js\";\n\nexport interface HydrateOptions {\n mismatch?: \"throw\" | \"warn-remount\" | \"remount\";\n onMismatch?: (error: HydrationMismatch) => void;\n context?: unknown;\n}\n\nexport interface HydrationMismatch {\n index: number;\n kind: \"node\" | \"attribute\" | \"event\" | \"descriptor\" | \"keyed\";\n message: string;\n}\n\ninterface MarkerRange {\n start: Comment;\n end: Comment;\n}\n\ninterface KeyedMarkerRange {\n start: Comment;\n end: Comment;\n serializedKey: string;\n}\n\ninterface ScannedMarkers {\n nodes: Map<number, MarkerRange>;\n attributes: Map<number, Element>;\n events: Map<number, Element>;\n keyed: Map<number, KeyedMarkerRange[]>;\n arrayItems: Map<number, MarkerRange[]>;\n}\n\nexport function hydrate(\n value: ElurTemplate | ElurComponent,\n container: Element,\n options: HydrateOptions = {},\n): ElurMountHandle {\n try {\n if (isElurComponent(value)) return hydrateComponent(value, container, options);\n const descriptor = value[ELUR_TEMPLATE_DESCRIPTOR];\n if (!descriptor) throwMismatch(options, -1, \"descriptor\", \"Template has no hydration descriptor\");\n const cleanup = hydrateDescriptor(descriptor!, container, options);\n return { unmount: cleanup };\n } catch (error) {\n if (options.mismatch === \"throw\") throw error;\n if (options.mismatch !== \"remount\") console.warn(\"[elur] Hydration mismatch; remounting root:\", error);\n container.replaceChildren();\n const cleanup = isElurComponent(value)\n ? value.render()._render(container, null)\n : value._render(container, null);\n return { unmount: cleanup };\n }\n}\n\nfunction hydrateComponent(\n component: ElurComponent,\n container: Element,\n options: HydrateOptions,\n): ElurMountHandle {\n _pushComponentContext();\n let cleanup = () => { };\n try {\n try {\n component.onInit?.();\n } catch (error) {\n if (component.onError) component.onError(error);\n else throw error;\n }\n const template = component.render();\n const descriptor = template[ELUR_TEMPLATE_DESCRIPTOR];\n if (!descriptor) throwMismatch(options, -1, \"descriptor\", \"Component template has no hydration descriptor\");\n cleanup = hydrateDescriptor(descriptor!, container, options);\n } finally {\n _popComponentContext();\n }\n const mountCleanup = component.onMount?.();\n return {\n unmount() {\n component.onUnmount?.();\n if (typeof mountCleanup === \"function\") mountCleanup();\n cleanup();\n },\n };\n}\n\nfunction hydrateDescriptor(\n descriptor: TemplateDescriptor,\n root: ParentNode,\n options: HydrateOptions,\n bounds?: MarkerRange,\n): () => void {\n const markers = scanMarkers(root, bounds);\n const cleanups: Array<() => void> = [];\n\n for (let index = 0; index < descriptor.contexts.length; index++) {\n const context = descriptor.contexts[index];\n const value = descriptor.values[index];\n if (context.type === \"event\") {\n const element = markers.events.get(index);\n if (!element) throwMismatch(options, index, \"event\", `Missing event marker ${index}`);\n element!.removeAttribute(`data-elur-e-${index}`);\n cleanups.push(activateEvent(element!, context.eventName, context.modifiers, value));\n continue;\n }\n if (context.type === \"attr\") {\n const element = markers.attributes.get(index);\n if (!element) throwMismatch(options, index, \"attribute\", `Missing attribute marker ${index}`);\n element!.removeAttribute(`data-elur-a-${index}`);\n cleanups.push(activateAttribute(element!, context.attrName, context.url === true, value));\n continue;\n }\n\n const range = markers.nodes.get(index);\n if (!range) throwMismatch(options, index, \"node\", `Missing node marker ${index}`);\n const cleanup = activateNode(range!, value, options, markers.keyed.get(index), markers.arrayItems.get(index));\n if (cleanup) cleanups.push(cleanup);\n }\n\n return () => {\n for (let index = cleanups.length - 1; index >= 0; index--) cleanups[index]();\n };\n}\n\nfunction scanMarkers(root: ParentNode, bounds?: MarkerRange): ScannedMarkers {\n const nodes = new Map<number, MarkerRange>();\n const starts = new Map<number, Comment>();\n const attributes = new Map<number, Element>();\n const events = new Map<number, Element>();\n const keyed = new Map<number, KeyedMarkerRange[]>();\n const arrayItems = new Map<number, MarkerRange[]>();\n const stack: number[] = [];\n const keyedStack: Array<{ start: Comment; serializedKey: string; parentIndex: number }> = [];\n const arrayStack: Array<{ start: Comment; parentIndex: number }> = [];\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);\n let current: Node | null;\n\n while ((current = walker.nextNode())) {\n if (bounds && !isInsideRange(current, bounds)) continue;\n if (current.nodeType === Node.COMMENT_NODE) {\n const comment = current as Comment;\n const startMatch = /^elur-(\\d+)$/.exec(comment.data);\n if (startMatch) {\n const index = Number(startMatch[1]);\n if (stack.length === 0) starts.set(index, comment);\n stack.push(index);\n continue;\n }\n const endMatch = /^elur-end-(\\d+)$/.exec(comment.data);\n if (endMatch) {\n const index = Number(endMatch[1]);\n const active = stack.pop();\n if (active === index && stack.length === 0) {\n const start = starts.get(index);\n if (start) nodes.set(index, { start, end: comment });\n }\n continue;\n }\n const keyedStartMatch = /^elur-ki:(.+)$/.exec(comment.data);\n if (keyedStartMatch) {\n const serializedKey = keyedStartMatch[1];\n if (keyedStack.length === 0 && stack.length === 1) {\n keyedStack.push({ start: comment, serializedKey, parentIndex: stack[stack.length - 1] });\n } else {\n keyedStack.push({ start: comment, serializedKey, parentIndex: -1 });\n }\n continue;\n }\n if (comment.data === \"elur-ke\") {\n const active = keyedStack.pop();\n if (active) {\n if (active.parentIndex >= 0) {\n const list = keyed.get(active.parentIndex) ?? [];\n list.push({ start: active.start, end: comment, serializedKey: active.serializedKey });\n keyed.set(active.parentIndex, list);\n }\n } else {\n throw new Error(\"[elur] Hydration marker mismatch: orphan keyed end marker (elur-ke)\");\n }\n continue;\n }\n if (comment.data === \"elur-ai\") {\n if (arrayStack.length === 0 && stack.length === 1) {\n arrayStack.push({ start: comment, parentIndex: stack[stack.length - 1] });\n } else {\n arrayStack.push({ start: comment, parentIndex: -1 });\n }\n continue;\n }\n if (comment.data === \"elur-aiend\") {\n const active = arrayStack.pop();\n if (active && active.parentIndex >= 0) {\n const list = arrayItems.get(active.parentIndex) ?? [];\n list.push({ start: active.start, end: comment });\n arrayItems.set(active.parentIndex, list);\n }\n continue;\n }\n continue;\n }\n if (stack.length > 0) continue;\n const element = current as Element;\n for (const attribute of Array.from(element.attributes)) {\n const eventMatch = /^data-elur-e-(\\d+)$/.exec(attribute.name);\n if (eventMatch) events.set(Number(eventMatch[1]), element);\n const attributeMatch = /^data-elur-a-(\\d+)$/.exec(attribute.name);\n if (attributeMatch) attributes.set(Number(attributeMatch[1]), element);\n }\n }\n\n return { nodes, attributes, events, keyed, arrayItems };\n}\n\nfunction isInsideRange(node: Node, range: MarkerRange): boolean {\n const domRange = document.createRange();\n domRange.setStartAfter(range.start);\n domRange.setEndBefore(range.end);\n return domRange.intersectsNode(node);\n}\n\nfunction activateEvent(\n element: Element,\n eventName: string,\n modifiers: readonly string[],\n value: unknown,\n): () => void {\n if (typeof value !== \"function\") throw new TypeError(`Event \"${eventName}\" requires a function`);\n const rawHandler = value as EventListener;\n\n // Use global delegation for delegable events without capture/once mods,\n // matching the mount-time behavior in bindings.ts. The element must be\n // connected to the document for delegation to work (events bubble to\n // document where the delegated listener is registered).\n const canDelegate =\n isDelegableEvent(eventName) &&\n !modifiers.includes(\"capture\") &&\n !modifiers.includes(\"once\") &&\n document.body.contains(element);\n\n if (canDelegate) {\n return activateDelegatedEvent(element, eventName, modifiers, rawHandler);\n }\n\n // Non-delegable events or disconnected elements: use addEventListener directly.\n const options: AddEventListenerOptions = {\n once: modifiers.includes(\"once\"),\n capture: modifiers.includes(\"capture\"),\n passive: modifiers.includes(\"passive\"),\n };\n const listener = (event: Event) => {\n if (modifiers.includes(\"prevent\")) event.preventDefault();\n if (modifiers.includes(\"stop\")) event.stopPropagation();\n if (modifiers.includes(\"self\") && event.target !== event.currentTarget) return;\n rawHandler(event);\n };\n element.addEventListener(eventName, listener, options);\n return () => element.removeEventListener(eventName, listener, options);\n}\n\nfunction activateAttribute(\n element: Element,\n name: string,\n url: boolean,\n value: unknown,\n): () => void {\n if (name === \"ref\") {\n const reference = value as ElurRef<Element>;\n reference.el = element;\n return () => { reference.el = null; };\n }\n\n const isProperty = (name === \"value\" || name === \"checked\" || name === \"selected\") && name in element;\n let firstRun = true;\n let pendingSync = false;\n const update = (resolved: unknown) => {\n if (isProperty) {\n if (!firstRun) {\n (element as any)[name] = resolved ?? \"\";\n } else {\n // Interaction before hydration: the DOM may hold a value the\n // user (or a hydration race with lazy island directives like\n // \"visible\") wrote before the binding activated. The DOM is\n // authoritative; keep it and propagate it to reactive model\n // sources once every handler is attached (microtask) so a\n // late @input/@change listener picks up the real value.\n const current = (element as any)[name];\n const model = resolved ?? \"\";\n if (String(current) !== String(model) && !pendingSync) {\n pendingSync = true;\n const eventName = name === \"checked\" || name === \"selected\" ? \"change\" : \"input\";\n queueMicrotask(() => {\n pendingSync = false;\n element.dispatchEvent(new Event(eventName, { bubbles: true }));\n });\n }\n }\n } else if (resolved === null || resolved === undefined || resolved === false) {\n element.removeAttribute(name);\n } else {\n const serialized = url ? sanitizeUrl(String(resolved)) : String(resolved);\n element.setAttribute(name, serialized);\n }\n firstRun = false;\n };\n\n if (typeof value === \"function\") {\n return effect(() => update((value as () => unknown)()));\n }\n update(value);\n return () => { };\n}\n\nfunction activateNode(\n range: MarkerRange,\n value: unknown,\n options: HydrateOptions,\n keyedItems?: KeyedMarkerRange[],\n arrayItems?: MarkerRange[],\n): (() => void) | undefined {\n if (typeof value !== \"function\") return hydrateNodeValue(range, value, options, keyedItems, arrayItems);\n\n let firstRun = true;\n let nestedCleanup: (() => void) | undefined;\n let textNode = findTextNode(range);\n let keyed: { state: Map<RepeatKey, KEntry>; prevOrder: RepeatKey[] } | null = null;\n const ctxSnapshot = _captureContextSnapshot();\n const keyedMount = createKeyedMount(ctxSnapshot);\n\n const warnDuplicate = (key: RepeatKey) => {\n console.warn(`[elur] repeat(): duplicate key \"${key}\". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);\n };\n\n const dispose = effect(() => {\n const resolved = (value as () => unknown)();\n\n if (isKeyedList(resolved)) {\n if (firstRun && !keyed) {\n // First resolution is a keyed list: adopt the SSR markers when\n // present. Afterwards we converge with the current model, which\n // handles count/ordering drift without recreating surviving nodes.\n const adopted = adoptKeyedRange(resolved, keyedItems, options);\n keyed = { state: adopted.state, prevOrder: adopted.prevOrder };\n nestedCleanup = adopted.cleanup;\n reconcileKeyedList({\n zoneStart: range.start,\n anchor: range.end,\n state: keyed.state,\n prevOrder: keyed.prevOrder,\n list: resolved,\n mount: keyedMount,\n ctxSnapshot,\n onDuplicateKey: warnDuplicate,\n });\n textNode = null;\n firstRun = false;\n return;\n }\n if (!keyed) {\n // The binding became keyed after another value: the SSR markers\n // were already consumed (or never existed), so mount fresh.\n nestedCleanup?.();\n clearRange(range);\n keyed = { state: new Map(), prevOrder: [] };\n nestedCleanup = () => {\n for (const entry of keyed!.state.values()) entry.cleanup();\n };\n }\n reconcileKeyedList({\n zoneStart: range.start,\n anchor: range.end,\n state: keyed.state,\n prevOrder: keyed.prevOrder,\n list: resolved,\n mount: keyedMount,\n ctxSnapshot,\n onDuplicateKey: warnDuplicate,\n });\n textNode = null;\n firstRun = false;\n return;\n }\n\n // Non-keyed value: tear down any keyed zone first.\n if (keyed) {\n nestedCleanup?.();\n clearRange(range);\n keyed = null;\n nestedCleanup = undefined;\n }\n\n if (typeof resolved === \"string\" || typeof resolved === \"number\" || typeof resolved === \"bigint\") {\n if (!textNode) {\n textNode = document.createTextNode(String(resolved));\n range.end.parentNode!.insertBefore(textNode, range.end);\n } else if (textNode.nodeValue !== String(resolved)) {\n textNode.nodeValue = String(resolved);\n }\n } else if (firstRun) {\n nestedCleanup = hydrateNodeValue(range, resolved, options, keyedItems, arrayItems);\n } else {\n nestedCleanup?.();\n clearRange(range);\n nestedCleanup = mountNodeValue(range, resolved);\n textNode = findTextNode(range);\n }\n firstRun = false;\n });\n\n return () => {\n dispose();\n nestedCleanup?.();\n };\n}\n\nfunction hydrateNodeValue(\n range: MarkerRange,\n value: unknown,\n options: HydrateOptions,\n keyedItems?: KeyedMarkerRange[],\n arrayItems?: MarkerRange[],\n): (() => void) | undefined {\n if (isKeyedList(value)) {\n const ctxSnapshot = _captureContextSnapshot();\n const adopted = adoptKeyedRange(value, keyedItems, options);\n reconcileKeyedList({\n zoneStart: range.start,\n anchor: range.end,\n state: adopted.state,\n prevOrder: adopted.prevOrder,\n list: value,\n mount: createKeyedMount(ctxSnapshot),\n ctxSnapshot,\n onDuplicateKey: (key) => {\n console.warn(`[elur] repeat(): duplicate key \"${key}\". Keys must be unique; the previous entry leaks (orphaned nodes + live effects).`);\n },\n });\n return adopted.cleanup;\n }\n if (Array.isArray(value)) {\n const cleanups: Array<() => void> = [];\n const hasMarkers = arrayItems !== undefined && arrayItems.length > 0;\n for (let index = 0; index < value.length; index++) {\n const item = value[index];\n const itemBounds = arrayItems?.[index];\n if (hasMarkers && itemBounds) {\n // Hydrate each item within its own SSR-delimited range so\n // repeated marker indices across items never collide.\n const cleanup = hydrateNodeValue(itemBounds, item, options);\n if (cleanup) cleanups.push(cleanup);\n } else if (hasMarkers) {\n // Client item with no SSR slot: mount it fresh at the end.\n const cleanup = mountNodeValue(range, item);\n if (cleanup) cleanups.push(cleanup);\n } else {\n const cleanup = hydrateNodeValue(range, item, options);\n if (cleanup) cleanups.push(cleanup);\n }\n }\n return cleanups.length ? () => { for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i](); } : undefined;\n }\n if (isElurTemplate(value)) {\n const descriptor = value[ELUR_TEMPLATE_DESCRIPTOR];\n if (!descriptor) throwMismatch(options, -1, \"descriptor\", \"Nested template has no hydration descriptor\");\n return hydrateDescriptor(descriptor!, range.start.parentNode as ParentNode, options, range);\n }\n if (isElurComponent(value)) {\n _pushComponentContext();\n let result: (() => void) | undefined;\n try {\n try {\n value.onInit?.();\n } catch (error) {\n if (value.onError) value.onError(error);\n else throw error;\n }\n const template = value.render();\n const descriptor = template[ELUR_TEMPLATE_DESCRIPTOR];\n if (!descriptor) throwMismatch(options, -1, \"descriptor\", \"Nested component has no hydration descriptor\");\n const cleanup = hydrateDescriptor(descriptor!, range.start.parentNode as ParentNode, options, range);\n const mountCleanup = value.onMount?.();\n result = () => {\n value.onUnmount?.();\n if (typeof mountCleanup === \"function\") mountCleanup();\n cleanup();\n };\n } finally {\n _popComponentContext();\n }\n return result;\n }\n if (value != null && typeof value === \"object\") {\n const protocol = (value as Record<PropertyKey, unknown>)[ELUR_RENDER_PROTOCOL] as\n | { hydrateDom?: (ctx: import(\"../template/types.js\").HydrationProtocolContext) => (() => void) | void }\n | undefined;\n if (protocol?.hydrateDom) {\n return protocol.hydrateDom({\n parent: range.start.parentNode!,\n bounds: range,\n context: options.context,\n render: (nested) => hydrateNodeValue(range, nested, options),\n }) ?? undefined;\n }\n }\n return undefined;\n}\n\nfunction adoptKeyedRange(\n list: import(\"../template/types.js\").KeyedList,\n keyedItems: KeyedMarkerRange[] | undefined,\n options: HydrateOptions,\n): { state: Map<RepeatKey, KEntry>; prevOrder: RepeatKey[]; cleanup: () => void } {\n const state = new Map<RepeatKey, KEntry>();\n const prevOrder: RepeatKey[] = [];\n\n if (!keyedItems || keyedItems.length === 0) {\n return { state, prevOrder, cleanup: () => { } };\n }\n\n const clientByKey = new Map<string, number>();\n for (let j = 0; j < list.items.length; j++) {\n const key = normalizeRepeatKey(list.keyFn(list.items[j], j), j);\n const serialized = serializeRepeatKey(key);\n if (clientByKey.has(serialized)) {\n console.warn(\n `[elur] repeat(): duplicate client key \"${key}\" during hydration. ` +\n \"Keys must be unique; entries after the first leak.\",\n );\n }\n clientByKey.set(serialized, j);\n }\n\n for (const marker of keyedItems) {\n const clientIndex = clientByKey.get(marker.serializedKey);\n if (clientIndex === undefined) {\n // SSR item not present in the client model → remove its DOM.\n removeKeyedMarker(marker);\n continue;\n }\n const item = list.items[clientIndex];\n const key = normalizeRepeatKey(list.keyFn(item, clientIndex), clientIndex);\n if (serializeRepeatKey(key) !== marker.serializedKey) {\n console.warn(\n `[elur] repeat(): hydration key mismatch at index ${clientIndex} ` +\n `(${deserializeRepeatKey(marker.serializedKey)} != ${key}). The SSR item is adopted by position.`,\n );\n }\n if (state.has(key)) {\n console.warn(`[elur] repeat(): duplicate key \"${key}\" during hydration; removing duplicate SSR node.`);\n removeKeyedMarker(marker);\n continue;\n }\n const rendered = list.renderFn(item, clientIndex);\n const cleanup = hydrateNodeValue(\n { start: marker.start, end: marker.end },\n rendered,\n options,\n );\n state.set(key, { start: marker.start, end: marker.end, cleanup: cleanup ?? (() => { }) });\n prevOrder.push(key);\n }\n\n return {\n state,\n prevOrder,\n cleanup: () => {\n for (const entry of state.values()) entry.cleanup();\n },\n };\n}\n\nfunction removeKeyedMarker(marker: KeyedMarkerRange): void {\n let node: Node | null = marker.start.nextSibling;\n while (node && node !== marker.end) {\n const next = node.nextSibling;\n node.parentNode?.removeChild(node);\n node = next;\n }\n marker.start.parentNode?.removeChild(marker.start);\n marker.end.parentNode?.removeChild(marker.end);\n}\n\nfunction mountNodeValue(range: MarkerRange, value: unknown): (() => void) | undefined {\n if (value === null || value === undefined || value === false || value === true) return undefined;\n if (Array.isArray(value)) {\n const cleanups: Array<() => void> = [];\n for (const item of value) {\n const cleanup = mountNodeValue(range, item);\n if (cleanup) cleanups.push(cleanup);\n }\n return cleanups.length ? () => { for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i](); } : undefined;\n }\n if (isElurTemplate(value)) return value._render(range.end.parentNode!, range.end);\n if (isElurComponent(value)) return value.render()._render(range.end.parentNode!, range.end);\n const node = document.createTextNode(String(value));\n range.end.parentNode!.insertBefore(node, range.end);\n return () => node.parentNode?.removeChild(node);\n}\n\nfunction findTextNode(range: MarkerRange): Text | null {\n let node = range.start.nextSibling;\n while (node && node !== range.end) {\n if (node.nodeType === Node.TEXT_NODE) return node as Text;\n node = node.nextSibling;\n }\n return null;\n}\n\nfunction clearRange(range: MarkerRange): void {\n let node = range.start.nextSibling;\n while (node && node !== range.end) {\n const next = node.nextSibling;\n node.parentNode?.removeChild(node);\n node = next;\n }\n}\n\nfunction throwMismatch(\n options: HydrateOptions,\n index: number,\n kind: HydrationMismatch[\"kind\"],\n message: string,\n): never {\n const mismatch = { index, kind, message } satisfies HydrationMismatch;\n options.onMismatch?.(mismatch);\n const error = new Error(`[elur] Hydration marker mismatch: ${message}`);\n Object.assign(error, { mismatch });\n throw error;\n}"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { Signal, signal, effect, computed, batch, watch, untrack, nextTick } from "./reactivity.js";
|
|
2
|
+
export type { WatchOptions } from "./reactivity.js";
|
|
3
|
+
export { html, repeat, raw, ref, showWhen, portal, createPortalOutlet, portalOutlet, provideOutlet, injectOutlet, createErrorBoundary, transition, ELUR_TEMPLATE_DESCRIPTOR, ELUR_RENDER_PROTOCOL, templateFeatures } from "./template/index.js";
|
|
4
|
+
export type { ElurTemplate, ElurMountHandle, KeyedList, ElurRef, PortalOutlet, ErrorFallback, TransitionOptions, TransitionContent, TemplateBindingContext, TemplateDescriptor, ElurRenderProtocol, ServerRenderProtocolContext, DomProtocolContext, HydrationProtocolContext } from "./template/index.js";
|
|
5
|
+
export { mount } from "./component.js";
|
|
6
|
+
export type { MountOptions } from "./component.js";
|
|
7
|
+
export { ElurComponent } from "./lifecycle.js";
|
|
8
|
+
export type { ElurChildren } from "./lifecycle.js";
|
|
9
|
+
export { createStore } from "./store.js";
|
|
10
|
+
export type { Store, StoreSignals, ElurPlugin } from "./store.js";
|
|
11
|
+
export { persistPlugin, loggerPlugin, guardPlugin, bridgePlugin } from "./plugins.js";
|
|
12
|
+
export { createRouter, RouterView, Link, elurRouter, RouterKey, _hasActiveRouter } from "./router.js";
|
|
13
|
+
export type { Router, NamedRouteLocation, RouteLocation, RouteRecord, RouterOptions, NavigationGuard, NavigationGuardResult, AfterEachHook, ResolvedRoute, ScrollPosition, ScrollBehavior, RouterMode, NavigationDirection, NavigationIntent, NavigationAction, NavigateOptions, } from "./router.js";
|
|
14
|
+
export { suspend, lazy } from "./async.js";
|
|
15
|
+
export type { SuspenseOptions } from "./async.js";
|
|
16
|
+
export { provide, inject, createInjectionKey } from "./context.js";
|
|
17
|
+
export type { InjectionKey } from "./context.js";
|
|
18
|
+
export { elurField, elurFieldArray, createForm, required, minLength, maxLength, email, pattern, min, max, createValidator, validators, extendValidators, } from "./form.js";
|
|
19
|
+
export type { DeepPartial, Validator, ValidateOn, FieldState, FieldArrayState, FieldErrors, FormState, FormOptions, ValidatorsBase } from "./form.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { Signal, signal, effect, computed, batch, watch, untrack, nextTick } from "./reactivity.js";
|
|
2
|
+
export type { WatchOptions } from "./reactivity.js";
|
|
3
|
+
export { html, repeat, raw, ref, showWhen, portal, createPortalOutlet, portalOutlet, provideOutlet, injectOutlet, createErrorBoundary, transition, ELUR_TEMPLATE_DESCRIPTOR, ELUR_RENDER_PROTOCOL, templateFeatures } from "./template/index.js";
|
|
4
|
+
export type { ElurTemplate, ElurMountHandle, KeyedList, ElurRef, PortalOutlet, ErrorFallback, TransitionOptions, TransitionContent, TemplateBindingContext, TemplateDescriptor, ElurRenderProtocol, ServerRenderProtocolContext, DomProtocolContext, HydrationProtocolContext } from "./template/index.js";
|
|
5
|
+
export { mount } from "./component.js";
|
|
6
|
+
export type { MountOptions } from "./component.js";
|
|
7
|
+
export { ElurComponent } from "./lifecycle.js";
|
|
8
|
+
export type { ElurChildren } from "./lifecycle.js";
|
|
9
|
+
export { createStore } from "./store.js";
|
|
10
|
+
export type { Store, StoreSignals, ElurPlugin } from "./store.js";
|
|
11
|
+
export { persistPlugin, loggerPlugin, guardPlugin, bridgePlugin } from "./plugins.js";
|
|
12
|
+
export { createRouter, RouterView, Link, elurRouter, RouterKey, _hasActiveRouter } from "./router.js";
|
|
13
|
+
export type { Router, NamedRouteLocation, RouteLocation, RouteRecord, RouterOptions, NavigationGuard, NavigationGuardResult, AfterEachHook, ResolvedRoute, ScrollPosition, ScrollBehavior, RouterMode, NavigationDirection, NavigationIntent, NavigationAction, NavigateOptions, } from "./router.js";
|
|
14
|
+
export { suspend, lazy } from "./async.js";
|
|
15
|
+
export type { SuspenseOptions } from "./async.js";
|
|
16
|
+
export { provide, inject, createInjectionKey } from "./context.js";
|
|
17
|
+
export type { InjectionKey } from "./context.js";
|
|
18
|
+
export { elurField, elurFieldArray, createForm, required, minLength, maxLength, email, pattern, min, max, createValidator, validators, extendValidators, } from "./form.js";
|
|
19
|
+
export type { DeepPartial, Validator, ValidateOn, FieldState, FieldArrayState, FieldErrors, FormState, FormOptions, ValidatorsBase } from "./form.js";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{__isElurComponent=!0;children;_debugName;_slots=new Map;setChildren(e){return this.children=e,this}setSlot(e,t){return this._slots.set(e,t),this}slot(e){return this._slots.get(e)}setDebugName(e){return this._debugName=e,this}};function t(e){return typeof e==`object`&&!!e&&e.__isElurComponent===!0}var n=null;function r(e){n=e}function i(e){n?.onMountStart?.(e)}function a(e){n?.onMountEnd?.(e)}function o(e){n?.onUnmount?.(e)}exports.ElurComponent=e,exports._debugComponentMountEnd=a,exports._debugComponentMountStart=i,exports._debugComponentUnmount=o,exports._setComponentDebugHooks=r,exports.isElurComponent=t;
|
|
2
|
+
//# sourceMappingURL=lifecycle.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.cjs","names":[],"sources":["../../src/elur/lifecycle.ts"],"sourcesContent":["import type { ElurTemplate } from \"./template/index.js\";\n\n// --- ElurChildren ---\n\n/** Valid child content for components. */\nexport type ElurChildren =\n | ElurTemplate\n | ElurComponent\n | Array<ElurTemplate | ElurComponent>\n | null\n | undefined;\n\n// --- ElurComponent ---\n\n/** Base class for components with lifecycle hooks. */\nexport abstract class ElurComponent {\n /** @internal */\n readonly __isElurComponent = true as const;\n\n /** Default slot — child content injected by the parent. */\n children?: ElurChildren;\n\n /** Optional label used by devtools. Falls back to class name. */\n _debugName?: string;\n\n /** @internal */\n private _slots = new Map<string, ElurChildren>();\n\n /** Sets the default slot content. Returns `this` for chaining. */\n setChildren(content: ElurChildren): this {\n this.children = content;\n return this;\n }\n\n /** Sets a named slot. Returns `this` for chaining. */\n setSlot(name: string, content: ElurChildren): this {\n this._slots.set(name, content);\n return this;\n }\n\n /** Returns content for a named slot. */\n slot(name: string): ElurChildren {\n return this._slots.get(name);\n }\n\n /** Sets an explicit devtools display name. Returns `this` for chaining. */\n setDebugName(name: string): this {\n this._debugName = name;\n return this;\n }\n\n /** Returns the component template. Called once on mount; updates happen via signals. */\n abstract render(): ElurTemplate;\n\n /** Called before `render()` — no DOM yet. Errors are caught by `onError` if present. */\n onInit?(): void;\n\n /** Server-only lifecycle hook. Runs during SSR after `onInit()`; never on the client. */\n onServerRender?(): void;\n\n /** Called after DOM insertion. May return a cleanup function. */\n onMount?(): (() => void) | void;\n\n /** Called before DOM removal. */\n onUnmount?(): void;\n\n /** Catches errors thrown in `onInit` and `onMount`. */\n onError?(err: unknown): void;\n}\n\n// --- Type guard ---\n\n/** @internal */\nexport function isElurComponent(v: unknown): v is ElurComponent {\n return (\n v != null &&\n typeof v === \"object\" &&\n (v as Record<string, unknown>).__isElurComponent === true\n );\n}\n\n// --- Devtools component tracking (internal) ---\n\nexport interface _ComponentDebugHooks {\n onMountStart?: (inst: ElurComponent) => void;\n onMountEnd?: (inst: ElurComponent) => void;\n onUnmount?: (inst: ElurComponent) => void;\n}\n\nlet _componentDebugHooks: _ComponentDebugHooks | null = null;\n\nexport function _setComponentDebugHooks(hooks: _ComponentDebugHooks | null): void {\n _componentDebugHooks = hooks;\n}\n\nexport function _debugComponentMountStart(inst: ElurComponent): void {\n _componentDebugHooks?.onMountStart?.(inst);\n}\n\nexport function _debugComponentMountEnd(inst: ElurComponent): void {\n _componentDebugHooks?.onMountEnd?.(inst);\n}\n\nexport function _debugComponentUnmount(inst: ElurComponent): void {\n _componentDebugHooks?.onUnmount?.(inst);\n}\n"],"mappings":"mEAeA,IAAsB,EAAtB,KAAoC,CAEhC,kBAA6B,GAG7B,SAGA,WAGA,OAAiB,IAAI,IAGrB,YAAY,EAA6B,CAErC,MADA,MAAK,SAAW,EACT,KAIX,QAAQ,EAAc,EAA6B,CAE/C,OADA,KAAK,OAAO,IAAI,EAAM,EAAQ,CACvB,KAIX,KAAK,EAA4B,CAC7B,OAAO,KAAK,OAAO,IAAI,EAAK,CAIhC,aAAa,EAAoB,CAE7B,MADA,MAAK,WAAa,EACX,OAyBf,SAAgB,EAAgB,EAAgC,CAC5D,OAEI,OAAO,GAAM,YADb,GAEC,EAA8B,oBAAsB,GAY7D,IAAI,EAAoD,KAExD,SAAgB,EAAwB,EAA0C,CAC9E,EAAuB,EAG3B,SAAgB,EAA0B,EAA2B,CACjE,GAAsB,eAAe,EAAK,CAG9C,SAAgB,EAAwB,EAA2B,CAC/D,GAAsB,aAAa,EAAK,CAG5C,SAAgB,EAAuB,EAA2B,CAC9D,GAAsB,YAAY,EAAK"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ElurTemplate } from "./template/index.js";
|
|
2
|
+
/** Valid child content for components. */
|
|
3
|
+
export type ElurChildren = ElurTemplate | ElurComponent | Array<ElurTemplate | ElurComponent> | null | undefined;
|
|
4
|
+
/** Base class for components with lifecycle hooks. */
|
|
5
|
+
export declare abstract class ElurComponent {
|
|
6
|
+
/** @internal */
|
|
7
|
+
readonly __isElurComponent: true;
|
|
8
|
+
/** Default slot — child content injected by the parent. */
|
|
9
|
+
children?: ElurChildren;
|
|
10
|
+
/** Optional label used by devtools. Falls back to class name. */
|
|
11
|
+
_debugName?: string;
|
|
12
|
+
/** @internal */
|
|
13
|
+
private _slots;
|
|
14
|
+
/** Sets the default slot content. Returns `this` for chaining. */
|
|
15
|
+
setChildren(content: ElurChildren): this;
|
|
16
|
+
/** Sets a named slot. Returns `this` for chaining. */
|
|
17
|
+
setSlot(name: string, content: ElurChildren): this;
|
|
18
|
+
/** Returns content for a named slot. */
|
|
19
|
+
slot(name: string): ElurChildren;
|
|
20
|
+
/** Sets an explicit devtools display name. Returns `this` for chaining. */
|
|
21
|
+
setDebugName(name: string): this;
|
|
22
|
+
/** Returns the component template. Called once on mount; updates happen via signals. */
|
|
23
|
+
abstract render(): ElurTemplate;
|
|
24
|
+
/** Called before `render()` — no DOM yet. Errors are caught by `onError` if present. */
|
|
25
|
+
onInit?(): void;
|
|
26
|
+
/** Server-only lifecycle hook. Runs during SSR after `onInit()`; never on the client. */
|
|
27
|
+
onServerRender?(): void;
|
|
28
|
+
/** Called after DOM insertion. May return a cleanup function. */
|
|
29
|
+
onMount?(): (() => void) | void;
|
|
30
|
+
/** Called before DOM removal. */
|
|
31
|
+
onUnmount?(): void;
|
|
32
|
+
/** Catches errors thrown in `onInit` and `onMount`. */
|
|
33
|
+
onError?(err: unknown): void;
|
|
34
|
+
}
|
|
35
|
+
/** @internal */
|
|
36
|
+
export declare function isElurComponent(v: unknown): v is ElurComponent;
|
|
37
|
+
export interface _ComponentDebugHooks {
|
|
38
|
+
onMountStart?: (inst: ElurComponent) => void;
|
|
39
|
+
onMountEnd?: (inst: ElurComponent) => void;
|
|
40
|
+
onUnmount?: (inst: ElurComponent) => void;
|
|
41
|
+
}
|
|
42
|
+
export declare function _setComponentDebugHooks(hooks: _ComponentDebugHooks | null): void;
|
|
43
|
+
export declare function _debugComponentMountStart(inst: ElurComponent): void;
|
|
44
|
+
export declare function _debugComponentMountEnd(inst: ElurComponent): void;
|
|
45
|
+
export declare function _debugComponentUnmount(inst: ElurComponent): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ElurTemplate } from "./template/index.js";
|
|
2
|
+
/** Valid child content for components. */
|
|
3
|
+
export type ElurChildren = ElurTemplate | ElurComponent | Array<ElurTemplate | ElurComponent> | null | undefined;
|
|
4
|
+
/** Base class for components with lifecycle hooks. */
|
|
5
|
+
export declare abstract class ElurComponent {
|
|
6
|
+
/** @internal */
|
|
7
|
+
readonly __isElurComponent: true;
|
|
8
|
+
/** Default slot — child content injected by the parent. */
|
|
9
|
+
children?: ElurChildren;
|
|
10
|
+
/** Optional label used by devtools. Falls back to class name. */
|
|
11
|
+
_debugName?: string;
|
|
12
|
+
/** @internal */
|
|
13
|
+
private _slots;
|
|
14
|
+
/** Sets the default slot content. Returns `this` for chaining. */
|
|
15
|
+
setChildren(content: ElurChildren): this;
|
|
16
|
+
/** Sets a named slot. Returns `this` for chaining. */
|
|
17
|
+
setSlot(name: string, content: ElurChildren): this;
|
|
18
|
+
/** Returns content for a named slot. */
|
|
19
|
+
slot(name: string): ElurChildren;
|
|
20
|
+
/** Sets an explicit devtools display name. Returns `this` for chaining. */
|
|
21
|
+
setDebugName(name: string): this;
|
|
22
|
+
/** Returns the component template. Called once on mount; updates happen via signals. */
|
|
23
|
+
abstract render(): ElurTemplate;
|
|
24
|
+
/** Called before `render()` — no DOM yet. Errors are caught by `onError` if present. */
|
|
25
|
+
onInit?(): void;
|
|
26
|
+
/** Server-only lifecycle hook. Runs during SSR after `onInit()`; never on the client. */
|
|
27
|
+
onServerRender?(): void;
|
|
28
|
+
/** Called after DOM insertion. May return a cleanup function. */
|
|
29
|
+
onMount?(): (() => void) | void;
|
|
30
|
+
/** Called before DOM removal. */
|
|
31
|
+
onUnmount?(): void;
|
|
32
|
+
/** Catches errors thrown in `onInit` and `onMount`. */
|
|
33
|
+
onError?(err: unknown): void;
|
|
34
|
+
}
|
|
35
|
+
/** @internal */
|
|
36
|
+
export declare function isElurComponent(v: unknown): v is ElurComponent;
|
|
37
|
+
export interface _ComponentDebugHooks {
|
|
38
|
+
onMountStart?: (inst: ElurComponent) => void;
|
|
39
|
+
onMountEnd?: (inst: ElurComponent) => void;
|
|
40
|
+
onUnmount?: (inst: ElurComponent) => void;
|
|
41
|
+
}
|
|
42
|
+
export declare function _setComponentDebugHooks(hooks: _ComponentDebugHooks | null): void;
|
|
43
|
+
export declare function _debugComponentMountStart(inst: ElurComponent): void;
|
|
44
|
+
export declare function _debugComponentMountEnd(inst: ElurComponent): void;
|
|
45
|
+
export declare function _debugComponentUnmount(inst: ElurComponent): void;
|