elements-kit 0.18.2 → 0.20.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/README.md +14 -0
- package/dist/await.d.mts +53 -0
- package/dist/await.mjs +70 -0
- package/dist/custom-elements.d.mts +1 -1
- package/dist/{element-xQwq4ulc.mjs → element-D3om9yA6.mjs} +71 -4
- package/dist/for.d.mts +20 -26
- package/dist/for.mjs +29 -4
- package/dist/fragment-ROPRBJQd.mjs +61 -0
- package/dist/hydrate/index.d.mts +41 -0
- package/dist/hydrate/index.mjs +2 -0
- package/dist/hydrate-6Qx4n4Su.mjs +380 -0
- package/dist/integrations/astro-client.d.mts +17 -0
- package/dist/integrations/astro-client.mjs +23 -0
- package/dist/integrations/astro-server.d.mts +15 -0
- package/dist/integrations/astro-server.mjs +39 -0
- package/dist/integrations/astro-slots.d.mts +12 -0
- package/dist/integrations/astro-slots.mjs +30 -0
- package/dist/integrations/astro.d.mts +46 -0
- package/dist/integrations/astro.mjs +64 -0
- package/dist/integrations/react.d.mts +1 -1
- package/dist/integrations/react.mjs +2 -2
- package/dist/jsx-runtime/index.d.mts +1 -1
- package/dist/jsx-runtime/index.mjs +2 -20
- package/dist/{lib-Dkc7cV5F.mjs → lib-DYypKhxk.mjs} +63 -5
- package/dist/render.mjs +1 -1
- package/dist/{scope-CnEvL9Nd.mjs → scope-zbEG299F.mjs} +1 -1
- package/dist/server/index.d.mts +43 -0
- package/dist/server/index.mjs +2 -0
- package/dist/server-iFSng50i.mjs +385 -0
- package/dist/signals/index.d.mts +2 -2
- package/dist/signals/index.mjs +5 -3
- package/dist/{slot-B8y0aEoz.d.mts → slot-BFWXeFRl.d.mts} +6 -0
- package/dist/{slot-Cne__au7.mjs → slot-Dvf30O0B.mjs} +12 -1
- package/dist/slot.d.mts +1 -1
- package/dist/slot.mjs +1 -1
- package/dist/{infer-B7T5hi_D.d.mts → types-ncUK9rki.d.mts} +140 -141
- package/dist/ui/overlay/index.css +70 -0
- package/dist/ui/overlay/index.d.mts +209 -0
- package/dist/ui/overlay/index.mjs +1001 -0
- package/dist/ui/overlay/overlay.css +332 -0
- package/dist/utilities/_observe.mjs +1 -1
- package/dist/utilities/active-element.d.mts +1 -1
- package/dist/utilities/active-element.mjs +1 -1
- package/dist/utilities/async.d.mts +19 -2
- package/dist/utilities/async.mjs +49 -2
- package/dist/utilities/context.mjs +1 -1
- package/dist/utilities/debounced.d.mts +1 -1
- package/dist/utilities/debounced.mjs +1 -1
- package/dist/utilities/dom-lifecycle.bench.mjs +3255 -1
- package/dist/utilities/dom-lifecycle.mjs +1 -1
- package/dist/utilities/element-rect.d.mts +1 -1
- package/dist/utilities/element-rect.mjs +1 -1
- package/dist/utilities/element-scroll.d.mts +1 -1
- package/dist/utilities/event-driven.d.mts +1 -1
- package/dist/utilities/event-driven.mjs +1 -1
- package/dist/utilities/event-listener.d.mts +1 -1
- package/dist/utilities/event-listener.mjs +1 -1
- package/dist/utilities/focus-within.d.mts +1 -1
- package/dist/utilities/focus-within.mjs +1 -1
- package/dist/utilities/form-object.d.mts +96 -0
- package/dist/utilities/form-object.mjs +285 -0
- package/dist/utilities/hover.d.mts +1 -1
- package/dist/utilities/hover.mjs +1 -1
- package/dist/utilities/interval.d.mts +1 -1
- package/dist/utilities/interval.mjs +1 -1
- package/dist/utilities/location.d.mts +1 -1
- package/dist/utilities/location.mjs +1 -1
- package/dist/utilities/media-devices.d.mts +1 -1
- package/dist/utilities/media-devices.mjs +1 -1
- package/dist/utilities/media-player.d.mts +1 -1
- package/dist/utilities/media-query.d.mts +1 -1
- package/dist/utilities/media-query.mjs +1 -1
- package/dist/utilities/network.d.mts +1 -1
- package/dist/utilities/network.mjs +1 -1
- package/dist/utilities/orientation.d.mts +1 -1
- package/dist/utilities/orientation.mjs +1 -1
- package/dist/utilities/previous.d.mts +1 -1
- package/dist/utilities/previous.mjs +1 -1
- package/dist/utilities/promise.d.mts +19 -2
- package/dist/utilities/promise.mjs +33 -3
- package/dist/utilities/retry.mjs +1 -1
- package/dist/utilities/routing.d.mts +1 -1
- package/dist/utilities/routing.mjs +1 -1
- package/dist/utilities/search-params.d.mts +1 -1
- package/dist/utilities/storage.d.mts +1 -1
- package/dist/utilities/throttled.d.mts +1 -1
- package/dist/utilities/throttled.mjs +1 -1
- package/dist/utilities/timeout.d.mts +1 -1
- package/dist/utilities/timeout.mjs +1 -1
- package/dist/utilities/window-focus.d.mts +1 -1
- package/dist/utilities/window-focus.mjs +1 -1
- package/dist/utilities/window-size.d.mts +1 -1
- package/dist/utilities/window-size.mjs +1 -1
- package/package.json +20 -5
- package/dist/benchmark.CX_oY03V-CSLAXL5f.mjs +0 -5145
- package/dist/magic-string.es-CXefOmkB.mjs +0 -1011
- package/dist/test.BmQO5GaM-Ddz9cDxc.mjs +0 -8266
- package/dist/utilities/active-element.test.d.mts +0 -1
- package/dist/utilities/active-element.test.mjs +0 -25
- package/dist/utilities/async.test.d.mts +0 -1
- package/dist/utilities/async.test.mjs +0 -275
- package/dist/utilities/context.test.d.mts +0 -1
- package/dist/utilities/context.test.mjs +0 -171
- package/dist/utilities/debounced.test.d.mts +0 -1
- package/dist/utilities/debounced.test.mjs +0 -68
- package/dist/utilities/dom-lifecycle.test.d.mts +0 -1
- package/dist/utilities/dom-lifecycle.test.mjs +0 -228
- package/dist/utilities/element-rect.test.d.mts +0 -1
- package/dist/utilities/element-rect.test.mjs +0 -101
- package/dist/utilities/element-scroll.test.d.mts +0 -1
- package/dist/utilities/element-scroll.test.mjs +0 -27
- package/dist/utilities/event-listener.test.d.mts +0 -1
- package/dist/utilities/event-listener.test.mjs +0 -60
- package/dist/utilities/focus-within.test.d.mts +0 -1
- package/dist/utilities/focus-within.test.mjs +0 -51
- package/dist/utilities/hover.test.d.mts +0 -1
- package/dist/utilities/hover.test.mjs +0 -54
- package/dist/utilities/intersection-observer.test.d.mts +0 -1
- package/dist/utilities/intersection-observer.test.mjs +0 -46
- package/dist/utilities/interval.test.d.mts +0 -1
- package/dist/utilities/interval.test.mjs +0 -115
- package/dist/utilities/location.test.d.mts +0 -1
- package/dist/utilities/location.test.mjs +0 -61
- package/dist/utilities/long-press.test.d.mts +0 -1
- package/dist/utilities/long-press.test.mjs +0 -54
- package/dist/utilities/media-devices.test.d.mts +0 -1
- package/dist/utilities/media-devices.test.mjs +0 -44
- package/dist/utilities/media-player.test.d.mts +0 -1
- package/dist/utilities/media-player.test.mjs +0 -102
- package/dist/utilities/mutation-observer.test.d.mts +0 -1
- package/dist/utilities/mutation-observer.test.mjs +0 -48
- package/dist/utilities/network.test.d.mts +0 -1
- package/dist/utilities/network.test.mjs +0 -30
- package/dist/utilities/on-click-outside.test.d.mts +0 -1
- package/dist/utilities/on-click-outside.test.mjs +0 -45
- package/dist/utilities/previous.test.d.mts +0 -1
- package/dist/utilities/previous.test.mjs +0 -90
- package/dist/utilities/promise.test.d.mts +0 -1
- package/dist/utilities/promise.test.mjs +0 -158
- package/dist/utilities/retry.test.d.mts +0 -1
- package/dist/utilities/retry.test.mjs +0 -85
- package/dist/utilities/routing.test.d.mts +0 -1
- package/dist/utilities/routing.test.mjs +0 -129
- package/dist/utilities/search-params.test.d.mts +0 -1
- package/dist/utilities/search-params.test.mjs +0 -37
- package/dist/utilities/ssr.test.d.mts +0 -1
- package/dist/utilities/ssr.test.mjs +0 -65
- package/dist/utilities/storage.test.d.mts +0 -1
- package/dist/utilities/storage.test.mjs +0 -139
- package/dist/utilities/throttled.test.d.mts +0 -1
- package/dist/utilities/throttled.test.mjs +0 -58
- package/dist/utilities/timeout.test.d.mts +0 -1
- package/dist/utilities/timeout.test.mjs +0 -121
- package/dist/utilities/window-size.test.d.mts +0 -1
- package/dist/utilities/window-size.test.mjs +0 -43
- /package/dist/{custom-elements-D5CgfNKc.d.mts → custom-elements-DK5VUcWA.d.mts} +0 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { C as untracked, _ as onCleanup, d as effectScope, n as CLAIM, t as ASYNC_REGION, u as effect, v as setDeferAsyncRuns } from "./lib-DYypKhxk.mjs";
|
|
2
|
+
import { isReactive, resolveProps } from "./signals/index.mjs";
|
|
3
|
+
import { isReactivePromiseLike } from "./utilities/promise.mjs";
|
|
4
|
+
import { flushDeferredAsyncRuns, isAsyncLike } from "./utilities/async.mjs";
|
|
5
|
+
import { i as applyProps, o as resolveChild, r as setRenderer, t as createElement } from "./element-D3om9yA6.mjs";
|
|
6
|
+
import { n as Slot } from "./slot-Dvf30O0B.mjs";
|
|
7
|
+
import { For, isForComponent } from "./for.mjs";
|
|
8
|
+
import { n as isFragmentComponent, r as parseHtml, t as Fragment } from "./fragment-ROPRBJQd.mjs";
|
|
9
|
+
//#region src/hydrate/claim.ts
|
|
10
|
+
let hydrationContext = null;
|
|
11
|
+
function setHydrationContext(ctx) {
|
|
12
|
+
const prev = hydrationContext;
|
|
13
|
+
hydrationContext = ctx;
|
|
14
|
+
return prev;
|
|
15
|
+
}
|
|
16
|
+
const VNODE = Symbol.for("elements-kit.vnode");
|
|
17
|
+
function isVNode(value) {
|
|
18
|
+
return typeof value === "object" && value !== null && VNODE in value;
|
|
19
|
+
}
|
|
20
|
+
const claimRenderer = { jsx(type, props) {
|
|
21
|
+
if (typeof type === "string") return {
|
|
22
|
+
[VNODE]: true,
|
|
23
|
+
kind: "el",
|
|
24
|
+
tag: type,
|
|
25
|
+
props
|
|
26
|
+
};
|
|
27
|
+
if (isFragmentComponent(type)) return {
|
|
28
|
+
[VNODE]: true,
|
|
29
|
+
kind: "frag",
|
|
30
|
+
children: props.children,
|
|
31
|
+
html: props.html === true
|
|
32
|
+
};
|
|
33
|
+
if (isForComponent(type)) return {
|
|
34
|
+
[VNODE]: true,
|
|
35
|
+
kind: "for",
|
|
36
|
+
props
|
|
37
|
+
};
|
|
38
|
+
if (typeof type === "function" && !type.prototype?.render) return type(resolveProps(props));
|
|
39
|
+
const name = typeof type === "function" ? type.name ?? "anonymous" : String(type);
|
|
40
|
+
throw new Error(`Hydration does not support class components ("${name}"); v1 supports intrinsic elements, function components, Fragment and For.`);
|
|
41
|
+
} };
|
|
42
|
+
function withClaimRenderer(fn) {
|
|
43
|
+
setRenderer(claimRenderer);
|
|
44
|
+
try {
|
|
45
|
+
return fn();
|
|
46
|
+
} finally {
|
|
47
|
+
setRenderer(null);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Claim `container`'s existing children against the evaluated tree. */
|
|
51
|
+
function claimChildren(container, root, onMismatch) {
|
|
52
|
+
walkList({
|
|
53
|
+
node: container.firstChild,
|
|
54
|
+
parent: container
|
|
55
|
+
}, root, onMismatch);
|
|
56
|
+
}
|
|
57
|
+
function walkList(cur, raw, om) {
|
|
58
|
+
if (raw == null || typeof raw === "boolean") return;
|
|
59
|
+
if (Array.isArray(raw)) {
|
|
60
|
+
for (const c of raw.flat(Infinity)) walkChild(cur, c, om);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
walkChild(cur, raw, om);
|
|
64
|
+
}
|
|
65
|
+
function walkChild(cur, c, om) {
|
|
66
|
+
if (c == null || typeof c === "boolean") return;
|
|
67
|
+
if (isVNode(c)) {
|
|
68
|
+
if (c.kind === "frag") {
|
|
69
|
+
if (c.html) return claimRawRegion(cur, c.children, om);
|
|
70
|
+
return walkList(cur, c.children, om);
|
|
71
|
+
}
|
|
72
|
+
if (c.kind === "for") return claimFor(cur, c, om);
|
|
73
|
+
return claimElement(cur, c, om);
|
|
74
|
+
}
|
|
75
|
+
if (isReactivePromiseLike(c) || isAsyncLike(c)) return claimAsync(cur, c, om);
|
|
76
|
+
if (typeof c === "function") return claimDynamic(cur, c, om);
|
|
77
|
+
if (c instanceof Node) return fallback(cur, om, c.nodeName, () => c);
|
|
78
|
+
claimText(cur, String(c), om);
|
|
79
|
+
}
|
|
80
|
+
function claimText(cur, text, om) {
|
|
81
|
+
if (text === "") return;
|
|
82
|
+
const node = cur.node;
|
|
83
|
+
if (node && node.nodeType === Node.TEXT_NODE) {
|
|
84
|
+
const data = node.data;
|
|
85
|
+
if (data === text) {
|
|
86
|
+
cur.node = node.nextSibling;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (data.startsWith(text)) {
|
|
90
|
+
node.splitText(text.length);
|
|
91
|
+
cur.node = node.nextSibling;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
fallback(cur, om, text, () => document.createTextNode(text));
|
|
96
|
+
}
|
|
97
|
+
function claimElement(cur, v, om) {
|
|
98
|
+
const node = cur.node;
|
|
99
|
+
if (!(node !== null && node.nodeType === Node.ELEMENT_NODE && node.localName.toLowerCase() === v.tag.toLowerCase())) {
|
|
100
|
+
fallback(cur, om, `<${v.tag}>`, () => buildVNode(v));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const el = node;
|
|
104
|
+
const { ref, children, live } = splitProps(v.props);
|
|
105
|
+
if (live) applyProps(el, live);
|
|
106
|
+
claimChildren(el, children, om);
|
|
107
|
+
if (typeof ref === "function") ref(el);
|
|
108
|
+
cur.node = el.nextSibling;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Split claimed-element props: static values are already in the server HTML
|
|
112
|
+
* and are skipped; `on:` handlers, reactive values and `prop:` assignments
|
|
113
|
+
* still need to run — they route through the normal `applyProps` path.
|
|
114
|
+
*/
|
|
115
|
+
function splitProps(props) {
|
|
116
|
+
let ref;
|
|
117
|
+
let children;
|
|
118
|
+
let live = null;
|
|
119
|
+
for (const [key, value] of Object.entries(props)) {
|
|
120
|
+
if (key === "children") {
|
|
121
|
+
children = value;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (key === "ref") {
|
|
125
|
+
ref = value;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (key === "innerHTML") throw new Error("innerHTML is not supported in hydration — there is no raw HTML sink.");
|
|
129
|
+
const colonIdx = key.indexOf(":");
|
|
130
|
+
const ns = colonIdx > 0 ? key.slice(0, colonIdx) : "";
|
|
131
|
+
if (ns === "on" || ns === "prop" || isReactive(value)) (live ??= {})[key] = value;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
ref,
|
|
135
|
+
children,
|
|
136
|
+
live
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function claimDynamic(cur, getter, om) {
|
|
140
|
+
const region = getter[ASYNC_REGION];
|
|
141
|
+
const claimed = cur.node?.nodeType === Node.COMMENT_NODE && cur.node.data === "{";
|
|
142
|
+
if (region && hydrationContext) hydrationContext.counter += region.ids;
|
|
143
|
+
const slot = claimSlot(cur, om);
|
|
144
|
+
const keepWhilePending = Boolean(region) && claimed;
|
|
145
|
+
effect(() => {
|
|
146
|
+
const value = getter();
|
|
147
|
+
if (keepWhilePending && region.pending()) return;
|
|
148
|
+
slot.set(resolveChild(value));
|
|
149
|
+
});
|
|
150
|
+
onCleanup(() => slot.clear());
|
|
151
|
+
}
|
|
152
|
+
function claimAsync(cur, p, om) {
|
|
153
|
+
const ctx = hydrationContext;
|
|
154
|
+
if (ctx) {
|
|
155
|
+
const record = ctx.data?.[String(ctx.counter++)];
|
|
156
|
+
const claim = p[CLAIM];
|
|
157
|
+
claim?.(record);
|
|
158
|
+
}
|
|
159
|
+
const slot = claimSlot(cur, om);
|
|
160
|
+
effect(() => {
|
|
161
|
+
if (p.state === "pending") return;
|
|
162
|
+
slot.set(resolveChild(p.result));
|
|
163
|
+
});
|
|
164
|
+
onCleanup(() => slot.clear());
|
|
165
|
+
}
|
|
166
|
+
function claimSlot(cur, om) {
|
|
167
|
+
const range = claimMarkerRange(cur, "{", "}");
|
|
168
|
+
if (range) return Slot.claim(range.start, range.end);
|
|
169
|
+
om?.({
|
|
170
|
+
expected: "<!--{-->",
|
|
171
|
+
found: cur.node
|
|
172
|
+
});
|
|
173
|
+
const slot = new Slot();
|
|
174
|
+
cur.parent.insertBefore(slot.render(), cur.node);
|
|
175
|
+
return slot;
|
|
176
|
+
}
|
|
177
|
+
function claimMarkerRange(cur, open, close) {
|
|
178
|
+
const start = cur.node;
|
|
179
|
+
if (!start || start.nodeType !== Node.COMMENT_NODE || start.data !== open) return null;
|
|
180
|
+
let depth = 0;
|
|
181
|
+
let node = start;
|
|
182
|
+
while (node) {
|
|
183
|
+
if (node.nodeType === Node.COMMENT_NODE) {
|
|
184
|
+
const data = node.data;
|
|
185
|
+
if (data === open) depth++;
|
|
186
|
+
else if (data === close && --depth === 0) {
|
|
187
|
+
cur.node = node.nextSibling;
|
|
188
|
+
return {
|
|
189
|
+
start,
|
|
190
|
+
end: node
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
node = node.nextSibling;
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
/** `<Fragment html>` region: adopt the server markup between the markers. */
|
|
199
|
+
function claimRawRegion(cur, source, om) {
|
|
200
|
+
const claimed = cur.node?.nodeType === Node.COMMENT_NODE && cur.node.data === "{";
|
|
201
|
+
const slot = claimSlot(cur, om);
|
|
202
|
+
if (typeof source !== "function") {
|
|
203
|
+
if (!claimed && source != null) slot.set(parseHtml(String(source)));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
let first = claimed;
|
|
207
|
+
effect(() => {
|
|
208
|
+
const value = source();
|
|
209
|
+
if (first) {
|
|
210
|
+
first = false;
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
slot.set(parseHtml(value == null ? "" : String(value)));
|
|
214
|
+
});
|
|
215
|
+
onCleanup(() => slot.clear());
|
|
216
|
+
}
|
|
217
|
+
function claimFor(cur, v, om) {
|
|
218
|
+
const inst = new For();
|
|
219
|
+
applyProps(inst, v.props);
|
|
220
|
+
const range = claimMarkerRange(cur, "<For>", "</For>");
|
|
221
|
+
if (!range) {
|
|
222
|
+
om?.({
|
|
223
|
+
expected: "<!--<For>-->",
|
|
224
|
+
found: cur.node
|
|
225
|
+
});
|
|
226
|
+
cur.parent.insertBefore(inst.render(), cur.node);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const items = untracked(() => inst.each);
|
|
230
|
+
const entries = /* @__PURE__ */ new Map();
|
|
231
|
+
const order = [];
|
|
232
|
+
let node = range.start.nextSibling;
|
|
233
|
+
let index = 0;
|
|
234
|
+
while (node && node !== range.end && index < items.length) {
|
|
235
|
+
if (node.nodeType === Node.COMMENT_NODE && /^\[(?!\/)/.test(node.data)) {
|
|
236
|
+
const startC = node;
|
|
237
|
+
const keyStr = startC.data.slice(1, -1);
|
|
238
|
+
const endC = findEntryEnd(startC, range.end, keyStr);
|
|
239
|
+
if (!endC) break;
|
|
240
|
+
const item = items[index];
|
|
241
|
+
const key = inst.by(item, index);
|
|
242
|
+
if (encodeURIComponent(String(key)) !== keyStr) break;
|
|
243
|
+
let dispose;
|
|
244
|
+
untracked(() => {
|
|
245
|
+
dispose = effectScope(() => {
|
|
246
|
+
const rendered = withClaimRenderer(() => inst.children(item, index));
|
|
247
|
+
walkList({
|
|
248
|
+
node: startC.nextSibling,
|
|
249
|
+
parent: startC.parentNode
|
|
250
|
+
}, rendered, om);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
entries.set(key, {
|
|
254
|
+
start: startC,
|
|
255
|
+
end: endC,
|
|
256
|
+
dispose
|
|
257
|
+
});
|
|
258
|
+
order.push(key);
|
|
259
|
+
index++;
|
|
260
|
+
node = endC.nextSibling;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
node = node.nextSibling;
|
|
264
|
+
}
|
|
265
|
+
const keep = /* @__PURE__ */ new Set();
|
|
266
|
+
for (const entry of entries.values()) {
|
|
267
|
+
let kept = entry.start;
|
|
268
|
+
while (kept) {
|
|
269
|
+
keep.add(kept);
|
|
270
|
+
if (kept === entry.end) break;
|
|
271
|
+
kept = kept.nextSibling;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
let stray = range.start.nextSibling;
|
|
275
|
+
while (stray && stray !== range.end) {
|
|
276
|
+
const next = stray.nextSibling;
|
|
277
|
+
if (!keep.has(stray)) stray.remove();
|
|
278
|
+
stray = next;
|
|
279
|
+
}
|
|
280
|
+
inst.hydrateRange(range.start, range.end, entries, order);
|
|
281
|
+
}
|
|
282
|
+
function findEntryEnd(start, boundary, key) {
|
|
283
|
+
let node = start.nextSibling;
|
|
284
|
+
while (node && node !== boundary) {
|
|
285
|
+
if (node.nodeType === Node.COMMENT_NODE && node.data === `[/${key}]`) return node;
|
|
286
|
+
node = node.nextSibling;
|
|
287
|
+
}
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
function fallback(cur, om, expected, build) {
|
|
291
|
+
om?.({
|
|
292
|
+
expected,
|
|
293
|
+
found: cur.node
|
|
294
|
+
});
|
|
295
|
+
const stale = cur.node;
|
|
296
|
+
const fresh = build();
|
|
297
|
+
cur.parent.insertBefore(fresh, stale);
|
|
298
|
+
if (stale) {
|
|
299
|
+
cur.node = stale.nextSibling;
|
|
300
|
+
cur.parent.removeChild(stale);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function buildVNode(v) {
|
|
304
|
+
if (v.kind === "el") {
|
|
305
|
+
const props = { ...v.props };
|
|
306
|
+
if ("children" in props) props.children = buildChildValue(props.children);
|
|
307
|
+
return createElement(v.tag, props);
|
|
308
|
+
}
|
|
309
|
+
if (v.kind === "frag") return Fragment({ children: (() => buildChildValue(v.children)) });
|
|
310
|
+
return createElement(For, v.props);
|
|
311
|
+
}
|
|
312
|
+
function buildChildValue(c) {
|
|
313
|
+
if (Array.isArray(c)) return c.map(buildChildValue);
|
|
314
|
+
if (isVNode(c)) return buildVNode(c);
|
|
315
|
+
return c;
|
|
316
|
+
}
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/hydrate/index.ts
|
|
319
|
+
/**
|
|
320
|
+
* Make server-rendered HTML interactive by re-executing the component tree
|
|
321
|
+
* in claim mode: existing DOM nodes are adopted instead of rebuilt, `on:`
|
|
322
|
+
* handlers attach to the claimed nodes, and dynamic children bind live to
|
|
323
|
+
* the server-emitted slot markers.
|
|
324
|
+
*
|
|
325
|
+
* The component code runs once on the client (closures are recreated by
|
|
326
|
+
* re-execution — no serialized handlers). Async children keep their
|
|
327
|
+
* server-rendered content visible until the client-side value settles.
|
|
328
|
+
*
|
|
329
|
+
* Server/client trees must match; on mismatch the affected subtree is
|
|
330
|
+
* rendered fresh and `options.onMismatch` is invoked.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```tsx
|
|
334
|
+
* const { dispose } = hydrate(document.getElementById("app")!, () => <App />);
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
function hydrate(container, app, options = {}) {
|
|
338
|
+
const data = readHydrationData(container);
|
|
339
|
+
let dispose;
|
|
340
|
+
untracked(() => {
|
|
341
|
+
dispose = effectScope(() => {
|
|
342
|
+
setRenderer(claimRenderer);
|
|
343
|
+
const prevDefer = setDeferAsyncRuns(true);
|
|
344
|
+
let root;
|
|
345
|
+
try {
|
|
346
|
+
root = app();
|
|
347
|
+
} finally {
|
|
348
|
+
setRenderer(null);
|
|
349
|
+
setDeferAsyncRuns(prevDefer);
|
|
350
|
+
}
|
|
351
|
+
const prevCtx = setHydrationContext({
|
|
352
|
+
counter: 0,
|
|
353
|
+
data
|
|
354
|
+
});
|
|
355
|
+
try {
|
|
356
|
+
claimChildren(container, root, options.onMismatch);
|
|
357
|
+
} finally {
|
|
358
|
+
setHydrationContext(prevCtx);
|
|
359
|
+
flushDeferredAsyncRuns();
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
return { dispose };
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Locate and parse the server's ek-data script. Malformed or absent data
|
|
367
|
+
* degrades to no seeding — async values settle through their own client
|
|
368
|
+
* execution instead.
|
|
369
|
+
*/
|
|
370
|
+
function readHydrationData(container) {
|
|
371
|
+
const script = container.querySelector("script[type=\"application/json\"]#ek-data") ?? container.ownerDocument?.getElementById("ek-data");
|
|
372
|
+
if (!script?.textContent) return null;
|
|
373
|
+
try {
|
|
374
|
+
return JSON.parse(script.textContent);
|
|
375
|
+
} catch {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
//#endregion
|
|
380
|
+
export { hydrate as t };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/integrations/astro-client.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Astro client entrypoint: hydrate an elements-kit island.
|
|
4
|
+
*
|
|
5
|
+
* Astro calls this as `hydrator(element)(Component, props, slots, { client })`
|
|
6
|
+
* once the island's client directive fires. `client:only` mounts fresh via
|
|
7
|
+
* `render`; every other directive adopts the server DOM via `hydrate` —
|
|
8
|
+
* handlers attach to existing nodes, nothing is rebuilt. The island's
|
|
9
|
+
* `astro:unmount` event tears everything down.
|
|
10
|
+
*/
|
|
11
|
+
declare const _default: (element: HTMLElement) => (Component: unknown, props: Record<string, unknown>, slots: Record<string, string>, {
|
|
12
|
+
client
|
|
13
|
+
}: {
|
|
14
|
+
client: string;
|
|
15
|
+
}) => Promise<void>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { _default as default };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { t as createElement } from "../element-D3om9yA6.mjs";
|
|
2
|
+
import { render } from "../render.mjs";
|
|
3
|
+
import { t as hydrate } from "../hydrate-6Qx4n4Su.mjs";
|
|
4
|
+
import { withSlotProps } from "./astro-slots.mjs";
|
|
5
|
+
//#region src/integrations/astro-client.ts
|
|
6
|
+
/**
|
|
7
|
+
* Astro client entrypoint: hydrate an elements-kit island.
|
|
8
|
+
*
|
|
9
|
+
* Astro calls this as `hydrator(element)(Component, props, slots, { client })`
|
|
10
|
+
* once the island's client directive fires. `client:only` mounts fresh via
|
|
11
|
+
* `render`; every other directive adopts the server DOM via `hydrate` —
|
|
12
|
+
* handlers attach to existing nodes, nothing is rebuilt. The island's
|
|
13
|
+
* `astro:unmount` event tears everything down.
|
|
14
|
+
*/
|
|
15
|
+
var astro_client_default = (element) => async (Component, props, slots, { client }) => {
|
|
16
|
+
if (!element.hasAttribute("ssr")) return;
|
|
17
|
+
const merged = withSlotProps(props, slots);
|
|
18
|
+
const app = () => createElement(Component, merged);
|
|
19
|
+
const dispose = client === "only" ? render(element, app) : hydrate(element, app).dispose;
|
|
20
|
+
element.addEventListener("astro:unmount", () => dispose(), { once: true });
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { astro_client_default as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/integrations/astro-server.d.ts
|
|
2
|
+
type RendererFn<T> = (Component: unknown, props: Record<string, unknown> | null | undefined, slots: Record<string, string>, metadata?: {
|
|
3
|
+
astroStaticSlot?: boolean;
|
|
4
|
+
}) => Promise<T>;
|
|
5
|
+
interface ElementsKitSSRRenderer {
|
|
6
|
+
name: string;
|
|
7
|
+
check: RendererFn<boolean>;
|
|
8
|
+
renderToStaticMarkup: RendererFn<{
|
|
9
|
+
html: string;
|
|
10
|
+
}>;
|
|
11
|
+
supportsAstroStaticSlot: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare const renderer: ElementsKitSSRRenderer;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { renderer as default };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { y as setInertEffects } from "../lib-DYypKhxk.mjs";
|
|
2
|
+
import { resolveProps } from "../signals/index.mjs";
|
|
3
|
+
import { r as setRenderer, t as createElement } from "../element-D3om9yA6.mjs";
|
|
4
|
+
import { withSlotProps } from "./astro-slots.mjs";
|
|
5
|
+
import { i as serverJsx, n as renderToString, r as SNode } from "../server-iFSng50i.mjs";
|
|
6
|
+
//#region src/integrations/astro-server.ts
|
|
7
|
+
/**
|
|
8
|
+
* Decide whether `Component` is an elements-kit component. Invoked by Astro
|
|
9
|
+
* for every candidate renderer, so this must reject foreign components: the
|
|
10
|
+
* component body runs under the server renderer, and only elements-kit JSX
|
|
11
|
+
* dispatches to it — the result is an `SNode`. A React component returns a
|
|
12
|
+
* React element object (never `SNode`); components that throw (hooks outside
|
|
13
|
+
* their framework, class components) are rejected by the catch.
|
|
14
|
+
*/
|
|
15
|
+
const check = async (Component, props) => {
|
|
16
|
+
if (typeof Component !== "function") return false;
|
|
17
|
+
const prevInert = setInertEffects(true);
|
|
18
|
+
setRenderer({ jsx: serverJsx });
|
|
19
|
+
try {
|
|
20
|
+
return Component(resolveProps(props ?? {})) instanceof SNode;
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
} finally {
|
|
24
|
+
setRenderer(null);
|
|
25
|
+
setInertEffects(prevInert);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const renderToStaticMarkup = async (Component, props, slots, metadata) => {
|
|
29
|
+
const merged = withSlotProps(props, slots, metadata?.astroStaticSlot === true);
|
|
30
|
+
return { html: await renderToString(() => createElement(Component, merged)) };
|
|
31
|
+
};
|
|
32
|
+
const renderer = {
|
|
33
|
+
name: "elements-kit",
|
|
34
|
+
check,
|
|
35
|
+
renderToStaticMarkup,
|
|
36
|
+
supportsAstroStaticSlot: true
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { renderer as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/integrations/astro-slots.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* @internal Map Astro's pre-rendered slot HTML (`Record<name, html>`) into
|
|
4
|
+
* elements-kit props: the `default` slot becomes `children`, named slots
|
|
5
|
+
* become `slot:<name>` props. Each value is a thunk building Astro's slot
|
|
6
|
+
* wrapper element around a `<Fragment html>` region — deferred so the jsx
|
|
7
|
+
* dispatches to whichever renderer is active when the component reads the
|
|
8
|
+
* prop (string emission on the server, DOM on the client).
|
|
9
|
+
*/
|
|
10
|
+
declare function withSlotProps(props: Record<string, unknown> | null | undefined, slots: Record<string, string> | null | undefined, staticSlot?: boolean): Record<string, unknown>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { withSlotProps };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { t as createElement } from "../element-D3om9yA6.mjs";
|
|
2
|
+
import { t as Fragment } from "../fragment-ROPRBJQd.mjs";
|
|
3
|
+
//#region src/integrations/astro-slots.ts
|
|
4
|
+
/**
|
|
5
|
+
* @internal Map Astro's pre-rendered slot HTML (`Record<name, html>`) into
|
|
6
|
+
* elements-kit props: the `default` slot becomes `children`, named slots
|
|
7
|
+
* become `slot:<name>` props. Each value is a thunk building Astro's slot
|
|
8
|
+
* wrapper element around a `<Fragment html>` region — deferred so the jsx
|
|
9
|
+
* dispatches to whichever renderer is active when the component reads the
|
|
10
|
+
* prop (string emission on the server, DOM on the client).
|
|
11
|
+
*/
|
|
12
|
+
function withSlotProps(props, slots, staticSlot = false) {
|
|
13
|
+
const base = { ...props ?? {} };
|
|
14
|
+
if (!slots) return base;
|
|
15
|
+
const tag = staticSlot ? "astro-static-slot" : "astro-slot";
|
|
16
|
+
for (const [name, html] of Object.entries(slots)) {
|
|
17
|
+
const slot = () => createElement(tag, {
|
|
18
|
+
...name === "default" ? {} : { name },
|
|
19
|
+
children: createElement(Fragment, {
|
|
20
|
+
html: true,
|
|
21
|
+
children: html
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
if (name === "default") base.children = slot;
|
|
25
|
+
else base[`slot:${name}`] = slot;
|
|
26
|
+
}
|
|
27
|
+
return base;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { withSlotProps };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/integrations/astro.d.ts
|
|
2
|
+
interface AstroRendererConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
clientEntrypoint: string;
|
|
5
|
+
serverEntrypoint: string;
|
|
6
|
+
}
|
|
7
|
+
interface AstroConfigSetupApi {
|
|
8
|
+
addRenderer(renderer: AstroRendererConfig): void;
|
|
9
|
+
updateConfig(config: Record<string, unknown>): unknown;
|
|
10
|
+
}
|
|
11
|
+
interface ElementsKitAstroIntegration {
|
|
12
|
+
name: string;
|
|
13
|
+
hooks: {
|
|
14
|
+
"astro:config:setup": (api: AstroConfigSetupApi) => void;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Astro integration: use elements-kit components as Astro islands.
|
|
19
|
+
*
|
|
20
|
+
* Registers the elements-kit renderer pair — server rendering via
|
|
21
|
+
* `elements-kit/server`, client hydration via `elements-kit/hydrate` — and
|
|
22
|
+
* points Vite's JSX transform at `elements-kit`, so `.tsx` island components
|
|
23
|
+
* need no per-file pragma.
|
|
24
|
+
*
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <Counter client:load /> // server-rendered, hydrated on load
|
|
27
|
+
* <Widget client:only="elements-kit" /> // client-rendered only
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Coexists with other framework renderers (React, etc.); scope their JSX
|
|
31
|
+
* transform with the framework integration's `include` option.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* // astro.config.mjs
|
|
36
|
+
* import { defineConfig } from "astro/config";
|
|
37
|
+
* import elementsKit from "elements-kit/integrations/astro";
|
|
38
|
+
*
|
|
39
|
+
* export default defineConfig({
|
|
40
|
+
* integrations: [elementsKit()],
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function elementsKit(): ElementsKitAstroIntegration;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { ElementsKitAstroIntegration, elementsKit as default };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
//#region src/integrations/astro.ts
|
|
2
|
+
/**
|
|
3
|
+
* Astro integration: use elements-kit components as Astro islands.
|
|
4
|
+
*
|
|
5
|
+
* Registers the elements-kit renderer pair — server rendering via
|
|
6
|
+
* `elements-kit/server`, client hydration via `elements-kit/hydrate` — and
|
|
7
|
+
* points Vite's JSX transform at `elements-kit`, so `.tsx` island components
|
|
8
|
+
* need no per-file pragma.
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Counter client:load /> // server-rendered, hydrated on load
|
|
12
|
+
* <Widget client:only="elements-kit" /> // client-rendered only
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Coexists with other framework renderers (React, etc.); scope their JSX
|
|
16
|
+
* transform with the framework integration's `include` option.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* // astro.config.mjs
|
|
21
|
+
* import { defineConfig } from "astro/config";
|
|
22
|
+
* import elementsKit from "elements-kit/integrations/astro";
|
|
23
|
+
*
|
|
24
|
+
* export default defineConfig({
|
|
25
|
+
* integrations: [elementsKit()],
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function elementsKit() {
|
|
30
|
+
return {
|
|
31
|
+
name: "elements-kit",
|
|
32
|
+
hooks: { "astro:config:setup": ({ addRenderer, updateConfig }) => {
|
|
33
|
+
addRenderer({
|
|
34
|
+
name: "elements-kit",
|
|
35
|
+
clientEntrypoint: "elements-kit/integrations/astro-client",
|
|
36
|
+
serverEntrypoint: "elements-kit/integrations/astro-server"
|
|
37
|
+
});
|
|
38
|
+
updateConfig({ vite: {
|
|
39
|
+
esbuild: {
|
|
40
|
+
jsx: "automatic",
|
|
41
|
+
jsxImportSource: "elements-kit"
|
|
42
|
+
},
|
|
43
|
+
optimizeDeps: { include: [
|
|
44
|
+
"elements-kit",
|
|
45
|
+
"elements-kit/jsx-runtime",
|
|
46
|
+
"elements-kit/jsx-dev-runtime",
|
|
47
|
+
"elements-kit/signals",
|
|
48
|
+
"elements-kit/for",
|
|
49
|
+
"elements-kit/slot",
|
|
50
|
+
"elements-kit/render",
|
|
51
|
+
"elements-kit/hydrate",
|
|
52
|
+
"elements-kit/await",
|
|
53
|
+
"elements-kit/custom-elements",
|
|
54
|
+
"elements-kit/attributes",
|
|
55
|
+
"elements-kit/integrations/astro-client",
|
|
56
|
+
"elements-kit/utilities/*"
|
|
57
|
+
] },
|
|
58
|
+
resolve: { dedupe: ["elements-kit"] }
|
|
59
|
+
} });
|
|
60
|
+
} }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { elementsKit as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { u as effect, x as signal } from "../lib-DYypKhxk.mjs";
|
|
2
2
|
import "../signals/index.mjs";
|
|
3
|
-
import { t as scope } from "../scope-
|
|
3
|
+
import { t as scope } from "../scope-zbEG299F.mjs";
|
|
4
4
|
import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
|
|
5
5
|
//#region src/integrations/react.ts
|
|
6
6
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { G as createElement, _ as Require, a as ComponentInstance, b as MaybeReactive, c as JSX, d as ComponentProps, f as ElementProps, g as ReactiveProps, h as RawProps, i as ComponentFn, l as SlotProps, m as Props, n as Component, o as PropsTarget, p as MaybeReactiveProps, r as ComponentClass, s as Attrs, t as Child, u as Fragment, v as ResolveProps } from "../types-ncUK9rki.mjs";
|
|
2
2
|
export { Attrs, type Child, type Component, type ComponentClass, type ComponentFn, type ComponentInstance, type ComponentProps, type ElementProps, Fragment, JSX, type MaybeReactive, type MaybeReactiveProps, type Props, type PropsTarget, type RawProps, type ReactiveProps, type Require, type ResolveProps, SlotProps, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Used by the JSX transform for `<>...</>` fragments.
|
|
5
|
-
*
|
|
6
|
-
* Each child is routed through `mountChild`, which handles Nodes, strings,
|
|
7
|
-
* numbers, arrays, and reactive getters — matching the behavior of any other
|
|
8
|
-
* JSX container. `mountChild` also wires each child's cleanup via its own
|
|
9
|
-
* `effectScope`, which links to the enclosing `effectScope` created by
|
|
10
|
-
* `createElement(Fragment, ...)` for disposal propagation.
|
|
11
|
-
*/
|
|
12
|
-
function Fragment(props) {
|
|
13
|
-
const fragment = document.createDocumentFragment();
|
|
14
|
-
const raw = props.children?.();
|
|
15
|
-
if (raw == null) return fragment;
|
|
16
|
-
const nodes = Array.isArray(raw) ? raw.flat(Infinity) : [raw];
|
|
17
|
-
for (const child of nodes) mountChild(fragment, child);
|
|
18
|
-
return fragment;
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
1
|
+
import { t as createElement } from "../element-D3om9yA6.mjs";
|
|
2
|
+
import { t as Fragment } from "../fragment-ROPRBJQd.mjs";
|
|
21
3
|
export { Fragment, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
|