@voltro/web 0.37.0 → 0.39.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 +316 -0
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/dist/{frameworkBoot--fOA34nd.js → frameworkBoot-Tso-IjA7.js} +113 -193
- package/dist/frameworkBoot.d.ts +4 -32
- package/dist/frameworkBoot.js +1 -1
- package/dist/index.d.ts +38 -0
- package/dist/index.js +7 -7
- package/dist/{mount-BKP99m_W.js → mount-BTAQ-8Vl.js} +7 -7
- package/dist/mount.js +1 -1
- package/dist/{serverContext-7toyzR70.js → serverContext-38JTbYPa.js} +96 -93
- package/dist/ssr.d.ts +41 -0
- package/dist/ssr.js +32 -32
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -503,9 +503,47 @@ export declare class LoaderCache {
|
|
|
503
503
|
|
|
504
504
|
export declare const loaderCacheKey: (pattern: string, params: Readonly<Record<string, string>>) => string;
|
|
505
505
|
|
|
506
|
+
/**
|
|
507
|
+
* What a `loader` receives.
|
|
508
|
+
*
|
|
509
|
+
* **It runs on the server AND again in the browser.** A loader is not a
|
|
510
|
+
* server-only hook: it runs during SSR for the first paint, and then runs
|
|
511
|
+
* AGAIN, in the browser, on every in-app navigation to the route. Same
|
|
512
|
+
* function, different environment.
|
|
513
|
+
*
|
|
514
|
+
* That precondition was never written down, and a consumer read "runs once per
|
|
515
|
+
* request" into the gap — which is the reading the wording invites. It cost
|
|
516
|
+
* them two days, and the reason it survived that long is the nastiest part: a
|
|
517
|
+
* client-only failure is invisible to every probe that does not NAVIGATE. A
|
|
518
|
+
* fresh page load, a `curl`, any SSR check goes through the server path and
|
|
519
|
+
* passes. Only clicking a link inside the running app reaches the other one.
|
|
520
|
+
*
|
|
521
|
+
* So anything server-only in a loader must be guarded by {@link isServer}.
|
|
522
|
+
*/
|
|
506
523
|
export declare interface LoaderContext<Procedures = unknown> {
|
|
507
524
|
readonly params: Readonly<Record<string, string>>;
|
|
508
525
|
readonly pathname: string;
|
|
526
|
+
/**
|
|
527
|
+
* `true` when this invocation is the SERVER one (SSR under `voltro dev` or
|
|
528
|
+
* `voltro start`), `false` in the browser.
|
|
529
|
+
*
|
|
530
|
+
* Exists because the alternatives are traps. `query` is absent in the browser
|
|
531
|
+
* and so reads as a discriminator, but branching on the ABSENCE OF A FUNCTION
|
|
532
|
+
* says nothing about why it is absent and breaks the moment anything else
|
|
533
|
+
* becomes conditional. `headers` is worse: it is `{}` in the browser, not
|
|
534
|
+
* `undefined`, so `ctx.headers ? …` is TRUE on both paths — a consumer
|
|
535
|
+
* checked exactly that and it silently did nothing.
|
|
536
|
+
*
|
|
537
|
+
* export const loader = async (ctx: LoaderContext) => {
|
|
538
|
+
* if (ctx.isServer) seedStore(prefs, await ctx.query!('prefs.get'))
|
|
539
|
+
* return null
|
|
540
|
+
* }
|
|
541
|
+
*
|
|
542
|
+
* REQUIRED, not optional: an optional boolean is omissible, and a server path
|
|
543
|
+
* that forgot it would read as `undefined` — falsy — and claim to be the
|
|
544
|
+
* browser. Required means the compiler names every construction site.
|
|
545
|
+
*/
|
|
546
|
+
readonly isServer: boolean;
|
|
509
547
|
/**
|
|
510
548
|
* The raw query string, INCLUDING the leading `?`, or `''` when there is
|
|
511
549
|
* none. Filled on every path — client navigation, `voltro dev` SSR and
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as e } from "./globalContext-d4A-ugDg.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
|
|
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-Tso-IjA7.js";
|
|
4
4
|
import { a as d, c as f, i as p, l as m, o as h, u as g } from "./defaultFallbacks-B4Ak-R6R.js";
|
|
5
|
-
import { a as _, i as ee, n as te, r as ne, t as re } from "./mount-
|
|
5
|
+
import { a as _, i as ee, n as te, r as ne, t as re } from "./mount-BTAQ-8Vl.js";
|
|
6
6
|
import { c as ie, d as ae, h as oe, l as se, p as ce, u as le } from "./routerState-DAT472IC.js";
|
|
7
|
-
import { A as ue, B as de, C as fe, D as pe, E as me, F as he, G as ge, H as _e, I as v, K as y, L as b, M as x, N as S, O as C, P as w, R as T, S as E, T as D, U as O, V as k, W as A, _ as j, a as M, b as N, c as P, d as F, f as I, g as ve, h as ye, i as be, j as xe, k as Se, l as Ce, m as we, n as Te, o as Ee, p as De, q as Oe, r as ke, s as Ae, t as je, u as Me, v as Ne, w as Pe, x as Fe, y as Ie, z as Le } from "./serverContext-
|
|
7
|
+
import { A as ue, B as de, C as fe, D as pe, E as me, F as he, G as ge, H as _e, I as v, K as y, L as b, M as x, N as S, O as C, P as w, R as T, S as E, T as D, U as O, V as k, W as A, _ as j, a as M, b as N, c as P, d as F, f as I, g as ve, h as ye, i as be, j as xe, k as Se, l as Ce, m as we, n as Te, o as Ee, p as De, q as Oe, r as ke, s as Ae, t as je, u as Me, v as Ne, w as Pe, x as Fe, y as Ie, z as Le } from "./serverContext-38JTbYPa.js";
|
|
8
8
|
import { Component as Re, Suspense as ze, createElement as L, use as Be, useCallback as Ve, useContext as He, useSyncExternalStore as Ue } from "react";
|
|
9
9
|
import { Fragment as R, jsx as z, jsxs as B } from "react/jsx-runtime";
|
|
10
10
|
export * from "@voltro/client";
|
|
@@ -147,11 +147,10 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
147
147
|
"aria-current": n ? "page" : void 0
|
|
148
148
|
}, e.label);
|
|
149
149
|
return n ? [r] : [r, L("span", { key: `s${t}` }, "/")];
|
|
150
|
-
})) : null
|
|
151
|
-
return L("div", { className: "voltro-blog-layout" }, u, L("main", {
|
|
150
|
+
})) : null, f = L("main", {
|
|
152
151
|
className: "voltro-blog-main",
|
|
153
152
|
style: Qe
|
|
154
|
-
}, d, r), a ? L("footer", {
|
|
153
|
+
}, d, r), p = a ? L("footer", {
|
|
155
154
|
className: "voltro-blog-footer",
|
|
156
155
|
style: {
|
|
157
156
|
maxWidth: "48rem",
|
|
@@ -159,7 +158,8 @@ var We = ({ value: e, fallback: t, children: n, errorFallback: r }) => /* @__PUR
|
|
|
159
158
|
padding: "2rem 1.5rem",
|
|
160
159
|
borderTop: "1px solid var(--voltro-blog-border, rgba(127,127,127,0.2))"
|
|
161
160
|
}
|
|
162
|
-
}, a) : null
|
|
161
|
+
}, a) : null;
|
|
162
|
+
return L("div", { className: "voltro-blog-layout" }, u, f, p);
|
|
163
163
|
}, G = (e) => {
|
|
164
164
|
if (e === "" || e === "/") return "/";
|
|
165
165
|
let t = e.startsWith("/") ? e : `/${e}`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./frameworkBoot
|
|
1
|
+
import { t as e } from "./frameworkBoot-Tso-IjA7.js";
|
|
2
2
|
import { o as t, r as n, t as r } from "./routerState-DAT472IC.js";
|
|
3
3
|
import { StrictMode as i, createElement as a } from "react";
|
|
4
4
|
import { createRoot as o, hydrateRoot as s } from "react-dom/client";
|
|
@@ -63,19 +63,19 @@ var d = /* @__PURE__ */ new Map(), f = (e, t) => {
|
|
|
63
63
|
descriptors: t.descriptors ?? {},
|
|
64
64
|
wsUrl: t.wsUrl ?? b(e),
|
|
65
65
|
headers: t.headers
|
|
66
|
-
})), m =
|
|
67
|
-
if (
|
|
68
|
-
if (
|
|
66
|
+
})), m = document.getElementById(r), h = n(m?.textContent, window.location.pathname), v = h !== null && f.children.length > 0, x = document.querySelector("meta[name=\"voltro-interactive\"]")?.getAttribute("content") ?? "full";
|
|
67
|
+
if (x === "none") return;
|
|
68
|
+
if (x === "islands") {
|
|
69
69
|
y(_()), g();
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
|
-
|
|
73
|
-
let
|
|
72
|
+
v && t(h), l(h?.storeSeeds), c(h?.preloadSeeds);
|
|
73
|
+
let S = /* @__PURE__ */ u(i, { children: /* @__PURE__ */ u(e, {
|
|
74
74
|
App: a,
|
|
75
75
|
apis: p,
|
|
76
76
|
...d.Devtools ? { Devtools: d.Devtools } : {}
|
|
77
77
|
}) });
|
|
78
|
-
|
|
78
|
+
v ? s(f, S) : o(f).render(S);
|
|
79
79
|
};
|
|
80
80
|
//#endregion
|
|
81
81
|
export { f as a, g as i, y as n, p as r, x as t };
|
package/dist/mount.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "./mount-
|
|
1
|
+
import { n as e, t } from "./mount-BTAQ-8Vl.js";
|
|
2
2
|
export { t as mount, e as noticeIslandsShipTheFullBundle };
|
|
@@ -291,7 +291,7 @@ var h = {
|
|
|
291
291
|
}
|
|
292
292
|
return this.props.children;
|
|
293
293
|
}
|
|
294
|
-
},
|
|
294
|
+
}, Se = "data-voltro-page-slot", Ce = () => /* @__PURE__ */ p("div", { [Se]: "" }), R = ({ routes: e, notFounds: i = [], notFound: o = n, errorFallback: c = r }) => {
|
|
295
295
|
let [m, h] = f(() => window.location.pathname), [g, _] = f(() => window.location.pathname), [v, y] = f(() => window.location.search + window.location.hash), b = v.split("#")[0] ?? "", x = d(new de()), S = d(/* @__PURE__ */ new Map()), [ne, w] = f(null), re = s((e, t) => (S.current.set(e, t), () => {
|
|
296
296
|
S.current.delete(e);
|
|
297
297
|
}), []), T = d(/* @__PURE__ */ new Map()), E = d(null), D = u(() => ae(e.map(ie)), [e]);
|
|
@@ -330,7 +330,7 @@ var h = {
|
|
|
330
330
|
n?.replace ? window.history.replaceState(r, "", e) : window.history.pushState(r, "", e), h(t.pathname), y(t.search + t.hash), n?.scroll !== !1 && me(t);
|
|
331
331
|
}, []), M = s((e, t) => {
|
|
332
332
|
let n = new URL(window.location.href), r = new URL(e, n);
|
|
333
|
-
if (
|
|
333
|
+
if (r.pathname !== n.pathname || r.search !== n.search || r.hash !== n.hash) {
|
|
334
334
|
for (let n of S.current.values()) if (n({
|
|
335
335
|
to: e,
|
|
336
336
|
...t ? { opts: t } : {}
|
|
@@ -356,7 +356,7 @@ var h = {
|
|
|
356
356
|
};
|
|
357
357
|
return document.addEventListener("click", e), () => document.removeEventListener("click", e);
|
|
358
358
|
}, [M]);
|
|
359
|
-
let N = u(() => O(D, m), [D, m]), P = d(/* @__PURE__ */ new Map()), [F, be] = f(0);
|
|
359
|
+
let N = u(() => O(D, m), [D, m]), P = d(/* @__PURE__ */ new Map()), [F, be] = f(0), Se = N?.route.load ? N.route.pattern : null;
|
|
360
360
|
l(() => {
|
|
361
361
|
let e = N?.route;
|
|
362
362
|
if (!e?.load || P.current.has(e.pattern)) return;
|
|
@@ -366,8 +366,8 @@ var h = {
|
|
|
366
366
|
}).catch(() => {}), () => {
|
|
367
367
|
t = !0;
|
|
368
368
|
};
|
|
369
|
-
}, [
|
|
370
|
-
let R = d(/* @__PURE__ */ new Set()),
|
|
369
|
+
}, [Se]);
|
|
370
|
+
let R = d(/* @__PURE__ */ new Set()), Te = s((e) => {
|
|
371
371
|
let t = e.load;
|
|
372
372
|
t && (P.current.has(e.pattern) || R.current.has(e.pattern) || (R.current.add(e.pattern), t().then((t) => {
|
|
373
373
|
P.current.set(e.pattern, t);
|
|
@@ -381,7 +381,7 @@ var h = {
|
|
|
381
381
|
let t = P.current.get(e.pattern);
|
|
382
382
|
return t ? {
|
|
383
383
|
...e,
|
|
384
|
-
...
|
|
384
|
+
...Pe(t),
|
|
385
385
|
load: void 0
|
|
386
386
|
} : null;
|
|
387
387
|
}, [N, F]), B = u(() => O(D, g), [D, g]), V = u(() => {
|
|
@@ -391,10 +391,10 @@ var h = {
|
|
|
391
391
|
let t = P.current.get(e.pattern);
|
|
392
392
|
return t ? {
|
|
393
393
|
...e,
|
|
394
|
-
...
|
|
394
|
+
...Pe(t),
|
|
395
395
|
load: void 0
|
|
396
396
|
} : null;
|
|
397
|
-
}, [B, F]),
|
|
397
|
+
}, [B, F]), Oe = s((e) => {
|
|
398
398
|
let t = new URL(e, window.location.origin), n = O(D, t.pathname);
|
|
399
399
|
if (!n) return;
|
|
400
400
|
let r = (e, r) => {
|
|
@@ -402,37 +402,38 @@ var h = {
|
|
|
402
402
|
params: n.params,
|
|
403
403
|
pathname: t.pathname,
|
|
404
404
|
search: t.search,
|
|
405
|
-
signal: e
|
|
405
|
+
signal: e,
|
|
406
|
+
isServer: !1
|
|
406
407
|
}));
|
|
407
408
|
};
|
|
408
|
-
|
|
409
|
+
Te(n.route), n.route.loader && r(k(n.route.pattern, n.params), n.route.loader), n.route.chain?.forEach((e, t) => {
|
|
409
410
|
e.loader && r(oe(n.route.pattern, t, n.params), e.loader);
|
|
410
411
|
});
|
|
411
|
-
}, [D,
|
|
412
|
-
|
|
413
|
-
let
|
|
412
|
+
}, [D, Te]), [H, U] = f({ status: "idle" }), W = d(void 0);
|
|
413
|
+
W.current === void 0 && (W.current = a());
|
|
414
|
+
let ke = d(!1), [Ae, je] = f(() => W.current?.pageClientOnly === !0 && W.current.pathname === m);
|
|
414
415
|
l(() => {
|
|
415
|
-
|
|
416
|
+
je(!1);
|
|
416
417
|
}, []);
|
|
417
|
-
let [
|
|
418
|
+
let [G, Me] = f(() => ({
|
|
418
419
|
pathname: m,
|
|
419
|
-
data: ge(
|
|
420
|
+
data: ge(W.current ?? null, m),
|
|
420
421
|
chain: N?.route.chain
|
|
421
422
|
}));
|
|
422
423
|
l(() => {
|
|
423
424
|
let e = (e) => {
|
|
424
|
-
_(m),
|
|
425
|
+
_(m), Me((t) => t.pathname === m && _e(t.data, e) ? t : {
|
|
425
426
|
pathname: m,
|
|
426
427
|
data: e,
|
|
427
428
|
chain: N?.route.chain
|
|
428
429
|
});
|
|
429
430
|
};
|
|
430
431
|
if (!N) {
|
|
431
|
-
|
|
432
|
+
U({ status: "idle" }), e(void 0);
|
|
432
433
|
return;
|
|
433
434
|
}
|
|
434
435
|
if (!z) {
|
|
435
|
-
|
|
436
|
+
U({
|
|
436
437
|
status: "pending",
|
|
437
438
|
key: k(N.route.pattern, N.params)
|
|
438
439
|
});
|
|
@@ -448,7 +449,8 @@ var h = {
|
|
|
448
449
|
params: n,
|
|
449
450
|
pathname: m,
|
|
450
451
|
search: b,
|
|
451
|
-
signal: t
|
|
452
|
+
signal: t,
|
|
453
|
+
isServer: !1
|
|
452
454
|
})
|
|
453
455
|
});
|
|
454
456
|
}
|
|
@@ -462,17 +464,18 @@ var h = {
|
|
|
462
464
|
params: n,
|
|
463
465
|
pathname: m,
|
|
464
466
|
search: b,
|
|
465
|
-
signal: e
|
|
467
|
+
signal: e,
|
|
468
|
+
isServer: !1
|
|
466
469
|
})
|
|
467
470
|
});
|
|
468
471
|
}
|
|
469
472
|
}), a.length === 0) {
|
|
470
|
-
|
|
473
|
+
U({ status: "idle" }), e(void 0);
|
|
471
474
|
return;
|
|
472
475
|
}
|
|
473
|
-
let o = k(t.pattern, n), s =
|
|
474
|
-
if (s && !
|
|
475
|
-
|
|
476
|
+
let o = k(t.pattern, n), s = W.current;
|
|
477
|
+
if (s && !ke.current && m === s.pathname) {
|
|
478
|
+
ke.current = !0;
|
|
476
479
|
for (let e of a) e.target === "page" ? s.pageRan && x.current.seed(e.cacheKey, s.page) : s.segments.has(e.target) && x.current.seed(e.cacheKey, s.segments.get(e.target));
|
|
477
480
|
}
|
|
478
481
|
let c = a.map((e) => ({
|
|
@@ -498,18 +501,18 @@ var h = {
|
|
|
498
501
|
};
|
|
499
502
|
}, u = l();
|
|
500
503
|
if (u) {
|
|
501
|
-
u.ok ? (
|
|
504
|
+
u.ok ? (U({
|
|
502
505
|
status: "success",
|
|
503
506
|
key: o,
|
|
504
507
|
data: u.data
|
|
505
|
-
}), e(u.data)) : (
|
|
508
|
+
}), e(u.data)) : (U({
|
|
506
509
|
status: "error",
|
|
507
510
|
key: o,
|
|
508
511
|
error: u.error
|
|
509
512
|
}), C(u.error) || e(void 0));
|
|
510
513
|
return;
|
|
511
514
|
}
|
|
512
|
-
|
|
515
|
+
U({
|
|
513
516
|
status: "pending",
|
|
514
517
|
key: o
|
|
515
518
|
}), i && _(m);
|
|
@@ -517,11 +520,11 @@ var h = {
|
|
|
517
520
|
return Promise.all(f).then(() => {
|
|
518
521
|
if (d) return;
|
|
519
522
|
let t = l();
|
|
520
|
-
t && (t.ok ? (
|
|
523
|
+
t && (t.ok ? (U({
|
|
521
524
|
status: "success",
|
|
522
525
|
key: o,
|
|
523
526
|
data: t.data
|
|
524
|
-
}), e(t.data)) : (
|
|
527
|
+
}), e(t.data)) : (U({
|
|
525
528
|
status: "error",
|
|
526
529
|
key: o,
|
|
527
530
|
error: t.error
|
|
@@ -534,36 +537,36 @@ var h = {
|
|
|
534
537
|
z,
|
|
535
538
|
m
|
|
536
539
|
]);
|
|
537
|
-
let
|
|
540
|
+
let K = G.data?.page, q = g === m, J = G.pathname === g, Ne = J ? G.data?.page : void 0, Fe = V?.loader === void 0 ? I : Ne, Ie = ve(), Y = u(() => {
|
|
538
541
|
if (!B) return null;
|
|
539
|
-
let e = B.params.locale ??
|
|
540
|
-
return ce(V?.meta, B.params,
|
|
542
|
+
let e = B.params.locale ?? Ie;
|
|
543
|
+
return ce(V?.meta, B.params, K, e);
|
|
541
544
|
}, [
|
|
542
545
|
B,
|
|
543
546
|
V,
|
|
544
|
-
|
|
545
|
-
|
|
547
|
+
K,
|
|
548
|
+
Ie
|
|
546
549
|
]);
|
|
547
|
-
l(() => ye(
|
|
548
|
-
let [
|
|
550
|
+
l(() => ye(Y), [Y]);
|
|
551
|
+
let [X, Z] = f(""), Q = d(!1), [Le, Re] = f(!1);
|
|
549
552
|
l(() => {
|
|
550
553
|
if (!Q.current) {
|
|
551
|
-
Q.current = !0,
|
|
554
|
+
Q.current = !0, Re(!0);
|
|
552
555
|
return;
|
|
553
556
|
}
|
|
554
|
-
let e =
|
|
557
|
+
let e = Y?.title ?? (typeof document < "u" ? document.title : "");
|
|
555
558
|
Z(e && e.length > 0 ? e : g);
|
|
556
|
-
}, [g,
|
|
559
|
+
}, [g, Y]), l(() => {
|
|
557
560
|
let e = E.current;
|
|
558
561
|
e && (E.current = null, pe(() => window.scrollTo(e.x, e.y)));
|
|
559
562
|
}, [g]);
|
|
560
|
-
let
|
|
563
|
+
let ze = u(() => ({
|
|
561
564
|
pathname: g,
|
|
562
565
|
search: v,
|
|
563
566
|
navigate: M,
|
|
564
567
|
params: B?.params ?? {},
|
|
565
|
-
prefetch:
|
|
566
|
-
loaderData:
|
|
568
|
+
prefetch: Oe,
|
|
569
|
+
loaderData: K,
|
|
567
570
|
registerBlocker: re,
|
|
568
571
|
blocked: ne
|
|
569
572
|
}), [
|
|
@@ -571,8 +574,8 @@ var h = {
|
|
|
571
574
|
v,
|
|
572
575
|
M,
|
|
573
576
|
B,
|
|
574
|
-
|
|
575
|
-
|
|
577
|
+
Oe,
|
|
578
|
+
K,
|
|
576
579
|
re,
|
|
577
580
|
ne
|
|
578
581
|
]);
|
|
@@ -591,47 +594,47 @@ var h = {
|
|
|
591
594
|
ee({
|
|
592
595
|
pathname: g,
|
|
593
596
|
params: B?.params ?? {},
|
|
594
|
-
loaderData:
|
|
597
|
+
loaderData: K
|
|
595
598
|
});
|
|
596
599
|
}, [
|
|
597
600
|
g,
|
|
598
601
|
B,
|
|
599
|
-
|
|
602
|
+
K
|
|
600
603
|
]), l(() => {
|
|
601
|
-
if (
|
|
604
|
+
if (H.status === "pending") return t({
|
|
602
605
|
id: "voltro:router:loader",
|
|
603
606
|
kind: "loading",
|
|
604
607
|
label: "Loading…"
|
|
605
608
|
});
|
|
606
|
-
}, [
|
|
607
|
-
if (
|
|
609
|
+
}, [H.status]), l(() => {
|
|
610
|
+
if (H.status === "error") return t({
|
|
608
611
|
id: "voltro:router:loader-error",
|
|
609
612
|
kind: "error",
|
|
610
613
|
label: "Loader failed"
|
|
611
614
|
});
|
|
612
|
-
}, [
|
|
613
|
-
|
|
614
|
-
}, [
|
|
615
|
-
let
|
|
615
|
+
}, [H.status]), l(() => {
|
|
616
|
+
H.status === "error" && C(H.error) && M(H.error.location, { replace: !0 });
|
|
617
|
+
}, [H, M]);
|
|
618
|
+
let Be = () => {
|
|
616
619
|
let e = le(i, g);
|
|
617
620
|
if (e) {
|
|
618
621
|
let { Component: t, chain: n } = e;
|
|
619
|
-
return
|
|
622
|
+
return De(n, /* @__PURE__ */ p(t, {}), g, c);
|
|
620
623
|
}
|
|
621
624
|
return /* @__PURE__ */ p(o, {});
|
|
622
|
-
},
|
|
623
|
-
if (!B) $ =
|
|
624
|
-
else if (te(
|
|
625
|
+
}, Ve = q && B && H.status === "error" ? H.error : void 0, $;
|
|
626
|
+
if (!B) $ = Be();
|
|
627
|
+
else if (te(Ve)) $ = Be();
|
|
625
628
|
else {
|
|
626
629
|
let e = B.route.chain, t = e ? e.length - 1 : -1, n = V?.ErrorBoundary ?? ue(e, "Error", t) ?? c, r;
|
|
627
|
-
if (
|
|
628
|
-
else if (
|
|
629
|
-
error:
|
|
630
|
+
if (Ae) r = /* @__PURE__ */ p(Ce, {});
|
|
631
|
+
else if (q && H.status === "error" && !C(H.error)) r = /* @__PURE__ */ p(n, {
|
|
632
|
+
error: H.error,
|
|
630
633
|
reset: () => {
|
|
631
|
-
x.current.invalidate(B.route.pattern), h((e) => e),
|
|
634
|
+
x.current.invalidate(B.route.pattern), h((e) => e), U({ status: "idle" });
|
|
632
635
|
}
|
|
633
636
|
});
|
|
634
|
-
else if (
|
|
637
|
+
else if (q && H.status === "pending") {
|
|
635
638
|
let i = V?.Pending ?? ue(e, "Pending", t);
|
|
636
639
|
if (i) r = /* @__PURE__ */ p(i, {});
|
|
637
640
|
else if (V?.Component) {
|
|
@@ -640,7 +643,7 @@ var h = {
|
|
|
640
643
|
resetKey: g,
|
|
641
644
|
Fallback: n,
|
|
642
645
|
children: /* @__PURE__ */ p(L.Provider, {
|
|
643
|
-
value:
|
|
646
|
+
value: Fe,
|
|
644
647
|
children: /* @__PURE__ */ p(e, {})
|
|
645
648
|
})
|
|
646
649
|
});
|
|
@@ -651,30 +654,30 @@ var h = {
|
|
|
651
654
|
resetKey: g,
|
|
652
655
|
Fallback: n,
|
|
653
656
|
children: /* @__PURE__ */ p(L.Provider, {
|
|
654
|
-
value:
|
|
657
|
+
value: Fe,
|
|
655
658
|
children: /* @__PURE__ */ p(e, {})
|
|
656
659
|
})
|
|
657
660
|
}) : null;
|
|
658
661
|
}
|
|
659
|
-
$ =
|
|
660
|
-
if (
|
|
662
|
+
$ = De(e, r, g, c, (t) => {
|
|
663
|
+
if (J) return G.data?.segments[t];
|
|
661
664
|
let n = e?.[t]?.Layout;
|
|
662
|
-
return n !== void 0 && n ===
|
|
665
|
+
return n !== void 0 && n === G.chain?.[t]?.Layout ? G.data?.segments[t] : void 0;
|
|
663
666
|
});
|
|
664
667
|
}
|
|
665
668
|
return /* @__PURE__ */ p(we, {
|
|
666
|
-
value:
|
|
667
|
-
announcer:
|
|
669
|
+
value: ze,
|
|
670
|
+
announcer: Le ? /* @__PURE__ */ p(Ee, { message: X }) : null,
|
|
668
671
|
children: $
|
|
669
672
|
});
|
|
670
673
|
}, we = ({ value: e, announcer: t, children: n }) => /* @__PURE__ */ m(P.Provider, {
|
|
671
674
|
value: e,
|
|
672
675
|
children: [n, t]
|
|
673
|
-
}),
|
|
676
|
+
}), Te = (e, t) => /* @__PURE__ */ p(we, {
|
|
674
677
|
value: e,
|
|
675
678
|
announcer: null,
|
|
676
679
|
children: t
|
|
677
|
-
}),
|
|
680
|
+
}), z = {
|
|
678
681
|
position: "absolute",
|
|
679
682
|
width: 1,
|
|
680
683
|
height: 1,
|
|
@@ -684,14 +687,14 @@ var h = {
|
|
|
684
687
|
clip: "rect(0, 0, 0, 0)",
|
|
685
688
|
whiteSpace: "nowrap",
|
|
686
689
|
border: 0
|
|
687
|
-
},
|
|
690
|
+
}, Ee = ({ message: e }) => /* @__PURE__ */ p("div", {
|
|
688
691
|
"data-vweb-route-announcer": "",
|
|
689
692
|
role: "status",
|
|
690
693
|
"aria-live": "assertive",
|
|
691
694
|
"aria-atomic": "true",
|
|
692
|
-
style:
|
|
695
|
+
style: z,
|
|
693
696
|
children: e
|
|
694
|
-
}),
|
|
697
|
+
}), De = (e, t, n, r, i) => {
|
|
695
698
|
if (!e || e.length === 0) return t;
|
|
696
699
|
let a = t;
|
|
697
700
|
for (let t = e.length - 1; t >= 0; t--) {
|
|
@@ -713,14 +716,14 @@ var h = {
|
|
|
713
716
|
}
|
|
714
717
|
}
|
|
715
718
|
return a;
|
|
716
|
-
},
|
|
719
|
+
}, B = () => F().pathname, V = () => F().navigate, Oe = () => F().params, H = () => {
|
|
717
720
|
let e = c(L);
|
|
718
721
|
if (e === I) throw Error("useLoaderData() was called at a level that declares no `loader`. Export `loader` from this page/layout, or — if this component is shared between routes that have one and routes that do not — read it with `useOptionalLoaderData()`, which returns `undefined` here instead of throwing. The React component stack below names the component.");
|
|
719
722
|
return e;
|
|
720
|
-
},
|
|
723
|
+
}, U = () => {
|
|
721
724
|
let e = c(L);
|
|
722
725
|
return e === I ? void 0 : e;
|
|
723
|
-
},
|
|
726
|
+
}, W = () => F().prefetch, ke = (e) => {
|
|
724
727
|
let { registerBlocker: t, blocked: n } = F(), r = d(Symbol("voltro:blocker")), i = d(e);
|
|
725
728
|
return i.current = e, l(() => {
|
|
726
729
|
let e = r.current;
|
|
@@ -734,22 +737,22 @@ var h = {
|
|
|
734
737
|
retry: n.retry,
|
|
735
738
|
reset: n.reset
|
|
736
739
|
} : { blocked: !1 };
|
|
737
|
-
},
|
|
740
|
+
}, Ae = (e) => e instanceof URLSearchParams ? e : new URLSearchParams(e), je = () => {
|
|
738
741
|
let { navigate: e } = F();
|
|
739
742
|
return s((t, n) => {
|
|
740
|
-
let r = new URLSearchParams(typeof window < "u" ? window.location.search : ""), i =
|
|
743
|
+
let r = new URLSearchParams(typeof window < "u" ? window.location.search : ""), i = Ae(typeof t == "function" ? t(r) : t).toString(), a = typeof window < "u" ? window.location.pathname : "/", o = i ? `${a}?${i}` : a;
|
|
741
744
|
e(o, {
|
|
742
745
|
replace: !n?.push,
|
|
743
746
|
...n?.scroll === void 0 ? {} : { scroll: n.scroll }
|
|
744
747
|
});
|
|
745
748
|
}, [e]);
|
|
746
|
-
},
|
|
749
|
+
}, G = (e) => e, Me = (e, t) => {
|
|
747
750
|
let n = new URLSearchParams();
|
|
748
751
|
for (let [e, r] of Object.entries(t)) r !== void 0 && n.append(e, String(r));
|
|
749
752
|
let r = n.toString();
|
|
750
753
|
return r ? `${e}?${r}` : e;
|
|
751
|
-
},
|
|
752
|
-
let f =
|
|
754
|
+
}, K = (e, t) => `${e}#${t.replace(/^#/, "")}`, q = (e) => /^([a-z][a-z0-9+.-]*:|\/\/|#)/i.test(e), J = ({ to: e, children: t, onClick: n, prefetch: r = !1, replace: i = !1, onMouseEnter: a, onFocus: o, ref: c, ...u }) => {
|
|
755
|
+
let f = V(), m = W(), h = q(e), g = d(null), ee = s((e) => {
|
|
753
756
|
g.current = e, typeof c == "function" ? c(e) : c && (c.current = e);
|
|
754
757
|
}, [c]);
|
|
755
758
|
l(() => {
|
|
@@ -782,10 +785,10 @@ var h = {
|
|
|
782
785
|
onFocus: y,
|
|
783
786
|
children: t
|
|
784
787
|
});
|
|
785
|
-
},
|
|
788
|
+
}, Ne = (e) => J({
|
|
786
789
|
...e,
|
|
787
790
|
to: e.to
|
|
788
|
-
}),
|
|
791
|
+
}), Pe = (e) => ({
|
|
789
792
|
Component: e.default,
|
|
790
793
|
meta: e.meta,
|
|
791
794
|
loader: e.loader,
|
|
@@ -793,27 +796,27 @@ var h = {
|
|
|
793
796
|
Pending: e.Pending,
|
|
794
797
|
renderMode: e.renderMode,
|
|
795
798
|
interactive: e.interactive
|
|
796
|
-
}),
|
|
799
|
+
}), Fe = (e, t, n = {}) => ({
|
|
797
800
|
pattern: e,
|
|
798
|
-
...
|
|
801
|
+
...Pe(t),
|
|
799
802
|
chain: n.chain
|
|
800
|
-
}),
|
|
803
|
+
}), Ie = (e, t, n = {}) => ({
|
|
801
804
|
pattern: e,
|
|
802
805
|
load: t,
|
|
803
806
|
chain: n.chain
|
|
804
|
-
}),
|
|
807
|
+
}), Y = async (e, t) => {
|
|
805
808
|
let n = O(e.map(ie), t)?.route.load;
|
|
806
809
|
if (n) try {
|
|
807
810
|
await n();
|
|
808
811
|
} catch {}
|
|
809
|
-
},
|
|
810
|
-
let e =
|
|
812
|
+
}, X = e("serverRequest", null), Z = () => c(X), Q = () => {
|
|
813
|
+
let e = Z();
|
|
811
814
|
if (e !== null) {
|
|
812
815
|
let t = e.url.indexOf("?");
|
|
813
816
|
return new URLSearchParams(t >= 0 ? e.url.slice(t + 1) : "");
|
|
814
817
|
}
|
|
815
818
|
return typeof window < "u" ? new URLSearchParams(window.location.search) : new URLSearchParams();
|
|
816
|
-
}, Le = ({ value: e, children: t }) => /* @__PURE__ */ p(
|
|
819
|
+
}, Le = ({ value: e, children: t }) => /* @__PURE__ */ p(X.Provider, {
|
|
817
820
|
value: e,
|
|
818
821
|
children: t
|
|
819
822
|
}), Re = (e) => {
|
|
@@ -834,4 +837,4 @@ var h = {
|
|
|
834
837
|
return t;
|
|
835
838
|
};
|
|
836
839
|
//#endregion
|
|
837
|
-
export {
|
|
840
|
+
export { H as A, b as B, Y as C, oe as D, ce as E, W as F, _ as G, C as H, je as I, ee as K, K as L, V as M, U as N, ae as O, Oe as P, Me as R, Fe as S, fe as T, x as U, te as V, S as W, G as _, Z as a, k as b, L as c, Ce as d, Ne as f, ie as g, P as h, Q as i, B as j, ke as k, I as l, R as m, Le as n, J as o, ne as p, v as q, Re as r, de as s, X as t, Se as u, le as v, Te as w, O as x, Ie as y, y as z };
|
package/dist/ssr.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { ProcedureOutput } from '@voltro/client';
|
|
|
6
6
|
import { ProcedureTypeMap } from '@voltro/client';
|
|
7
7
|
import { ReactNode } from 'react';
|
|
8
8
|
import { seedPreloadedSubscription } from '@voltro/client';
|
|
9
|
+
import { seedPreloadedSubscriptionFailure } from '@voltro/client';
|
|
9
10
|
import { StoreSeed } from '@voltro/client';
|
|
10
11
|
import { StoreSeedBag } from '@voltro/client';
|
|
11
12
|
|
|
@@ -210,9 +211,47 @@ declare type InteractiveMode = 'full' | 'islands' | 'none';
|
|
|
210
211
|
/** True for exactly the object {@link defer} returns. */
|
|
211
212
|
export declare const isDeferredLoaderResult: (value: unknown) => value is DeferredLoaderResult;
|
|
212
213
|
|
|
214
|
+
/**
|
|
215
|
+
* What a `loader` receives.
|
|
216
|
+
*
|
|
217
|
+
* **It runs on the server AND again in the browser.** A loader is not a
|
|
218
|
+
* server-only hook: it runs during SSR for the first paint, and then runs
|
|
219
|
+
* AGAIN, in the browser, on every in-app navigation to the route. Same
|
|
220
|
+
* function, different environment.
|
|
221
|
+
*
|
|
222
|
+
* That precondition was never written down, and a consumer read "runs once per
|
|
223
|
+
* request" into the gap — which is the reading the wording invites. It cost
|
|
224
|
+
* them two days, and the reason it survived that long is the nastiest part: a
|
|
225
|
+
* client-only failure is invisible to every probe that does not NAVIGATE. A
|
|
226
|
+
* fresh page load, a `curl`, any SSR check goes through the server path and
|
|
227
|
+
* passes. Only clicking a link inside the running app reaches the other one.
|
|
228
|
+
*
|
|
229
|
+
* So anything server-only in a loader must be guarded by {@link isServer}.
|
|
230
|
+
*/
|
|
213
231
|
declare interface LoaderContext<Procedures = unknown> {
|
|
214
232
|
readonly params: Readonly<Record<string, string>>;
|
|
215
233
|
readonly pathname: string;
|
|
234
|
+
/**
|
|
235
|
+
* `true` when this invocation is the SERVER one (SSR under `voltro dev` or
|
|
236
|
+
* `voltro start`), `false` in the browser.
|
|
237
|
+
*
|
|
238
|
+
* Exists because the alternatives are traps. `query` is absent in the browser
|
|
239
|
+
* and so reads as a discriminator, but branching on the ABSENCE OF A FUNCTION
|
|
240
|
+
* says nothing about why it is absent and breaks the moment anything else
|
|
241
|
+
* becomes conditional. `headers` is worse: it is `{}` in the browser, not
|
|
242
|
+
* `undefined`, so `ctx.headers ? …` is TRUE on both paths — a consumer
|
|
243
|
+
* checked exactly that and it silently did nothing.
|
|
244
|
+
*
|
|
245
|
+
* export const loader = async (ctx: LoaderContext) => {
|
|
246
|
+
* if (ctx.isServer) seedStore(prefs, await ctx.query!('prefs.get'))
|
|
247
|
+
* return null
|
|
248
|
+
* }
|
|
249
|
+
*
|
|
250
|
+
* REQUIRED, not optional: an optional boolean is omissible, and a server path
|
|
251
|
+
* that forgot it would read as `undefined` — falsy — and claim to be the
|
|
252
|
+
* browser. Required means the compiler names every construction site.
|
|
253
|
+
*/
|
|
254
|
+
readonly isServer: boolean;
|
|
216
255
|
/**
|
|
217
256
|
* The raw query string, INCLUDING the leading `?`, or `''` when there is
|
|
218
257
|
* none. Filled on every path — client navigation, `voltro dev` SSR and
|
|
@@ -676,6 +715,8 @@ declare interface RouteSegment {
|
|
|
676
715
|
|
|
677
716
|
export { seedPreloadedSubscription }
|
|
678
717
|
|
|
718
|
+
export { seedPreloadedSubscriptionFailure }
|
|
719
|
+
|
|
679
720
|
/**
|
|
680
721
|
* Serialise arbitrary data for inlining into an HTML `<script>` body.
|
|
681
722
|
*
|