@voltro/web 0.51.0 → 0.53.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/CHANGELOG.md +356 -0
- package/THIRD-PARTY-NOTICES.md +281 -1
- package/dist/{defaultFallbacks-B4Ak-R6R.js → defaultFallbacks-SQ45vAhz.js} +1 -1
- package/dist/{frameworkBoot-CV_o2tIk.js → frameworkBoot-CnE9vzLQ.js} +2 -2
- package/dist/frameworkBoot.js +1 -1
- package/dist/globalContext-AuflFFmy.js +2 -0
- package/dist/hooks.js +1 -1
- package/dist/index.d.ts +247 -36
- package/dist/index.js +183 -72
- package/dist/islands.d.ts +66 -0
- package/dist/islands.js +60 -0
- package/dist/mount.js +37 -2
- package/dist/{routerState-DAT472IC.js → routerState-Cr6fTbka.js} +4 -2
- package/dist/serverContext-BwzZ6Q7d.js +1148 -0
- package/dist/ssr.d.ts +35 -10
- package/dist/ssr.js +47 -46
- package/package.json +9 -4
- package/dist/globalContext-d4A-ugDg.js +0 -10
- package/dist/mount-nudb4UCl.js +0 -81
- package/dist/serverContext-38JTbYPa.js +0 -840
package/dist/index.js
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
|
-
import { t as e } from "./globalContext-
|
|
1
|
+
import { t as e } from "./globalContext-AuflFFmy.js";
|
|
2
2
|
import { AppClientsContext as t, useAppClient as n } from "./hooks.js";
|
|
3
|
-
import { a as r, c as i, i as a, l as o, o as s, r as c, s as l, u } from "./frameworkBoot-
|
|
4
|
-
import { a as d, c as f, i as p, l as m, o as h, u as g } from "./defaultFallbacks-
|
|
5
|
-
import {
|
|
6
|
-
import { c as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
3
|
+
import { a as r, c as i, i as a, l as o, o as s, r as c, s as l, u } from "./frameworkBoot-CnE9vzLQ.js";
|
|
4
|
+
import { a as d, c as f, i as p, l as m, o as h, u as g } from "./defaultFallbacks-SQ45vAhz.js";
|
|
5
|
+
import { getIslandComponent as _, hydrateIslandsOnPage as v, island as y } from "./islands.js";
|
|
6
|
+
import { c as b, d as x, f as S, g as C, l as w, m as T } from "./routerState-Cr6fTbka.js";
|
|
7
|
+
import { mount as E, noticeIslandsShipTheFullBundle as ee } from "./mount.js";
|
|
8
|
+
import { A as te, B as ne, C as re, D as ie, E as ae, F as oe, G as se, H as ce, I as le, K as ue, L as de, M as fe, N as pe, O as me, P as he, R as ge, S as _e, T as ve, U as ye, V as be, W as D, _ as O, a as k, b as A, c as j, d as M, f as N, g as xe, h as Se, i as Ce, j as we, k as Te, l as Ee, m as De, n as Oe, o as ke, p as Ae, q as je, r as Me, s as Ne, t as Pe, u as Fe, v as Ie, w as Le, x as Re, y as ze, z as Be } from "./serverContext-BwzZ6Q7d.js";
|
|
9
|
+
import { Component as Ve, Suspense as He, createElement as P, use as Ue, useCallback as We, useContext as Ge, useEffect as Ke, useSyncExternalStore as qe } from "react";
|
|
10
|
+
import { Fragment as F, jsx as I, jsxs as L } from "react/jsx-runtime";
|
|
10
11
|
export * from "@voltro/client";
|
|
11
12
|
export * from "@voltro/ui";
|
|
12
13
|
//#region src/await.tsx
|
|
13
|
-
var
|
|
14
|
+
var R = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PURE__ */ I(He, {
|
|
14
15
|
fallback: t,
|
|
15
|
-
children: /* @__PURE__ */
|
|
16
|
+
children: /* @__PURE__ */ I(Ye, {
|
|
16
17
|
errorFallback: r,
|
|
17
|
-
children: /* @__PURE__ */
|
|
18
|
+
children: /* @__PURE__ */ I(Je, {
|
|
18
19
|
value: e,
|
|
19
20
|
errorFallback: r ?? null,
|
|
20
21
|
children: n
|
|
21
22
|
})
|
|
22
23
|
})
|
|
23
|
-
}),
|
|
24
|
-
let r =
|
|
25
|
-
return a === void 0 ? /* @__PURE__ */
|
|
26
|
-
},
|
|
24
|
+
}), z = ({ body: e }) => /* @__PURE__ */ I("script", { dangerouslySetInnerHTML: { __html: e } }), Je = ({ value: e, errorFallback: t, children: n }) => {
|
|
25
|
+
let r = Ue(e), i = x(e), a = C(r);
|
|
26
|
+
return a === void 0 ? /* @__PURE__ */ L(F, { children: [i === void 0 ? null : /* @__PURE__ */ I(z, { body: S(i, r) }), n(r)] }) : /* @__PURE__ */ L(F, { children: [i === void 0 ? null : /* @__PURE__ */ I(z, { body: w(i, a) }), t] });
|
|
27
|
+
}, Ye = class extends Ve {
|
|
27
28
|
state = { error: void 0 };
|
|
28
29
|
static getDerivedStateFromError(e) {
|
|
29
30
|
return { error: e };
|
|
@@ -31,7 +32,7 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
31
32
|
render() {
|
|
32
33
|
return this.state.error === void 0 ? this.props.children : this.props.errorFallback ?? null;
|
|
33
34
|
}
|
|
34
|
-
},
|
|
35
|
+
}, Xe = (e) => typeof e == "object" && !!e && typeof e.src == "string", B = ({ src: e }) => e, V = e("imageConfig", { loader: B }), Ze = ({ loader: e, children: t }) => P(V.Provider, { value: { loader: e } }, t), H = [
|
|
35
36
|
640,
|
|
36
37
|
750,
|
|
37
38
|
828,
|
|
@@ -40,8 +41,8 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
40
41
|
1920,
|
|
41
42
|
2048,
|
|
42
43
|
3840
|
|
43
|
-
],
|
|
44
|
-
let i = n !== void 0 && !r ? Array.from(new Set(
|
|
44
|
+
], Qe = (e, t, n, r) => {
|
|
45
|
+
let i = n !== void 0 && !r ? Array.from(new Set(H.filter((e) => e <= n * 2).concat(n))).sort((e, t) => e - t) : [...H];
|
|
45
46
|
return {
|
|
46
47
|
srcSet: i.map((n) => `${e({
|
|
47
48
|
src: t,
|
|
@@ -52,43 +53,153 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
52
53
|
width: i[i.length - 1]
|
|
53
54
|
})
|
|
54
55
|
};
|
|
55
|
-
},
|
|
56
|
-
let
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
}, $e = ({ src: e, alt: t, width: n, height: r, fill: i = !1, sizes: a, priority: o = !1, loader: s, quality: c, placeholder: l, blurDataURL: u, style: d, ...f }) => {
|
|
57
|
+
let p = Ge(V).loader, m = s ?? p, h = c === void 0 ? m : (e) => m({
|
|
58
|
+
...e,
|
|
59
|
+
quality: c
|
|
60
|
+
}), g = Xe(e) ? e : void 0, _ = g === void 0 ? e : g.src, v = n ?? (g !== void 0 && g.width > 0 ? g.width : void 0), y = r ?? (g !== void 0 && g.height > 0 ? g.height : void 0), b = u ?? (g !== void 0 && g.blurDataURL !== "" ? g.blurDataURL : void 0), x = l ?? (b !== void 0 && g !== void 0 ? "blur" : "empty");
|
|
61
|
+
!i && (v === void 0 || y === void 0) && typeof console < "u" && console.warn(`<Image src="${_}"> needs both width and height (or fill) to reserve layout space and avoid CLS.`);
|
|
62
|
+
let { srcSet: S, fallback: C } = g !== void 0 && g.srcSet !== "" ? {
|
|
63
|
+
srcSet: g.srcSet,
|
|
64
|
+
fallback: g.src
|
|
65
|
+
} : Qe(h, _, v, i), w = x === "blur" && b ? {
|
|
66
|
+
backgroundImage: `url(${b})`,
|
|
60
67
|
backgroundSize: "cover",
|
|
61
68
|
backgroundPosition: "center"
|
|
62
|
-
} : {},
|
|
69
|
+
} : {}, T = i ? {
|
|
63
70
|
position: "absolute",
|
|
64
71
|
inset: 0,
|
|
65
72
|
height: "100%",
|
|
66
73
|
width: "100%",
|
|
67
74
|
objectFit: "cover"
|
|
68
|
-
} : {}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
srcSet: m,
|
|
75
|
+
} : {}, E = P("img", {
|
|
76
|
+
src: C,
|
|
77
|
+
srcSet: S === "" ? void 0 : S,
|
|
72
78
|
sizes: a ?? (i ? "100vw" : void 0),
|
|
73
79
|
alt: t,
|
|
74
80
|
...i ? {} : {
|
|
75
|
-
width:
|
|
76
|
-
height:
|
|
81
|
+
width: v,
|
|
82
|
+
height: y
|
|
77
83
|
},
|
|
78
84
|
loading: o ? "eager" : "lazy",
|
|
79
85
|
decoding: "async",
|
|
80
86
|
...o ? { fetchPriority: "high" } : {},
|
|
81
87
|
style: {
|
|
82
|
-
...
|
|
83
|
-
...
|
|
84
|
-
...
|
|
88
|
+
...w,
|
|
89
|
+
...T,
|
|
90
|
+
...d
|
|
85
91
|
},
|
|
86
|
-
...
|
|
92
|
+
...f
|
|
87
93
|
});
|
|
88
|
-
|
|
94
|
+
return g !== void 0 && g.sources.length > 0 ? P("picture", null, ...g.sources.map((e) => P("source", {
|
|
95
|
+
key: e.type,
|
|
96
|
+
type: e.type,
|
|
97
|
+
srcSet: e.srcSet,
|
|
98
|
+
sizes: a ?? (i ? "100vw" : void 0)
|
|
99
|
+
})), E) : E;
|
|
100
|
+
}, et = Symbol.for("@voltro/web/script:registry"), U = () => {
|
|
101
|
+
let e = globalThis;
|
|
102
|
+
return e[et] ??= /* @__PURE__ */ new Map();
|
|
103
|
+
}, tt = () => {
|
|
104
|
+
U().clear();
|
|
105
|
+
}, W = (e, t, n) => {
|
|
106
|
+
e.status = t, e.error = n;
|
|
107
|
+
let r = e.listeners.splice(0);
|
|
108
|
+
for (let e of r) t === "loaded" ? e.onLoad?.() : e.onError?.(n);
|
|
109
|
+
}, G = (e, t) => {
|
|
110
|
+
let n = U(), r = n.get(t);
|
|
111
|
+
if (r !== void 0) {
|
|
112
|
+
if (r.status === "loaded" || r.status === "error") {
|
|
113
|
+
let t = !1;
|
|
114
|
+
return queueMicrotask(() => {
|
|
115
|
+
t || (r.status === "loaded" ? e.onLoad?.() : e.onError?.(r.error));
|
|
116
|
+
}), () => {
|
|
117
|
+
t = !0;
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
let t = {
|
|
121
|
+
onLoad: e.onLoad,
|
|
122
|
+
onError: e.onError
|
|
123
|
+
};
|
|
124
|
+
return r.listeners.push(t), () => {
|
|
125
|
+
let e = r.listeners.indexOf(t);
|
|
126
|
+
e !== -1 && r.listeners.splice(e, 1);
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
let i = {
|
|
130
|
+
status: "loading",
|
|
131
|
+
listeners: []
|
|
132
|
+
};
|
|
133
|
+
n.set(t, i);
|
|
134
|
+
let a = document.createElement("script"), o = e.nonce ?? document.querySelector("script[nonce]")?.nonce;
|
|
135
|
+
o !== void 0 && o !== "" && (a.nonce = o), e.id !== void 0 && (a.id = e.id);
|
|
136
|
+
for (let [t, n] of Object.entries(e.attributes ?? {})) a.setAttribute(t, n);
|
|
137
|
+
if (e.src !== void 0) {
|
|
138
|
+
a.addEventListener("load", () => {
|
|
139
|
+
W(i, "loaded");
|
|
140
|
+
}), a.addEventListener("error", (e) => {
|
|
141
|
+
W(i, "error", e);
|
|
142
|
+
});
|
|
143
|
+
let t = {
|
|
144
|
+
onLoad: e.onLoad,
|
|
145
|
+
onError: e.onError
|
|
146
|
+
};
|
|
147
|
+
return i.listeners.push(t), a.src = e.src, document.body.appendChild(a), () => {
|
|
148
|
+
let e = i.listeners.indexOf(t);
|
|
149
|
+
e !== -1 && i.listeners.splice(e, 1);
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
a.textContent = e.children ?? "";
|
|
153
|
+
try {
|
|
154
|
+
document.body.appendChild(a), W(i, "loaded"), e.onLoad?.();
|
|
155
|
+
} catch (t) {
|
|
156
|
+
W(i, "error", t), e.onError?.(t);
|
|
157
|
+
}
|
|
158
|
+
}, nt = (e) => {
|
|
159
|
+
let t = globalThis;
|
|
160
|
+
if (typeof t.requestIdleCallback == "function") {
|
|
161
|
+
let n = t.requestIdleCallback(e);
|
|
162
|
+
return () => t.cancelIdleCallback?.(n);
|
|
163
|
+
}
|
|
164
|
+
let n = setTimeout(e, 0);
|
|
165
|
+
return () => clearTimeout(n);
|
|
166
|
+
}, rt = ({ src: e, children: t, id: n, strategy: r = "afterInteractive", onLoad: i, onError: a, nonce: o, attributes: s }) => (Ke(() => {
|
|
167
|
+
if (e === void 0 && (t === void 0 || t === "")) {
|
|
168
|
+
console.warn("<Script> needs either src or inline children — rendered nothing.");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (e === void 0 && n === void 0) {
|
|
172
|
+
console.error("<Script> with inline children requires an `id` (the dedupe key). Script not injected.");
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
let c = e ?? `inline:${n}`, l = {
|
|
176
|
+
...e === void 0 ? {} : { src: e },
|
|
177
|
+
...t === void 0 ? {} : { children: t },
|
|
178
|
+
...n === void 0 ? {} : { id: n },
|
|
179
|
+
...i ? { onLoad: i } : {},
|
|
180
|
+
...a ? { onError: a } : {},
|
|
181
|
+
...o === void 0 ? {} : { nonce: o },
|
|
182
|
+
...s === void 0 ? {} : { attributes: s }
|
|
183
|
+
};
|
|
184
|
+
if (r === "lazyOnload") {
|
|
185
|
+
let e, t = nt(() => {
|
|
186
|
+
e = G(l, c);
|
|
187
|
+
});
|
|
188
|
+
return () => {
|
|
189
|
+
t(), e?.();
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return G(l, c);
|
|
193
|
+
}, []), null), it = (e) => e.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""), at = (e) => {
|
|
194
|
+
let t = `--font-${it(e)}`;
|
|
195
|
+
return {
|
|
196
|
+
variable: t,
|
|
197
|
+
fontFamily: `var(${t})`
|
|
198
|
+
};
|
|
199
|
+
}, ot = ({ to: e, children: t, className: n }) => P("a", {
|
|
89
200
|
href: e,
|
|
90
201
|
className: n
|
|
91
|
-
}, t),
|
|
202
|
+
}, t), st = {
|
|
92
203
|
position: "sticky",
|
|
93
204
|
top: 0,
|
|
94
205
|
zIndex: 10,
|
|
@@ -99,13 +210,13 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
99
210
|
padding: "1rem 1.5rem",
|
|
100
211
|
borderBottom: "1px solid var(--voltro-blog-border, rgba(127,127,127,0.2))",
|
|
101
212
|
backdropFilter: "blur(8px)"
|
|
102
|
-
},
|
|
213
|
+
}, ct = {
|
|
103
214
|
maxWidth: "48rem",
|
|
104
215
|
margin: "0 auto",
|
|
105
216
|
padding: "2rem 1.5rem",
|
|
106
217
|
width: "100%"
|
|
107
|
-
},
|
|
108
|
-
let { brand: t, topNav: n, children: r, pathname: i, footer: a, breadcrumbs: o, headerRight: s } = e, c = e.Link ??
|
|
218
|
+
}, lt = (e) => {
|
|
219
|
+
let { brand: t, topNav: n, children: r, pathname: i, footer: a, breadcrumbs: o, headerRight: s } = e, c = e.Link ?? ot, l = P("nav", {
|
|
109
220
|
className: "voltro-blog-nav",
|
|
110
221
|
style: {
|
|
111
222
|
display: "flex",
|
|
@@ -114,20 +225,20 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
114
225
|
}
|
|
115
226
|
}, ...n.map((e) => {
|
|
116
227
|
let t = i === e.href;
|
|
117
|
-
return
|
|
228
|
+
return P(c, {
|
|
118
229
|
key: e.href,
|
|
119
230
|
to: e.href,
|
|
120
231
|
className: t ? "voltro-blog-nav-link is-active" : "voltro-blog-nav-link",
|
|
121
232
|
children: e.label
|
|
122
233
|
});
|
|
123
|
-
})), u =
|
|
234
|
+
})), u = P("header", {
|
|
124
235
|
className: "voltro-blog-header",
|
|
125
|
-
style:
|
|
126
|
-
},
|
|
236
|
+
style: st
|
|
237
|
+
}, P("div", { className: "voltro-blog-brand" }, t), s ? P("div", { style: {
|
|
127
238
|
display: "flex",
|
|
128
239
|
gap: "1rem",
|
|
129
240
|
alignItems: "center"
|
|
130
|
-
} }, l, s) : l), d = o && o.length > 0 ?
|
|
241
|
+
} }, l, s) : l), d = o && o.length > 0 ? P("nav", {
|
|
131
242
|
className: "voltro-blog-breadcrumbs",
|
|
132
243
|
"aria-label": "Breadcrumb",
|
|
133
244
|
style: {
|
|
@@ -138,19 +249,19 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
138
249
|
gap: "0.5rem"
|
|
139
250
|
}
|
|
140
251
|
}, ...o.flatMap((e, t) => {
|
|
141
|
-
let n = t === o.length - 1, r = e.href && !n ?
|
|
252
|
+
let n = t === o.length - 1, r = e.href && !n ? P(c, {
|
|
142
253
|
key: `c${t}`,
|
|
143
254
|
to: e.href,
|
|
144
255
|
children: e.label
|
|
145
|
-
}) :
|
|
256
|
+
}) : P("span", {
|
|
146
257
|
key: `c${t}`,
|
|
147
258
|
"aria-current": n ? "page" : void 0
|
|
148
259
|
}, e.label);
|
|
149
|
-
return n ? [r] : [r,
|
|
150
|
-
})) : null, f =
|
|
260
|
+
return n ? [r] : [r, P("span", { key: `s${t}` }, "/")];
|
|
261
|
+
})) : null, f = P("main", {
|
|
151
262
|
className: "voltro-blog-main",
|
|
152
|
-
style:
|
|
153
|
-
}, d, r), p = a ?
|
|
263
|
+
style: ct
|
|
264
|
+
}, d, r), p = a ? P("footer", {
|
|
154
265
|
className: "voltro-blog-footer",
|
|
155
266
|
style: {
|
|
156
267
|
maxWidth: "48rem",
|
|
@@ -159,32 +270,32 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
159
270
|
borderTop: "1px solid var(--voltro-blog-border, rgba(127,127,127,0.2))"
|
|
160
271
|
}
|
|
161
272
|
}, a) : null;
|
|
162
|
-
return
|
|
163
|
-
},
|
|
273
|
+
return P("div", { className: "voltro-blog-layout" }, u, f, p);
|
|
274
|
+
}, K = (e) => {
|
|
164
275
|
if (e === "" || e === "/") return "/";
|
|
165
276
|
let t = e.startsWith("/") ? e : `/${e}`;
|
|
166
277
|
return t.endsWith("/") ? t.slice(0, -1) : t;
|
|
167
|
-
},
|
|
168
|
-
let n = e.endsWith("/") ? e.slice(0, -1) : e, r =
|
|
278
|
+
}, q = (e, t) => {
|
|
279
|
+
let n = e.endsWith("/") ? e.slice(0, -1) : e, r = K(t);
|
|
169
280
|
return r === "/" ? `${n}/` : `${n}${r}`;
|
|
170
|
-
},
|
|
171
|
-
let r =
|
|
281
|
+
}, J = (e, t, n) => {
|
|
282
|
+
let r = K(e);
|
|
172
283
|
return t === n ? r : r === "/" ? `/${t}` : `/${t}${r}`;
|
|
173
|
-
},
|
|
174
|
-
let { siteUrl: t, path: n, locale: r, locales: i, defaultLocale: a, xDefault: o = !0 } = e, s =
|
|
284
|
+
}, ut = (e, t) => q(e, t), dt = (e) => {
|
|
285
|
+
let { siteUrl: t, path: n, locale: r, locales: i, defaultLocale: a, xDefault: o = !0 } = e, s = q(t, J(n, r, a)), c = i.map((e) => ({
|
|
175
286
|
rel: "alternate",
|
|
176
287
|
hreflang: e,
|
|
177
|
-
href:
|
|
288
|
+
href: q(t, J(n, e, a))
|
|
178
289
|
}));
|
|
179
290
|
return o && c.push({
|
|
180
291
|
rel: "alternate",
|
|
181
292
|
hreflang: "x-default",
|
|
182
|
-
href:
|
|
293
|
+
href: q(t, J(n, a, a))
|
|
183
294
|
}), {
|
|
184
295
|
canonical: s,
|
|
185
296
|
links: c
|
|
186
297
|
};
|
|
187
|
-
}, Y = "voltro:theme",
|
|
298
|
+
}, Y = "voltro:theme", ft = 31536e3, pt = () => {
|
|
188
299
|
if (typeof document > "u") return "system";
|
|
189
300
|
try {
|
|
190
301
|
let e = document.cookie.match(/(?:^|;\s*)voltro:theme=([^;]*)/), t = e?.[1] === void 0 ? "" : decodeURIComponent(e[1]);
|
|
@@ -192,17 +303,17 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
192
303
|
} catch {
|
|
193
304
|
return "system";
|
|
194
305
|
}
|
|
195
|
-
},
|
|
306
|
+
}, mt = () => {
|
|
196
307
|
if (typeof window > "u" || !window.matchMedia) return !1;
|
|
197
308
|
try {
|
|
198
309
|
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
199
310
|
} catch {
|
|
200
311
|
return !1;
|
|
201
312
|
}
|
|
202
|
-
}, X = (e) => e === "system" ?
|
|
313
|
+
}, X = (e) => e === "system" ? mt() ? "dark" : "light" : e, Z = 0, Q = /* @__PURE__ */ new Set(), $ = () => {
|
|
203
314
|
Z++;
|
|
204
315
|
for (let e of Q) e();
|
|
205
|
-
},
|
|
316
|
+
}, ht = (e) => {
|
|
206
317
|
Q.add(e);
|
|
207
318
|
let t, n = () => $();
|
|
208
319
|
if (typeof window < "u" && window.matchMedia) try {
|
|
@@ -214,21 +325,21 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
214
325
|
t?.removeEventListener("change", n);
|
|
215
326
|
} catch {}
|
|
216
327
|
};
|
|
217
|
-
},
|
|
218
|
-
let e =
|
|
328
|
+
}, gt = () => {
|
|
329
|
+
let e = pt();
|
|
219
330
|
return `${Z}:${e}:${X(e)}`;
|
|
220
|
-
},
|
|
221
|
-
let [, e, t] =
|
|
331
|
+
}, _t = () => "0:system:light", vt = () => {
|
|
332
|
+
let [, e, t] = qe(ht, gt, _t).split(":");
|
|
222
333
|
return {
|
|
223
334
|
theme: e,
|
|
224
335
|
resolvedTheme: t,
|
|
225
|
-
setTheme:
|
|
336
|
+
setTheme: We((e) => {
|
|
226
337
|
if (typeof document < "u") try {
|
|
227
|
-
document.cookie = e === "system" ? `${Y}=; path=/; max-age=0; SameSite=Lax` : `${Y}=${e}; path=/; max-age=${
|
|
338
|
+
document.cookie = e === "system" ? `${Y}=; path=/; max-age=0; SameSite=Lax` : `${Y}=${e}; path=/; max-age=${ft}; SameSite=Lax`, document.documentElement.classList.toggle("dark", X(e) === "dark");
|
|
228
339
|
} catch {}
|
|
229
340
|
$();
|
|
230
341
|
}, [])
|
|
231
342
|
};
|
|
232
|
-
},
|
|
343
|
+
}, yt = "framework-web";
|
|
233
344
|
//#endregion
|
|
234
|
-
export { t as AppClientsContext,
|
|
345
|
+
export { t as AppClientsContext, R as Await, lt as BlogLayout, p as FallbackStringsProvider, $e as Image, Ze as ImageConfigProvider, Me as Link, Ce as LoaderCache, k as LoaderDataContext, ke as NO_LOADER_DATA, i as NavigationIndicator, Be as NotFoundError, Ne as PAGE_SLOT_ATTR, j as PageSlot, Ee as PlainLink, Fe as RENDER_MODES, o as ReconnectContext, ne as RedirectError, M as Router, N as RouterContext, rt as Script, Y as THEME_COOKIE, yt as WEB_NAME, ut as canonicalUrl, Ae as compileRoute, le as decodeSearchParams, d as defaultFallbackStrings, b as defer, de as encodeSearchParams, De as externalUrl, Se as findNotFound, c as formatPrintf, _ as getIslandComponent, se as getRouteSnapshot, f as getStatuses, v as hydrateIslandsOnPage, a as installBrowserConsoleBridge, r as installServerLogRelay, T as isDeferredLoaderResult, be as isNotFound, ce as isRedirect, y as island, q as joinUrl, xe as lazyPageRoute, O as loaderCacheKey, at as localFont, J as localizedPath, Ie as matchRoute, E as mount, K as normalizePath, ye as notFound, ee as noticeIslandsShipTheFullBundle, ze as pageRoute, Pe as parseCookieHeader, B as passthroughImageLoader, A as preloadRouteModule, m as pushStatus, D as redirect, s as registerClientTrace, Re as renderRouterProviderTree, tt as resetScriptRegistryForTest, _e as resolveAnchorNavigation, re as resolveMeta, ge as searchParamsToObject, Le as segmentLoaderKey, dt as seoAlternates, ue as setRouteSnapshot, ve as sortRoutesByPriority, je as subscribeRouteSnapshot, g as subscribeStatuses, l as subscribeTraceErrors, n as useAppClient, ae as useBlocker, h as useFallbackStrings, ie as useLoaderData, me as useLocation, Te as useNavigate, te as useOptionalLoaderData, we as useParams, fe as usePrefetch, u as useReconnect, Oe as useSearchParams, pe as useSetSearchParams, vt as useTheme, he as withHash, oe as withQuery };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Look up a registered island Component by name. Returns undefined if
|
|
6
|
+
* the name isn't registered (typically means the user forgot to import
|
|
7
|
+
* the island file in this bundle).
|
|
8
|
+
*/
|
|
9
|
+
export declare const getIslandComponent: (name: string) => ComponentType<unknown> | undefined;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Client-side runtime: scan the document for `[data-voltro-island]`
|
|
13
|
+
* markers and schedule each for hydration per its strategy. Called by the
|
|
14
|
+
* per-page islands entry, and by `@voltro/web/mount` when an islands page
|
|
15
|
+
* is reached through the full app bundle (SPA navigation). Idempotent —
|
|
16
|
+
* running twice is a no-op (we mark elements as visited).
|
|
17
|
+
*/
|
|
18
|
+
export declare const hydrateIslandsOnPage: (options?: HydrateIslandsOptions) => void;
|
|
19
|
+
|
|
20
|
+
export declare interface HydrateIslandsOptions {
|
|
21
|
+
/** Wrap every island root — the per-page islands entry of a page whose
|
|
22
|
+
* islands use framework hooks passes a `<VoltroRuntimeProvider>` here so
|
|
23
|
+
* a `useSubscription` island gets a live runtime. Purely presentational
|
|
24
|
+
* entries pass nothing and never load the client core. */
|
|
25
|
+
readonly wrap?: (children: ReactNode) => ReactNode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export declare type HydrateStrategy =
|
|
29
|
+
/** Hydrate as soon as the client runtime mounts (after main script load). */
|
|
30
|
+
'load'
|
|
31
|
+
/** Hydrate when the browser is idle (via `requestIdleCallback`, with a
|
|
32
|
+
* setTimeout fallback for browsers that lack it). */
|
|
33
|
+
| 'idle'
|
|
34
|
+
/** Hydrate when the element scrolls into the viewport (IntersectionObserver). */
|
|
35
|
+
| 'visible'
|
|
36
|
+
/** Hydrate on the first pointer / keyboard interaction with the element. */
|
|
37
|
+
| 'interaction'
|
|
38
|
+
/** Never hydrate. Useful for fully-static islands (e.g. SSR-only data
|
|
39
|
+
* display that never changes). */
|
|
40
|
+
| 'never'
|
|
41
|
+
/** CLIENT-ONLY: the server renders an empty placeholder (never the
|
|
42
|
+
* component — a browser-only lib touching `window` in render would
|
|
43
|
+
* crash the SSR pass), and the client mounts fresh with `createRoot`
|
|
44
|
+
* instead of hydrating. Astro's `client:only`. */
|
|
45
|
+
| 'only';
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Wrap a Component as an island. The returned Component renders the
|
|
49
|
+
* inner content wrapped in a marker `<div data-voltro-island>` that
|
|
50
|
+
* carries the island's name + props + hydrate strategy. The same
|
|
51
|
+
* call also registers the Component under its name so the client
|
|
52
|
+
* runtime can find it when hydrating.
|
|
53
|
+
*/
|
|
54
|
+
export declare const island: <P extends Record<string, unknown>>(Component: ComponentType<P>, options: IslandOptions) => ComponentType<P>;
|
|
55
|
+
|
|
56
|
+
export declare interface IslandOptions {
|
|
57
|
+
/** Stable id of this island. Must be unique within an app. The framework
|
|
58
|
+
* uses it to match the server-rendered marker with the client-side
|
|
59
|
+
* Component. */
|
|
60
|
+
readonly name: string;
|
|
61
|
+
/** When the client runtime should hydrate this island. Defaults to
|
|
62
|
+
* `visible` — matches Astro's default and is the best perf/UX balance. */
|
|
63
|
+
readonly hydrate?: HydrateStrategy;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { }
|
package/dist/islands.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createElement as e } from "react";
|
|
2
|
+
import { createRoot as t, hydrateRoot as n } from "react-dom/client";
|
|
3
|
+
//#region src/islands.tsx
|
|
4
|
+
var r = /* @__PURE__ */ new Map(), i = (t, n) => {
|
|
5
|
+
r.set(n.name, t);
|
|
6
|
+
let i = n.hydrate ?? "visible", a = (r) => e("div", {
|
|
7
|
+
"data-voltro-island": "",
|
|
8
|
+
"data-island-name": n.name,
|
|
9
|
+
"data-island-hydrate": i,
|
|
10
|
+
"data-island-props": o(r, n.name)
|
|
11
|
+
}, i === "only" ? null : e(t, r));
|
|
12
|
+
return a.displayName = `Island(${n.name})`, a;
|
|
13
|
+
}, a = (e) => r.get(e), o = (e, t) => {
|
|
14
|
+
if (process.env.NODE_ENV !== "production" && typeof e == "object" && e) for (let [n, r] of Object.entries(e)) {
|
|
15
|
+
let e = typeof r == "function" ? "a function" : r instanceof Date ? "a Date (arrives as an ISO string)" : r instanceof Map || r instanceof Set ? "a Map/Set (arrives as {})" : void 0;
|
|
16
|
+
e !== void 0 && console.warn(`[voltro] island "${t}" prop "${n}" is ${e} — island props cross an HTML attribute as JSON. Pass a JSON shape (string/number/boolean/array/plain object) and reconstruct richer types inside the island.`);
|
|
17
|
+
}
|
|
18
|
+
return JSON.stringify(e ?? {}).replace(/</g, "\\u003c");
|
|
19
|
+
}, s = (e) => {
|
|
20
|
+
if (!e) return {};
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(e);
|
|
23
|
+
} catch {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
}, c = (i) => {
|
|
27
|
+
let a = document.querySelectorAll("[data-voltro-island]:not([data-voltro-hydrated])");
|
|
28
|
+
for (let o of a) {
|
|
29
|
+
let a = o.dataset.islandName ?? "", c = r.get(a);
|
|
30
|
+
if (!c) {
|
|
31
|
+
console.warn(`[voltro] island "${a}" referenced in DOM but not registered. Did the island file get imported in this bundle?`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
let l = s(o.dataset.islandProps ?? null), u = o.dataset.islandHydrate ?? "visible";
|
|
35
|
+
o.setAttribute("data-voltro-hydrated", "pending");
|
|
36
|
+
let d = () => {
|
|
37
|
+
if (o.getAttribute("data-voltro-hydrated") === "done") return;
|
|
38
|
+
o.setAttribute("data-voltro-hydrated", "done");
|
|
39
|
+
let r = i?.wrap === void 0 ? e(c, l) : i.wrap(e(c, l));
|
|
40
|
+
u === "only" ? t(o).render(r) : n(o, r);
|
|
41
|
+
};
|
|
42
|
+
if (u === "load" || u === "only") d();
|
|
43
|
+
else if (u === "idle") {
|
|
44
|
+
let e = globalThis.requestIdleCallback;
|
|
45
|
+
e ? e(d) : setTimeout(d, 0);
|
|
46
|
+
} else if (u === "visible") {
|
|
47
|
+
let e = new IntersectionObserver((t) => {
|
|
48
|
+
t.some((e) => e.isIntersecting) && (e.disconnect(), d());
|
|
49
|
+
}, { rootMargin: "64px" });
|
|
50
|
+
e.observe(o);
|
|
51
|
+
} else if (u === "interaction") {
|
|
52
|
+
let e = () => {
|
|
53
|
+
o.removeEventListener("pointerdown", e), o.removeEventListener("keydown", e), d();
|
|
54
|
+
};
|
|
55
|
+
o.addEventListener("pointerdown", e, { passive: !0 }), o.addEventListener("keydown", e);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { a as getIslandComponent, c as hydrateIslandsOnPage, i as island };
|
package/dist/mount.js
CHANGED
|
@@ -1,2 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { t as e } from "./frameworkBoot-CnE9vzLQ.js";
|
|
2
|
+
import { hydrateIslandsOnPage as t } from "./islands.js";
|
|
3
|
+
import { o as n, r, t as i } from "./routerState-Cr6fTbka.js";
|
|
4
|
+
import { StrictMode as a } from "react";
|
|
5
|
+
import { createRoot as o, hydrateRoot as s } from "react-dom/client";
|
|
6
|
+
import { applyPreloadSeeds as c, applyStoreSeeds as l } from "@voltro/client";
|
|
7
|
+
import { jsx as u } from "react/jsx-runtime";
|
|
8
|
+
//#region src/mount.tsx
|
|
9
|
+
var d = () => !1, f = "__voltroIslandsBundleNoticeShown", p = (e) => {
|
|
10
|
+
if (!e) return;
|
|
11
|
+
let t = globalThis;
|
|
12
|
+
t[f] !== !0 && (t[f] = !0, console.info("[voltro] islands mode: hydration is scoped to this page's islands, but the JS payload is NOT reduced — the full app bundle is still downloaded and evaluated. Islands buy CPU, not bytes, today. See the \"Render modes\" docs page."));
|
|
13
|
+
}, m = (e) => `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}/ws/${e}`, h = (f, h) => {
|
|
14
|
+
let g = document.getElementById(h.rootId ?? "root");
|
|
15
|
+
if (!g) throw Error(`@voltro/web: no #${h.rootId ?? "root"} element in the document`);
|
|
16
|
+
let _ = Object.entries(h.apis).map(([e, t]) => ({
|
|
17
|
+
name: e,
|
|
18
|
+
group: t.group,
|
|
19
|
+
descriptors: t.descriptors ?? {},
|
|
20
|
+
wsUrl: t.wsUrl ?? m(e),
|
|
21
|
+
headers: t.headers
|
|
22
|
+
})), v = document.getElementById(i), y = r(v?.textContent, window.location.pathname), b = y !== null && g.children.length > 0, x = document.querySelector("meta[name=\"voltro-interactive\"]")?.getAttribute("content") ?? "full";
|
|
23
|
+
if (x === "none") return;
|
|
24
|
+
if (x === "islands") {
|
|
25
|
+
p(d()), t();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
b && n(y), l(y?.storeSeeds), c(y?.preloadSeeds);
|
|
29
|
+
let S = /* @__PURE__ */ u(a, { children: /* @__PURE__ */ u(e, {
|
|
30
|
+
App: f,
|
|
31
|
+
apis: _,
|
|
32
|
+
...h.Devtools ? { Devtools: h.Devtools } : {}
|
|
33
|
+
}) });
|
|
34
|
+
b ? s(g, S) : o(g).render(S);
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { h as mount, p as noticeIslandsShipTheFullBundle };
|
|
@@ -55,7 +55,9 @@ var e = /* @__PURE__ */ RegExp("\\u2028", "g"), t = /* @__PURE__ */ RegExp("\\u2
|
|
|
55
55
|
}, x = (e) => {
|
|
56
56
|
let { page: t, renderMode: n, interactive: r, layoutShell: i } = e;
|
|
57
57
|
if (i === "artefact") throw Error(`[voltro] a layout in "${t}"'s chain uses defer() in its loader, but this page's SSR layout shell is PRERENDERED at build time into a static HTML file. defer() streams values in AFTER the shell, and a file has no "after" — the <Await> fallback would be frozen into the artefact forever. Drop defer() from the layout loader and return the values directly (the shell then prerenders as before), or give the layout per-request data so the page is served on demand.`);
|
|
58
|
-
|
|
58
|
+
let a = e.ppr === !0 && n === "isr";
|
|
59
|
+
if (e.ppr === !0 && n !== "isr") throw Error(`[voltro] "${t}" exports ppr = true with renderMode: '${n}'. Partial prerendering caches a SHELL and appends per-request holes, which needs the isr serve path — a '${n}' ${n === "static" ? "file is served by any static host with no way to append holes" : "page already streams per request, ppr adds nothing"}. ` + (n === "static" ? "Set `export const renderMode = 'isr'` (a long revalidate gives the same cache behaviour)." : "Drop the ppr export."));
|
|
60
|
+
if (!(n === "ssr" || n === "spa" && i === "stream") && !a) throw Error(`[voltro] "${t}" uses defer() in its loader but has renderMode: '${n}'. defer() streams values in AFTER the shell, which only a per-request response can do — '${n}' produces a stored HTML artefact with no "after". Set \`export const renderMode = 'ssr'\` on this page, add \`export const ppr = true\` to an isr page (partial prerendering: cached shell + per-request holes), or drop defer() and return the values directly.`);
|
|
59
61
|
if (r !== "full") throw Error(`[voltro] "${t}" uses defer() in its loader but has interactive: '${r}'. ` + (r === "none" ? "Revealing a streamed <Suspense> boundary requires React's inline reveal scripts, and interactive: 'none' ships no JS at all — the <Await> fallback would be permanent. " : "interactive: 'islands' never hydrates the page's React root, so nothing consumes the streamed values and the <Await> fallback would be permanent. ") + "Remove the `interactive` export (defaults to 'full'), or drop defer() and return the values directly.");
|
|
60
62
|
}, S = "__voltro_state__", C = (e) => {
|
|
61
63
|
let t = Object.keys(e.segmentLoaderData ?? {}).map((e) => Number(e)).filter((e) => Number.isInteger(e)).sort((e, t) => e - t), n = e.deferredPageIds !== void 0, r = e.deferredSegmentIds !== void 0 && Object.keys(e.deferredSegmentIds).length > 0;
|
|
@@ -112,4 +114,4 @@ var e = /* @__PURE__ */ RegExp("\\u2028", "g"), t = /* @__PURE__ */ RegExp("\\u2
|
|
|
112
114
|
k = e;
|
|
113
115
|
}, j = () => k;
|
|
114
116
|
//#endregion
|
|
115
|
-
export {
|
|
117
|
+
export { p as _, w as a, i as c, l as d, m as f, y as g, b as h, j as i, h as l, a as m, C as n, A as o, o as p, D as r, x as s, S as t, u, n as v };
|