@voltro/web 0.52.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 +229 -0
- package/THIRD-PARTY-NOTICES.md +281 -1
- package/dist/index.d.ts +103 -4
- package/dist/index.js +180 -70
- package/dist/mount.js +1 -1
- package/dist/{routerState-DAT472IC.js → routerState-Cr6fTbka.js} +4 -2
- package/dist/serverContext-BwzZ6Q7d.js +1148 -0
- package/dist/ssr.d.ts +29 -0
- package/dist/ssr.js +45 -45
- package/package.json +3 -3
- package/dist/serverContext-CzmZZwuQ.js +0 -910
package/dist/ssr.d.ts
CHANGED
|
@@ -94,12 +94,25 @@ export declare interface DeferralTarget {
|
|
|
94
94
|
* Absent for every full-page render, where `renderMode` alone decides.
|
|
95
95
|
*/
|
|
96
96
|
readonly layoutShell?: 'stream' | 'artefact' | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Partial prerendering: the page EXPORTED `ppr = true`. Makes `defer()` on
|
|
99
|
+
* `renderMode: 'isr'` legal — the cached SHELL renders the eager fields plus
|
|
100
|
+
* each `<Await>` fallback (credential-free, fail-closed), and the deferred
|
|
101
|
+
* HOLES run per request with the full request context, appended to the same
|
|
102
|
+
* response as registry settle scripts. The client reveals them through
|
|
103
|
+
* hydration — no React resume, no cached reveal scripts.
|
|
104
|
+
*/
|
|
105
|
+
readonly ppr?: boolean;
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
/** Brand key on the object `defer()` returns. A single explicit container
|
|
100
109
|
* check — NOT a scan of arbitrary loader results for markers by shape. */
|
|
101
110
|
declare const DEFERRED_RESULT_TAG: "__voltroDeferredLoaderResult";
|
|
102
111
|
|
|
112
|
+
/** Stable registry id for one deferred field. `scope` is `'page'` or the
|
|
113
|
+
* layout's chain index — the same index the router-state payload keys by. */
|
|
114
|
+
export declare const deferredId: (scope: "page" | number, key: string) => string;
|
|
115
|
+
|
|
103
116
|
/** What a loader returns when it defers part of its data. Opaque to user
|
|
104
117
|
* code: build it with {@link defer}, read it with `useLoaderData()`. */
|
|
105
118
|
declare interface DeferredLoaderResult<TEager extends object = object, TDeferred extends Record<string, Promise<unknown>> = Record<string, Promise<unknown>>> {
|
|
@@ -112,6 +125,9 @@ declare interface DeferredLoaderResult<TEager extends object = object, TDeferred
|
|
|
112
125
|
readonly deferred: TDeferred;
|
|
113
126
|
}
|
|
114
127
|
|
|
128
|
+
/** The body of the `<script>` `<Await>` emits when its promise resolves. */
|
|
129
|
+
export declare const deferredSettleScript: (id: string, value: unknown) => string;
|
|
130
|
+
|
|
115
131
|
/** Build the wire payload from what the server render was given. */
|
|
116
132
|
export declare const encodeRouterState: (input: RouterStateInput) => InlinedRouterState;
|
|
117
133
|
|
|
@@ -373,6 +389,19 @@ declare interface PageDescriptor<TLoaderData = unknown> {
|
|
|
373
389
|
* set this to `'islands'` so only marked interactive zones
|
|
374
390
|
* hydrate; the rest stays pure static HTML. */
|
|
375
391
|
readonly interactive?: InteractiveMode | undefined;
|
|
392
|
+
/**
|
|
393
|
+
* Intercepting route (modal-with-URL): when a SOFT navigation reaches this
|
|
394
|
+
* page FROM one of the `from` route patterns, the page renders as an
|
|
395
|
+
* OVERLAY above the still-mounted origin page instead of replacing it —
|
|
396
|
+
* URL changes, Back closes the overlay, a hard load of the same URL
|
|
397
|
+
* renders the page standalone. `from` is one or more route PATTERNS
|
|
398
|
+
* (`'/photos'`, `'/albums/[id]'`); a soft navigation from any other route
|
|
399
|
+
* renders standalone. Full-hydration pages only (`interactive: 'full'`) —
|
|
400
|
+
* islands/none pages have no client router to intercept with.
|
|
401
|
+
*/
|
|
402
|
+
readonly intercept?: {
|
|
403
|
+
readonly from: string | ReadonlyArray<string>;
|
|
404
|
+
} | undefined;
|
|
376
405
|
}
|
|
377
406
|
|
|
378
407
|
declare interface PageMeta {
|
package/dist/ssr.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import { s as e } from "./defaultFallbacks-SQ45vAhz.js";
|
|
2
|
-
import { _ as t, a as n,
|
|
3
|
-
import { C as
|
|
4
|
-
import { createElement as
|
|
5
|
-
import { ServerRequestContext as
|
|
6
|
-
import { renderToPipeableStream as
|
|
7
|
-
import { AsyncLocalStorage as
|
|
2
|
+
import { _ as t, a as n, f as r, h as i, m as a, n as o, s, t as c, u as l, v as u } from "./routerState-Cr6fTbka.js";
|
|
3
|
+
import { C as d, a as f, c as p, o as m, t as h, x as g } from "./serverContext-BwzZ6Q7d.js";
|
|
4
|
+
import { createElement as _ } from "react";
|
|
5
|
+
import { ServerRequestContext as v, makePreloadSeedBag as y, makeStoreSeedBag as b, seedPreloadedSubscription as x, seedPreloadedSubscriptionFailure as S, setPreloadSeedResolver as C, setStoreSeedResolver as w } from "@voltro/client";
|
|
6
|
+
import { renderToPipeableStream as T, renderToString as E } from "react-dom/server";
|
|
7
|
+
import { AsyncLocalStorage as D } from "node:async_hooks";
|
|
8
8
|
//#region src/storeSeedScope.ts
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
var
|
|
9
|
+
var O = new D();
|
|
10
|
+
w(() => O.getStore()?.store ?? null), C(() => O.getStore()?.preload ?? null);
|
|
11
|
+
var k = async (e) => {
|
|
12
12
|
let t = {
|
|
13
|
-
store:
|
|
14
|
-
preload:
|
|
13
|
+
store: b(),
|
|
14
|
+
preload: y()
|
|
15
15
|
};
|
|
16
16
|
return {
|
|
17
|
-
result: await
|
|
17
|
+
result: await O.run(t, e),
|
|
18
18
|
storeSeeds: t.store.seeds,
|
|
19
19
|
preloadSeeds: t.preload.seeds
|
|
20
20
|
};
|
|
21
|
-
},
|
|
21
|
+
}, A = () => {
|
|
22
22
|
let e = {
|
|
23
|
-
store:
|
|
24
|
-
preload:
|
|
23
|
+
store: b(),
|
|
24
|
+
preload: y()
|
|
25
25
|
};
|
|
26
|
-
return
|
|
27
|
-
},
|
|
28
|
-
let t =
|
|
26
|
+
return O.enterWith(e), e.store;
|
|
27
|
+
}, j = () => O.getStore()?.store.seeds ?? null, M = () => O.getStore()?.preload.seeds ?? null, N = (e) => {
|
|
28
|
+
let t = j(), r = M(), i = e.storeSeeds !== void 0 || t === null || t.length === 0 ? e : {
|
|
29
29
|
...e,
|
|
30
30
|
storeSeeds: t
|
|
31
31
|
};
|
|
@@ -33,19 +33,19 @@ var D = async (e) => {
|
|
|
33
33
|
...i,
|
|
34
34
|
preloadSeeds: r
|
|
35
35
|
});
|
|
36
|
-
},
|
|
37
|
-
let a =
|
|
36
|
+
}, P = (e, t, n, r, i) => {
|
|
37
|
+
let a = _(f.Provider, { value: i ? n : m }, _(e));
|
|
38
38
|
if (!t) return a;
|
|
39
39
|
for (let e = t.length - 1; e >= 0; e--) {
|
|
40
40
|
let n = t[e];
|
|
41
41
|
if (n.Layout) {
|
|
42
42
|
let t = n.Layout;
|
|
43
|
-
a =
|
|
43
|
+
a = _(f.Provider, { value: n.loader === void 0 ? m : r(e) }, _(t, { children: a }));
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
return a;
|
|
47
|
-
},
|
|
48
|
-
let { descriptor: n, params: r, pathname: i, search: a, loaderData: o, segmentLoaderData: s, requestContext: c, outerWrap:
|
|
47
|
+
}, F = (t) => {
|
|
48
|
+
let { descriptor: n, params: r, pathname: i, search: a, loaderData: o, segmentLoaderData: s, requestContext: c, outerWrap: l, locale: u, pageSlot: f } = t, m = d(n.meta, r, o, u), h = {
|
|
49
49
|
pathname: i,
|
|
50
50
|
search: a ?? "",
|
|
51
51
|
params: r,
|
|
@@ -56,26 +56,26 @@ var D = async (e) => {
|
|
|
56
56
|
prefetch: () => {},
|
|
57
57
|
registerBlocker: () => () => {},
|
|
58
58
|
blocked: null
|
|
59
|
-
}, y =
|
|
59
|
+
}, y = f ? p : n.Component;
|
|
60
60
|
if (!y) throw Error(`SSR received a descriptor with no Component for "${i}". Lazy page routes are a client-only optimization and must not be used on the server.`);
|
|
61
|
-
let b =
|
|
62
|
-
return b =
|
|
61
|
+
let b = g(h, P(y, n.chain, f ? void 0 : o, (e) => s?.[e], !f && n.loader !== void 0));
|
|
62
|
+
return b = _(e, {
|
|
63
63
|
chrome: null,
|
|
64
64
|
children: b
|
|
65
|
-
}), c && (b =
|
|
65
|
+
}), c && (b = _(v.Provider, { value: c }, b)), l && (b = l(b)), {
|
|
66
66
|
tree: b,
|
|
67
|
-
meta:
|
|
67
|
+
meta: m
|
|
68
68
|
};
|
|
69
|
-
},
|
|
70
|
-
let { tree: t, meta: n } =
|
|
69
|
+
}, I = (e) => {
|
|
70
|
+
let { tree: t, meta: n } = F(e);
|
|
71
71
|
return {
|
|
72
|
-
html:
|
|
72
|
+
html: E(t),
|
|
73
73
|
meta: n
|
|
74
74
|
};
|
|
75
|
-
},
|
|
76
|
-
let { tree: t, meta: n } =
|
|
75
|
+
}, L = (e) => {
|
|
76
|
+
let { tree: t, meta: n } = F(e);
|
|
77
77
|
return {
|
|
78
|
-
stream:
|
|
78
|
+
stream: T(t, {
|
|
79
79
|
...e.bootstrapModules ? { bootstrapModules: [...e.bootstrapModules] } : {},
|
|
80
80
|
...e.nonce === void 0 ? {} : { nonce: e.nonce },
|
|
81
81
|
...e.onShellReady ? { onShellReady: e.onShellReady } : {},
|
|
@@ -84,20 +84,20 @@ var D = async (e) => {
|
|
|
84
84
|
}),
|
|
85
85
|
meta: n
|
|
86
86
|
};
|
|
87
|
-
},
|
|
87
|
+
}, R = (e) => {
|
|
88
88
|
if (!e) return "";
|
|
89
89
|
let t = [];
|
|
90
|
-
if (typeof e.title == "string" && t.push(`<title>${
|
|
91
|
-
let e = n.name ? `name="${
|
|
92
|
-
e && t.push(`<meta ${e} content="${
|
|
90
|
+
if (typeof e.title == "string" && t.push(`<title>${z(e.title)}</title>`), e.description && t.push(`<meta name="description" content="${B(e.description)}" />`), e.noIndex && t.push("<meta name=\"robots\" content=\"noindex, nofollow\" />"), e.canonical && t.push(`<link rel="canonical" href="${B(e.canonical)}" />`), e.tags) for (let n of e.tags) {
|
|
91
|
+
let e = n.name ? `name="${B(n.name)}"` : n.property ? `property="${B(n.property)}"` : "";
|
|
92
|
+
e && t.push(`<meta ${e} content="${B(n.content)}" />`);
|
|
93
93
|
}
|
|
94
94
|
if (e.links) for (let n of e.links) {
|
|
95
95
|
let e = [
|
|
96
|
-
`rel="${
|
|
97
|
-
`href="${
|
|
98
|
-
n.hreflang ? `hreflang="${
|
|
99
|
-
n.type ? `type="${
|
|
100
|
-
n.title ? `title="${
|
|
96
|
+
`rel="${B(n.rel)}"`,
|
|
97
|
+
`href="${B(n.href)}"`,
|
|
98
|
+
n.hreflang ? `hreflang="${B(n.hreflang)}"` : "",
|
|
99
|
+
n.type ? `type="${B(n.type)}"` : "",
|
|
100
|
+
n.title ? `title="${B(n.title)}"` : ""
|
|
101
101
|
].filter(Boolean).join(" ");
|
|
102
102
|
t.push(`<link ${e} />`);
|
|
103
103
|
}
|
|
@@ -106,6 +106,6 @@ var D = async (e) => {
|
|
|
106
106
|
t.push(`<script type="application/ld+json" data-voltro-page-jsonld>${e}<\/script>`);
|
|
107
107
|
}
|
|
108
108
|
return t.join("\n ");
|
|
109
|
-
},
|
|
109
|
+
}, z = (e) => e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"), B = (e) => e.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
110
110
|
//#endregion
|
|
111
|
-
export { c as ROUTER_STATE_SCRIPT_ID, s as assertDeferralSupported,
|
|
111
|
+
export { c as ROUTER_STATE_SCRIPT_ID, s as assertDeferralSupported, A as beginStoreSeeds, M as currentPreloadSeeds, j as currentStoreSeeds, l as deferredId, r as deferredSettleScript, o as encodeRouterState, a as isDeferredLoaderResult, h as parseCookieHeader, i as prepareDeferredLoaderData, t as renderDeferredRegistryScript, R as renderMetaToHtml, I as renderPageToHtml, L as renderPageToStream, N as renderRouterStateScript, x as seedPreloadedSubscription, S as seedPreloadedSubscriptionFailure, u as serialiseStateForInlining, k as withStoreSeeds };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "The Voltro web framework — file-based routing, render modes (SSR / SSG / islands), the page-export contract, data hooks, and the browser mount.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"node": ">=24.0.0"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@voltro/client": "0.
|
|
67
|
-
"@voltro/ui": "0.
|
|
66
|
+
"@voltro/client": "0.53.0",
|
|
67
|
+
"@voltro/ui": "0.53.0"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"@effect/platform": "^0.97.0",
|