@rsc-kit/core 0.1.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 +95 -0
- package/SECURITY.md +60 -0
- package/dist/action.d.ts +90 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/action.js +137 -0
- package/dist/action.js.map +1 -0
- package/dist/build-rsc-vite.d.ts +39 -0
- package/dist/build-rsc-vite.d.ts.map +1 -0
- package/dist/build-rsc-vite.js +172 -0
- package/dist/build-rsc-vite.js.map +1 -0
- package/dist/cache.d.ts +25 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +108 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +85 -0
- package/dist/cli.js.map +1 -0
- package/dist/compile.d.ts +55 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +141 -0
- package/dist/compile.js.map +1 -0
- package/dist/devServer.d.ts +18 -0
- package/dist/devServer.d.ts.map +1 -0
- package/dist/devServer.js +70 -0
- package/dist/devServer.js.map +1 -0
- package/dist/devUrls.d.ts +11 -0
- package/dist/devUrls.d.ts.map +1 -0
- package/dist/devUrls.js +68 -0
- package/dist/devUrls.js.map +1 -0
- package/dist/embed.d.ts +21 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +119 -0
- package/dist/embed.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +38 -0
- package/dist/errors.js.map +1 -0
- package/dist/export.d.ts +41 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +100 -0
- package/dist/export.js.map +1 -0
- package/dist/files.d.ts +39 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +146 -0
- package/dist/files.js.map +1 -0
- package/dist/headers.d.ts +81 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +96 -0
- package/dist/headers.js.map +1 -0
- package/dist/host.d.ts +86 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +590 -0
- package/dist/host.js.map +1 -0
- package/dist/js/ActivityRouter.d.ts +47 -0
- package/dist/js/ActivityRouter.d.ts.map +1 -0
- package/dist/js/ActivityRouter.js +87 -0
- package/dist/js/ActivityRouter.js.map +1 -0
- package/dist/js/DocumentTitle.d.ts +22 -0
- package/dist/js/DocumentTitle.d.ts.map +1 -0
- package/dist/js/DocumentTitle.js +28 -0
- package/dist/js/DocumentTitle.js.map +1 -0
- package/dist/js/Form.d.ts +54 -0
- package/dist/js/Form.d.ts.map +1 -0
- package/dist/js/Form.js +225 -0
- package/dist/js/Form.js.map +1 -0
- package/dist/js/Link.d.ts +29 -0
- package/dist/js/Link.d.ts.map +1 -0
- package/dist/js/Link.js +112 -0
- package/dist/js/Link.js.map +1 -0
- package/dist/js/PathnameProvider.d.ts +8 -0
- package/dist/js/PathnameProvider.d.ts.map +1 -0
- package/dist/js/PathnameProvider.js +24 -0
- package/dist/js/PathnameProvider.js.map +1 -0
- package/dist/js/RedirectBoundary.d.ts +18 -0
- package/dist/js/RedirectBoundary.d.ts.map +1 -0
- package/dist/js/RedirectBoundary.js +34 -0
- package/dist/js/RedirectBoundary.js.map +1 -0
- package/dist/js/SegmentBoundary.d.ts +8 -0
- package/dist/js/SegmentBoundary.d.ts.map +1 -0
- package/dist/js/SegmentBoundary.js +38 -0
- package/dist/js/SegmentBoundary.js.map +1 -0
- package/dist/js/SlotBoundary.d.ts +15 -0
- package/dist/js/SlotBoundary.d.ts.map +1 -0
- package/dist/js/SlotBoundary.js +17 -0
- package/dist/js/SlotBoundary.js.map +1 -0
- package/dist/js/createViteRscApp.d.ts +8 -0
- package/dist/js/createViteRscApp.d.ts.map +1 -0
- package/dist/js/createViteRscApp.js +185 -0
- package/dist/js/createViteRscApp.js.map +1 -0
- package/dist/js/errors.d.ts +51 -0
- package/dist/js/errors.d.ts.map +1 -0
- package/dist/js/errors.js +93 -0
- package/dist/js/errors.js.map +1 -0
- package/dist/js/navigate.d.ts +118 -0
- package/dist/js/navigate.d.ts.map +1 -0
- package/dist/js/navigate.js +780 -0
- package/dist/js/navigate.js.map +1 -0
- package/dist/js/onlineStore.d.ts +23 -0
- package/dist/js/onlineStore.d.ts.map +1 -0
- package/dist/js/onlineStore.js +42 -0
- package/dist/js/onlineStore.js.map +1 -0
- package/dist/js/pagePayload.d.ts +15 -0
- package/dist/js/pagePayload.d.ts.map +1 -0
- package/dist/js/pagePayload.js +39 -0
- package/dist/js/pagePayload.js.map +1 -0
- package/dist/js/router.d.ts +29 -0
- package/dist/js/router.d.ts.map +1 -0
- package/dist/js/router.js +40 -0
- package/dist/js/router.js.map +1 -0
- package/dist/js/section.d.ts +16 -0
- package/dist/js/section.d.ts.map +1 -0
- package/dist/js/section.js +55 -0
- package/dist/js/section.js.map +1 -0
- package/dist/js/segmentStore.d.ts +69 -0
- package/dist/js/segmentStore.d.ts.map +1 -0
- package/dist/js/segmentStore.js +127 -0
- package/dist/js/segmentStore.js.map +1 -0
- package/dist/js/slotStore.d.ts +35 -0
- package/dist/js/slotStore.d.ts.map +1 -0
- package/dist/js/slotStore.js +46 -0
- package/dist/js/slotStore.js.map +1 -0
- package/dist/js/standardSchema.d.ts +47 -0
- package/dist/js/standardSchema.d.ts.map +1 -0
- package/dist/js/standardSchema.js +41 -0
- package/dist/js/standardSchema.js.map +1 -0
- package/dist/js/useForm.d.ts +43 -0
- package/dist/js/useForm.d.ts.map +1 -0
- package/dist/js/useForm.js +164 -0
- package/dist/js/useForm.js.map +1 -0
- package/dist/js/useLinkStatus.d.ts +2 -0
- package/dist/js/useLinkStatus.d.ts.map +1 -0
- package/dist/js/useLinkStatus.js +3 -0
- package/dist/js/useLinkStatus.js.map +1 -0
- package/dist/js/useOnline.d.ts +8 -0
- package/dist/js/useOnline.d.ts.map +1 -0
- package/dist/js/useOnline.js +20 -0
- package/dist/js/useOnline.js.map +1 -0
- package/dist/js/usePathname.d.ts +9 -0
- package/dist/js/usePathname.d.ts.map +1 -0
- package/dist/js/usePathname.js +32 -0
- package/dist/js/usePathname.js.map +1 -0
- package/dist/js/useSearchParams.d.ts +2 -0
- package/dist/js/useSearchParams.d.ts.map +1 -0
- package/dist/js/useSearchParams.js +60 -0
- package/dist/js/useSearchParams.js.map +1 -0
- package/dist/manifest.d.ts +66 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +13 -0
- package/dist/manifest.js.map +1 -0
- package/dist/prerender.d.ts +138 -0
- package/dist/prerender.d.ts.map +1 -0
- package/dist/prerender.js +387 -0
- package/dist/prerender.js.map +1 -0
- package/dist/redirect.d.ts +34 -0
- package/dist/redirect.d.ts.map +1 -0
- package/dist/redirect.js +108 -0
- package/dist/redirect.js.map +1 -0
- package/dist/redirectDigest.d.ts +20 -0
- package/dist/redirectDigest.d.ts.map +1 -0
- package/dist/redirectDigest.js +66 -0
- package/dist/redirectDigest.js.map +1 -0
- package/dist/request.d.ts +93 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/request.js +308 -0
- package/dist/request.js.map +1 -0
- package/dist/revalidate.d.ts +43 -0
- package/dist/revalidate.d.ts.map +1 -0
- package/dist/revalidate.js +99 -0
- package/dist/revalidate.js.map +1 -0
- package/dist/routes.d.ts +37 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +28 -0
- package/dist/routes.js.map +1 -0
- package/dist/routing.d.ts +52 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +146 -0
- package/dist/routing.js.map +1 -0
- package/dist/runtime.d.ts +36 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +86 -0
- package/dist/runtime.js.map +1 -0
- package/dist/safeUrl.d.ts +10 -0
- package/dist/safeUrl.d.ts.map +1 -0
- package/dist/safeUrl.js +40 -0
- package/dist/safeUrl.js.map +1 -0
- package/dist/streaming.d.ts +62 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +108 -0
- package/dist/streaming.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/vite.d.ts +109 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +1909 -0
- package/dist/vite.js.map +1 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +863 -0
- package/dist/worker.js.map +1 -0
- package/package.json +223 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { ManifestRoute, RouteManifest } from './manifest.js';
|
|
2
|
+
export interface PrerenderEngine {
|
|
3
|
+
manifest?(): RouteManifest;
|
|
4
|
+
getStaticParams?(component: string): Promise<Record<string, string>[] | null>;
|
|
5
|
+
handleRscPprShell(component: string, props?: Record<string, unknown>, layouts?: {
|
|
6
|
+
component: string;
|
|
7
|
+
props: Record<string, unknown>;
|
|
8
|
+
}[], loadings?: string[], parallelSlots?: Record<string, string>, pageKey?: string,
|
|
9
|
+
/** How long to render before taking what has flushed. Defaults to the full budget. */
|
|
10
|
+
budgetMs?: number): Promise<{
|
|
11
|
+
shellHtml: string;
|
|
12
|
+
timedOut: boolean;
|
|
13
|
+
usedDynamicApis: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
}>;
|
|
16
|
+
handleRsc(component: string, props?: Record<string, unknown>, callbackSocket?: string | null, layouts?: {
|
|
17
|
+
component: string;
|
|
18
|
+
props: Record<string, unknown>;
|
|
19
|
+
}[], loadings?: string[], parallelSlots?: Record<string, string>, from?: number, pageKey?: string, bootstrap?: boolean): Promise<{
|
|
20
|
+
body: string;
|
|
21
|
+
rscPayload: string;
|
|
22
|
+
clientComponents: string[];
|
|
23
|
+
}>;
|
|
24
|
+
handleRscPayload(component: string, props?: Record<string, unknown>, layouts?: {
|
|
25
|
+
component: string;
|
|
26
|
+
props: Record<string, unknown>;
|
|
27
|
+
}[], loadings?: string[], parallelSlots?: Record<string, string>, from?: number, pageKey?: string): Promise<{
|
|
28
|
+
rscPayload: string;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
export interface PrerenderOptions {
|
|
32
|
+
engine: PrerenderEngine;
|
|
33
|
+
/**
|
|
34
|
+
* Where the output goes, as a sink rather than a directory.
|
|
35
|
+
*
|
|
36
|
+
* `writeTo` in `@rsc-kit/core/files` is the one for a disk, which is what a
|
|
37
|
+
* build normally wants. A function because the read side is one — a host
|
|
38
|
+
* that supplies a reader should be able to supply the matching writer —
|
|
39
|
+
* and because a test can hand it a Map instead of a temp directory.
|
|
40
|
+
*/
|
|
41
|
+
write: (name: string, contents: string) => Promise<void> | void;
|
|
42
|
+
/** The route table. Defaults to the one the bundle carries. */
|
|
43
|
+
manifest?: RouteManifest;
|
|
44
|
+
/**
|
|
45
|
+
* Props for a page at build time.
|
|
46
|
+
*
|
|
47
|
+
* There is no request here, which is the point: anything a page needs that
|
|
48
|
+
* only a request can supply is exactly what makes it un-freezable. Defaults
|
|
49
|
+
* to the url params alone.
|
|
50
|
+
*/
|
|
51
|
+
props?: (route: ManifestRoute, params: Record<string, string>) => Record<string, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* How many routes to render at once. Defaults to 6; 1 renders sequentially.
|
|
54
|
+
*
|
|
55
|
+
* Worth lowering when the pages talk to something that will not enjoy six
|
|
56
|
+
* concurrent callers — a local database, a rate-limited API.
|
|
57
|
+
*/
|
|
58
|
+
concurrency?: number;
|
|
59
|
+
/** Identifies the build in what gets written, so a stale page can be spotted. */
|
|
60
|
+
version?: string;
|
|
61
|
+
/** Called as each url is decided, for build output. */
|
|
62
|
+
onResult?: (result: PrerenderResult) => void;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The build's refusal to store a route it cannot answer ahead of time.
|
|
66
|
+
*
|
|
67
|
+
* Thrown rather than reported, because the alternative is a category: a bucket
|
|
68
|
+
* of routes that quietly render per request, which is where the slow ones go
|
|
69
|
+
* to be forgotten. Every route is either stored or has said it will not be.
|
|
70
|
+
*/
|
|
71
|
+
export declare class NotPrerenderable extends Error {
|
|
72
|
+
readonly routes: PrerenderResult[];
|
|
73
|
+
constructor(routes: PrerenderResult[]);
|
|
74
|
+
}
|
|
75
|
+
export interface PrerenderResult {
|
|
76
|
+
url: string;
|
|
77
|
+
component: string;
|
|
78
|
+
/**
|
|
79
|
+
* frozen — the whole page is on disk.
|
|
80
|
+
* shell — the chrome is on disk and the rest is rendered per request.
|
|
81
|
+
* blocked — nothing could be stored. Fails the build.
|
|
82
|
+
* error — the render itself failed, or the build refused what it produced.
|
|
83
|
+
*
|
|
84
|
+
* There is no outcome for "rendered per request". A route that cannot be
|
|
85
|
+
* stored has its boundary in the wrong place, and the fix is to move it —
|
|
86
|
+
* not to declare the problem away, which is how the slow ones get forgotten.
|
|
87
|
+
*/
|
|
88
|
+
type: 'frozen' | 'shell' | 'blocked' | 'error';
|
|
89
|
+
reason: string | null;
|
|
90
|
+
/**
|
|
91
|
+
* Something worth knowing that is not a failure.
|
|
92
|
+
*
|
|
93
|
+
* The one that matters: a page whose only boundary is the root loading.tsx.
|
|
94
|
+
* It is stored, so the build has nothing to refuse — but the fallback that
|
|
95
|
+
* caught it belongs to the whole app rather than to this page, and every
|
|
96
|
+
* page in the app shows the same thing while this one's data arrives.
|
|
97
|
+
*/
|
|
98
|
+
warning?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The file name a route's shell is stored under, with params standing in for
|
|
102
|
+
* themselves: /posts/[slug] → posts/_slug_.
|
|
103
|
+
*
|
|
104
|
+
* A shell contains nothing that varies by param — everything that does is
|
|
105
|
+
* behind a boundary the client fills — so one shell serves every url the
|
|
106
|
+
* route matches, including the ones the app never listed.
|
|
107
|
+
*/
|
|
108
|
+
export declare function patternKey(route: ManifestRoute): string;
|
|
109
|
+
/** Close a document the render was aborted in the middle of. */
|
|
110
|
+
export declare function closeDocument(html: string): string;
|
|
111
|
+
/**
|
|
112
|
+
* The file name a url is stored under: / → index, /a/b → a/b.
|
|
113
|
+
*
|
|
114
|
+
* Refuses a key that could leave the directory it is written into. The input is
|
|
115
|
+
* whatever generateStaticParams() returned — typically slugs from a database or
|
|
116
|
+
* a CMS — so a record named `../../../../etc/cron.d/x` is an arbitrary file
|
|
117
|
+
* write on the build machine with content the same record influences.
|
|
118
|
+
*
|
|
119
|
+
* Checked here rather than in the writer, because the writer is supplied by the
|
|
120
|
+
* host: `writeTo` on disk does the obvious thing, but a KV or edge binding has
|
|
121
|
+
* no notion of a parent directory and no reason to look for one.
|
|
122
|
+
*/
|
|
123
|
+
export declare function pathKey(url: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* Substitute params into a route's segments to get a concrete url.
|
|
126
|
+
*
|
|
127
|
+
* A param is one segment, so a value carrying a slash is not a deeper url — it
|
|
128
|
+
* is a value that was never a single segment. A catch-all is the exception and
|
|
129
|
+
* is spelled as one in the route.
|
|
130
|
+
*/
|
|
131
|
+
export declare function urlFor(route: ManifestRoute, params: Record<string, string>): string;
|
|
132
|
+
export declare function urlsToBuild(manifest: RouteManifest, engine: PrerenderEngine): Promise<{
|
|
133
|
+
route: ManifestRoute;
|
|
134
|
+
params: Record<string, string>;
|
|
135
|
+
url: string;
|
|
136
|
+
}[]>;
|
|
137
|
+
export declare function prerender(options: PrerenderOptions): Promise<PrerenderResult[]>;
|
|
138
|
+
//# sourceMappingURL=prerender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prerender.d.ts","sourceRoot":"","sources":["../src/prerender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
// Rendering pages at build time, for a JavaScript host.
|
|
2
|
+
//
|
|
3
|
+
// The engine does the rendering; this decides what to render and what to do
|
|
4
|
+
// with the result. Two decisions, and both are easy to get subtly wrong:
|
|
5
|
+
//
|
|
6
|
+
// Which urls exist — a route with no params is one url, a route with params is
|
|
7
|
+
// however many `generateStaticParams` returns, and a route with params that
|
|
8
|
+
// declares none cannot be prerendered at all.
|
|
9
|
+
//
|
|
10
|
+
// Whether a page can be frozen — asked by rendering it, never declared. The
|
|
11
|
+
// shell probe replaces the host global with a promise that never resolves, so
|
|
12
|
+
// a page that reaches for request data suspends and says so by doing it. A
|
|
13
|
+
// page that simply takes too long says so by not finishing.
|
|
14
|
+
//
|
|
15
|
+
// The file layout matches the one Laravel writes, so both hosts serve the same
|
|
16
|
+
// shapes and anything that reads them works for either.
|
|
17
|
+
import { withRedirect } from './redirect.js';
|
|
18
|
+
import { withCache } from './cache.js';
|
|
19
|
+
import { requestWasRead, withRequest } from './request.js';
|
|
20
|
+
/** What a prerenderer needs from the built bundle, beyond serving a request. */
|
|
21
|
+
/**
|
|
22
|
+
* How long the root-fallback diagnostic waits before answering.
|
|
23
|
+
*
|
|
24
|
+
* Short on purpose: the question is whether anything painted, not what. See
|
|
25
|
+
* the call site.
|
|
26
|
+
*/
|
|
27
|
+
const ROOT_FALLBACK_BUDGET_MS = 200;
|
|
28
|
+
/**
|
|
29
|
+
* How many routes render at once.
|
|
30
|
+
*
|
|
31
|
+
* Each is a full React render, so this trades memory and CPU for wall time.
|
|
32
|
+
* The gain flattens almost immediately — measured on a twelve-route example:
|
|
33
|
+
* 10.2 s sequential, 4.1 s at four, 4.0 s at six, 4.0 s at twelve, beyond
|
|
34
|
+
* which one route's own serial chain is the floor.
|
|
35
|
+
*
|
|
36
|
+
* Four rather than six because the difference between them is inside the
|
|
37
|
+
* noise, and the smaller number leaves room for whatever else is running.
|
|
38
|
+
* A build is rarely the only thing on a machine — it shares CI with other
|
|
39
|
+
* jobs, and it shares a laptop with the test suite that renders its own
|
|
40
|
+
* fixtures, where six was enough to turn a two-second budget into a timeout.
|
|
41
|
+
*/
|
|
42
|
+
const DEFAULT_PRERENDER_CONCURRENCY = 4;
|
|
43
|
+
/**
|
|
44
|
+
* The build's refusal to store a route it cannot answer ahead of time.
|
|
45
|
+
*
|
|
46
|
+
* Thrown rather than reported, because the alternative is a category: a bucket
|
|
47
|
+
* of routes that quietly render per request, which is where the slow ones go
|
|
48
|
+
* to be forgotten. Every route is either stored or has said it will not be.
|
|
49
|
+
*/
|
|
50
|
+
export class NotPrerenderable extends Error {
|
|
51
|
+
routes;
|
|
52
|
+
constructor(routes) {
|
|
53
|
+
super('Some routes could not be prerendered:\n\n' +
|
|
54
|
+
routes.map((r) => ` ${r.url} — ${r.reason ?? 'failed to render'}`).join('\n') +
|
|
55
|
+
'\n\nEach one reads request data — params, headers, cookies, or the host —\n' +
|
|
56
|
+
'above every Suspense boundary, so nothing can paint without it.\n\n' +
|
|
57
|
+
'Put the part that waits inside <Suspense>, or add a loading.tsx beside\n' +
|
|
58
|
+
'the page, so there is something to store while the rest arrives.\n');
|
|
59
|
+
this.name = 'NotPrerenderable';
|
|
60
|
+
this.routes = routes;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The file name a route's shell is stored under, with params standing in for
|
|
65
|
+
* themselves: /posts/[slug] → posts/_slug_.
|
|
66
|
+
*
|
|
67
|
+
* A shell contains nothing that varies by param — everything that does is
|
|
68
|
+
* behind a boundary the client fills — so one shell serves every url the
|
|
69
|
+
* route matches, including the ones the app never listed.
|
|
70
|
+
*/
|
|
71
|
+
export function patternKey(route) {
|
|
72
|
+
const parts = route.segments.map((s) => (s.type === 'static' ? s.value : `_${s.value}_`));
|
|
73
|
+
return parts.join('/') || 'index';
|
|
74
|
+
}
|
|
75
|
+
/** Close a document the render was aborted in the middle of. */
|
|
76
|
+
export function closeDocument(html) {
|
|
77
|
+
let out = html;
|
|
78
|
+
if (!/<\/body>/i.test(out) && /<body/i.test(out))
|
|
79
|
+
out += '</body>';
|
|
80
|
+
if (!/<\/html>/i.test(out) && /<html/i.test(out))
|
|
81
|
+
out += '</html>';
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The file name a url is stored under: / → index, /a/b → a/b.
|
|
86
|
+
*
|
|
87
|
+
* Refuses a key that could leave the directory it is written into. The input is
|
|
88
|
+
* whatever generateStaticParams() returned — typically slugs from a database or
|
|
89
|
+
* a CMS — so a record named `../../../../etc/cron.d/x` is an arbitrary file
|
|
90
|
+
* write on the build machine with content the same record influences.
|
|
91
|
+
*
|
|
92
|
+
* Checked here rather than in the writer, because the writer is supplied by the
|
|
93
|
+
* host: `writeTo` on disk does the obvious thing, but a KV or edge binding has
|
|
94
|
+
* no notion of a parent directory and no reason to look for one.
|
|
95
|
+
*/
|
|
96
|
+
export function pathKey(url) {
|
|
97
|
+
const key = url.replace(/^\/+|\/+$/g, '') || 'index';
|
|
98
|
+
if (key.split('/').some((segment) => segment === '..' || segment === '.')) {
|
|
99
|
+
throw new Error('Refusing to store ' + JSON.stringify(url) + ': the path leaves the output directory. ' +
|
|
100
|
+
'A url segment came from generateStaticParams() or a route param and contains "..".');
|
|
101
|
+
}
|
|
102
|
+
return key;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Substitute params into a route's segments to get a concrete url.
|
|
106
|
+
*
|
|
107
|
+
* A param is one segment, so a value carrying a slash is not a deeper url — it
|
|
108
|
+
* is a value that was never a single segment. A catch-all is the exception and
|
|
109
|
+
* is spelled as one in the route.
|
|
110
|
+
*/
|
|
111
|
+
export function urlFor(route, params) {
|
|
112
|
+
const parts = route.segments.map((segment) => {
|
|
113
|
+
if (segment.type === 'static')
|
|
114
|
+
return segment.value;
|
|
115
|
+
const value = params[segment.value] ?? '';
|
|
116
|
+
if (segment.type !== 'catchAll' && /[/\\]/.test(value)) {
|
|
117
|
+
throw new Error('The ' + segment.value + ' param is ' + JSON.stringify(value) + ', which is not one url ' +
|
|
118
|
+
'segment. A value with a slash in it has to be a catch-all route, or be encoded.');
|
|
119
|
+
}
|
|
120
|
+
return value;
|
|
121
|
+
});
|
|
122
|
+
return '/' + parts.filter((p) => p !== '').join('/');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Every url this build should attempt, and the params each was built from.
|
|
126
|
+
*
|
|
127
|
+
* A parameterised route that declares no `generateStaticParams` yields
|
|
128
|
+
* nothing — not an error: rendering on demand is a legitimate answer, and the
|
|
129
|
+
* alternative is guessing at slugs the app never listed.
|
|
130
|
+
*/
|
|
131
|
+
/** Stand-in values for a route whose real urls were never listed. */
|
|
132
|
+
function placeholders(route) {
|
|
133
|
+
const params = {};
|
|
134
|
+
for (const segment of route.segments) {
|
|
135
|
+
if (segment.type !== 'static')
|
|
136
|
+
params[segment.value] = '_';
|
|
137
|
+
}
|
|
138
|
+
return params;
|
|
139
|
+
}
|
|
140
|
+
export async function urlsToBuild(manifest, engine) {
|
|
141
|
+
const entries = [];
|
|
142
|
+
for (const route of manifest.routes) {
|
|
143
|
+
const parameterised = route.segments.some((s) => s.type !== 'static');
|
|
144
|
+
if (!parameterised) {
|
|
145
|
+
entries.push({ route, params: {}, url: urlFor(route, {}) });
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
// A route that lists no urls still gets one attempt, with placeholder
|
|
149
|
+
// params, so it can ship a shell. Nothing in a shell varies by param.
|
|
150
|
+
if (!route.staticParams) {
|
|
151
|
+
entries.push({ route, params: placeholders(route), url: urlFor(route, placeholders(route)) });
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const sets = (await engine.getStaticParams?.(route.component)) ?? null;
|
|
155
|
+
// Null means the route declares none, so it is rendered on demand. An
|
|
156
|
+
// empty array means the app looked and there is nothing to build — both
|
|
157
|
+
// produce no files, and only one of them is a mistake to warn about.
|
|
158
|
+
if (!sets)
|
|
159
|
+
continue;
|
|
160
|
+
for (const params of sets) {
|
|
161
|
+
entries.push({ route, params, url: urlFor(route, params) });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return entries;
|
|
165
|
+
}
|
|
166
|
+
export async function prerender(options) {
|
|
167
|
+
const { engine, write, version } = options;
|
|
168
|
+
const manifest = options.manifest ?? engine.manifest?.();
|
|
169
|
+
if (!manifest) {
|
|
170
|
+
throw new Error('No route table. Pass `manifest`, or build with a plugin version that embeds one.');
|
|
171
|
+
}
|
|
172
|
+
const entries = await urlsToBuild(manifest, engine);
|
|
173
|
+
const results = new Array(entries.length);
|
|
174
|
+
// Rendered a few at a time rather than one after another.
|
|
175
|
+
//
|
|
176
|
+
// Most of a build is this loop, and most of this loop is waiting: a page
|
|
177
|
+
// whose shell is decided by a two-second budget spends two seconds doing
|
|
178
|
+
// nothing while the next page waits its turn. Nothing here is shared between
|
|
179
|
+
// routes — the probe's stand-in host is held in async context, so concurrent
|
|
180
|
+
// renders cannot see each other's — which is what makes overlapping them
|
|
181
|
+
// safe, and was not true until it was scoped.
|
|
182
|
+
//
|
|
183
|
+
// Bounded, because each one is a full React render: unbounded would turn a
|
|
184
|
+
// large site into as many concurrent renders as it has pages.
|
|
185
|
+
//
|
|
186
|
+
// Results are placed by index, so what a build reports does not depend on
|
|
187
|
+
// which page happened to finish first.
|
|
188
|
+
const concurrency = Math.max(1, options.concurrency ?? DEFAULT_PRERENDER_CONCURRENCY);
|
|
189
|
+
let next = 0;
|
|
190
|
+
const worker = async () => {
|
|
191
|
+
while (true) {
|
|
192
|
+
const index = next++;
|
|
193
|
+
if (index >= entries.length)
|
|
194
|
+
return;
|
|
195
|
+
const { route, params, url } = entries[index];
|
|
196
|
+
results[index] = await prerenderOne(route, params, url);
|
|
197
|
+
options.onResult?.(results[index]);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, entries.length) }, worker));
|
|
201
|
+
const refused = results.filter((r) => r.type === 'blocked');
|
|
202
|
+
if (refused.length > 0) {
|
|
203
|
+
throw new NotPrerenderable(refused);
|
|
204
|
+
}
|
|
205
|
+
return results;
|
|
206
|
+
async function prerenderOne(route, params, url) {
|
|
207
|
+
const props = options.props ? options.props(route, params) : params;
|
|
208
|
+
const layouts = route.layouts.map((component) => ({ component, props: {} }));
|
|
209
|
+
const unlistedNow = route.segments.some((seg) => seg.type !== 'static') && !route.staticParams;
|
|
210
|
+
const said = (type, reason) => ({
|
|
211
|
+
// A route standing in for many urls reports the pattern. Reporting the
|
|
212
|
+
// placeholder url instead prints `/posts/_`, which looks like a page.
|
|
213
|
+
url: unlistedNow ? '/' + patternKey(route) : url,
|
|
214
|
+
component: route.component,
|
|
215
|
+
type,
|
|
216
|
+
reason,
|
|
217
|
+
});
|
|
218
|
+
const unlisted = route.segments.some((seg) => seg.type !== 'static') && !route.staticParams;
|
|
219
|
+
// Classify by rendering, never by asking. The probe is cheap and cannot
|
|
220
|
+
// hang: anything still suspended when its budget expires is the answer.
|
|
221
|
+
//
|
|
222
|
+
// Wrapped so a redirect has somewhere to be recorded. Reading the scope
|
|
223
|
+
// rather than inspecting the thrown error is the only thing that works
|
|
224
|
+
// from out here: React catches what a component throws and re-raises its
|
|
225
|
+
// own, whose message is stripped in production — so a redirect above the
|
|
226
|
+
// boundaries arrives as a generic render failure, and one from inside a
|
|
227
|
+
// boundary never arrives at all.
|
|
228
|
+
// A build renders each url once, and each gets its own table: two routes
|
|
229
|
+
// must not share an answer just because they were built in the same run.
|
|
230
|
+
// No request, deliberately: a page that reads one is caught below rather
|
|
231
|
+
// than frozen holding whatever the build machine happened to send.
|
|
232
|
+
const { shell, redirected, readRequest } = await withRequest(null, () => withCache(() => withRedirect(async (taken) => {
|
|
233
|
+
try {
|
|
234
|
+
return {
|
|
235
|
+
shell: await engine.handleRscPprShell(route.component, props, layouts, route.loadings, route.slots,
|
|
236
|
+
// Only when this shell serves one url. A parameterised route's
|
|
237
|
+
// shell is shared, so baking a url into it would put the wrong one
|
|
238
|
+
// on every page but the one that happened to be built.
|
|
239
|
+
unlistedNow ? '' : url),
|
|
240
|
+
redirected: taken(),
|
|
241
|
+
readRequest: requestWasRead(),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
// A guard refusing throws out of the probe rather than being caught
|
|
246
|
+
// inside it: middleware run before the render, so there is no render yet
|
|
247
|
+
// to capture the failure. A refusal is a classification, not a build
|
|
248
|
+
// error — the route is one that cannot be frozen.
|
|
249
|
+
const refused = taken();
|
|
250
|
+
if (!refused)
|
|
251
|
+
throw error;
|
|
252
|
+
return { shell: null, redirected: refused, readRequest: requestWasRead() };
|
|
253
|
+
}
|
|
254
|
+
})));
|
|
255
|
+
// A page that leaves rather than renders is not a build failure, and it is
|
|
256
|
+
// not something to freeze either: what would be stored is the redirect's
|
|
257
|
+
// own emptiness, served for ever to everyone. Rendered on demand instead,
|
|
258
|
+
// where the redirect can actually happen.
|
|
259
|
+
/**
|
|
260
|
+
* Did this page's own boundary catch the wait, or the app's?
|
|
261
|
+
*
|
|
262
|
+
* A root loading.tsx wraps every page, so a page that blocks — or throws,
|
|
263
|
+
* which is how a client hook says it has no server answer — is caught
|
|
264
|
+
* whatever it does. The route is stored either way and the build has
|
|
265
|
+
* nothing to refuse, which makes a page whose boundary is in the wrong
|
|
266
|
+
* place look exactly like one whose boundary is right.
|
|
267
|
+
*
|
|
268
|
+
* Asked by rendering again without the root fallback, and only for a route
|
|
269
|
+
* that has no closer one.
|
|
270
|
+
*
|
|
271
|
+
* Only for a route that came out as a shell. A frozen one rendered to
|
|
272
|
+
* completion with the root boundary present, and removing a boundary
|
|
273
|
+
* cannot stop a render that already finished — so the second probe
|
|
274
|
+
* finishes too, its markup is the whole document, and the emptiness test
|
|
275
|
+
* cannot fire. It was being paid for anyway: a second full render of every
|
|
276
|
+
* frozen page, which on a site whose pages are mostly frozen is most of
|
|
277
|
+
* the prerender.
|
|
278
|
+
*/
|
|
279
|
+
async function withRootFallbackChecked(result) {
|
|
280
|
+
if (result.type !== 'shell')
|
|
281
|
+
return result;
|
|
282
|
+
if (route.loadings.length !== 1 || !engine.handleRscPprShell)
|
|
283
|
+
return result;
|
|
284
|
+
// A tenth of the shell budget, because this is a different question.
|
|
285
|
+
//
|
|
286
|
+
// Deciding what a page's shell IS means waiting out everything that can
|
|
287
|
+
// resolve. Asking whether anything paints at all without the root
|
|
288
|
+
// fallback is a boolean about the first flush — and a page that paints,
|
|
289
|
+
// paints immediately. Given the full budget it cost two seconds a route
|
|
290
|
+
// to learn what the first millisecond already said, which on this
|
|
291
|
+
// example was 40% of the entire prerender.
|
|
292
|
+
const withoutRoot = await withRequest(null, () => withCache(() => withRedirect(async () => engine.handleRscPprShell(route.component, props, layouts, [], route.slots, url, ROOT_FALLBACK_BUDGET_MS)))).catch(() => null);
|
|
293
|
+
if (withoutRoot && closeDocument(withoutRoot.shellHtml.trim()) === '') {
|
|
294
|
+
result.warning =
|
|
295
|
+
'nothing painted without the root loading.tsx — the fallback the whole app shares ' +
|
|
296
|
+
'is standing in for this page. Put a boundary where the waiting is.';
|
|
297
|
+
}
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
// A route that only redirects still has an answer to freeze — the answer
|
|
301
|
+
// is the redirect, not a page. Rendering it per request re-derives a
|
|
302
|
+
// constant, and on a static host there would be nothing to derive it with.
|
|
303
|
+
if (redirected) {
|
|
304
|
+
await write(`${pathKey(url)}.redirect.json`, JSON.stringify({ status: redirected.status, location: redirected.location }));
|
|
305
|
+
return said('frozen', `redirects to ${redirected.location}`);
|
|
306
|
+
}
|
|
307
|
+
if (!shell)
|
|
308
|
+
return said('error', 'refused before it rendered');
|
|
309
|
+
if (shell.error)
|
|
310
|
+
return said('error', shell.error);
|
|
311
|
+
// A timeout is the ordinary path for a page that streams, not a failure:
|
|
312
|
+
// the probe hands the page a host global that never resolves, React
|
|
313
|
+
// flushes everything that does not depend on it, and the abort happens
|
|
314
|
+
// once there is nothing left to flush. So the captured markup IS the
|
|
315
|
+
// shell — layouts, static content, and the fallbacks standing in for what
|
|
316
|
+
// has not arrived.
|
|
317
|
+
if (shell.timedOut) {
|
|
318
|
+
const body = closeDocument(shell.shellHtml.trim());
|
|
319
|
+
// Nothing was flushed before the page blocked, so there is no shell to
|
|
320
|
+
// ship — a page that blocks above every boundary can only be rendered on
|
|
321
|
+
// demand. `reaches for the host` is the specific reason when both are
|
|
322
|
+
// true; a page that merely ran long says the other thing.
|
|
323
|
+
if (body === '') {
|
|
324
|
+
return said('blocked', (readRequest
|
|
325
|
+
? 'reads the request'
|
|
326
|
+
: shell.usedDynamicApis
|
|
327
|
+
? 'reaches for the host'
|
|
328
|
+
: 'blocks') +
|
|
329
|
+
' before anything can paint, so there is no shell to store');
|
|
330
|
+
}
|
|
331
|
+
await writeShell(route, url, body);
|
|
332
|
+
return await withRootFallbackChecked(said('shell', null));
|
|
333
|
+
}
|
|
334
|
+
// Rendered whole, with params that were invented because the route listed
|
|
335
|
+
// none. Freezing that stores a page whose id is literally `_`, and a shell
|
|
336
|
+
// is no better: the value is in the markup rather than behind a boundary
|
|
337
|
+
// the client fills. A route reaches this only by rendering its params
|
|
338
|
+
// before it can paint, which is exactly the shape that cannot be shared
|
|
339
|
+
// across urls.
|
|
340
|
+
if (unlisted) {
|
|
341
|
+
return said('blocked', 'renders its params before it can paint, and lists no urls to build');
|
|
342
|
+
}
|
|
343
|
+
const shipsJs = route.clientJs !== false;
|
|
344
|
+
const rendered = await engine.handleRsc(route.component, props, null, layouts,
|
|
345
|
+
// Not empty: a page whose layout declares a parallel slot renders without
|
|
346
|
+
// it otherwise, and nothing says so — the page comes out whole apart from
|
|
347
|
+
// the missing region.
|
|
348
|
+
route.loadings, route.slots, 0, url, shipsJs);
|
|
349
|
+
// A client component without a runtime is inert markup — a button that
|
|
350
|
+
// does nothing. Refused rather than shipped, and named, because they are
|
|
351
|
+
// usually inherited from a shared layout rather than written on the page.
|
|
352
|
+
if (!shipsJs && rendered.clientComponents.length > 0) {
|
|
353
|
+
return said('error', `ships no client runtime, but the tree renders ${rendered.clientComponents.join(', ')}. ` +
|
|
354
|
+
'These usually come from a shared layout rather than the page itself.');
|
|
355
|
+
}
|
|
356
|
+
const key = pathKey(url);
|
|
357
|
+
await write(`${key}.html`, rendered.body);
|
|
358
|
+
await write(`${key}.flight`, rendered.rscPayload);
|
|
359
|
+
// One variant per depth the client might already hold. Without them every
|
|
360
|
+
// navigation to a prerendered route is a whole document, which replaces the
|
|
361
|
+
// root and unmounts the pages retained behind it — so going back does not
|
|
362
|
+
// restore the form you were filling in. Most routes in a real app are
|
|
363
|
+
// prerendered, which makes this the common path rather than an edge case.
|
|
364
|
+
for (let depth = 1; depth <= route.layouts.length; depth++) {
|
|
365
|
+
const { rscPayload } = await engine.handleRscPayload(route.component, props, layouts, route.loadings, route.slots, depth, url);
|
|
366
|
+
await write(`${key}.seg${depth}.flight`, rscPayload);
|
|
367
|
+
}
|
|
368
|
+
await write(`${key}.meta.json`, JSON.stringify({ layouts: route.layouts, component: route.component, version: version ?? null }, null, 2));
|
|
369
|
+
return await withRootFallbackChecked(said('frozen', null));
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Freeze a shell, under the url when it is one and under the route's pattern
|
|
373
|
+
* when it stands for many.
|
|
374
|
+
*
|
|
375
|
+
* A route whose urls were never listed still gets a shell: nothing in it
|
|
376
|
+
* varies by param, so the same markup is correct for every url the route
|
|
377
|
+
* matches. That is most of the value — the routes you can enumerate are the
|
|
378
|
+
* ones you could already freeze whole.
|
|
379
|
+
*/
|
|
380
|
+
async function writeShell(route, url, body) {
|
|
381
|
+
const parameterised = route.segments.some((s) => s.type !== 'static');
|
|
382
|
+
const key = parameterised && !route.staticParams ? patternKey(route) : pathKey(url);
|
|
383
|
+
await write(`${key}.ppr.html`, body);
|
|
384
|
+
await write(`${key}.ppr-meta.json`, JSON.stringify({ layouts: route.layouts, component: route.component, parameterised, version: version ?? null }, null, 2));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=prerender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prerender.js","sourceRoot":"","sources":["../src/prerender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Href } from './routes.js';
|
|
2
|
+
import type { Redirection } from './redirectDigest.js';
|
|
3
|
+
export { RedirectSignal, isRedirectSignal, redirectDigest, parseRedirectDigest } from './redirectDigest.js';
|
|
4
|
+
export type { Redirection } from './redirectDigest.js';
|
|
5
|
+
/**
|
|
6
|
+
* Leave this page for another one.
|
|
7
|
+
*
|
|
8
|
+
* Never returns: it throws, which stops the component that called it. Do not
|
|
9
|
+
* wrap a call in `try`/`catch` without rethrowing what you do not recognise —
|
|
10
|
+
* swallowing this turns a redirect into a blank region.
|
|
11
|
+
*
|
|
12
|
+
* `location` is typed to the routes the build found, so a redirect to a page
|
|
13
|
+
* that no longer exists stops compiling. Cast with `as Href` when the
|
|
14
|
+
* destination is computed — remembering where someone was going and sending
|
|
15
|
+
* them back to it is the usual case.
|
|
16
|
+
*
|
|
17
|
+
* Where it is called decides how it is delivered, and the difference matters
|
|
18
|
+
* for anything that must not be seen. A call above every Suspense boundary is
|
|
19
|
+
* answered with a status code before a byte is written. A call inside one is
|
|
20
|
+
* answered after the shell — which holds no data from inside the boundary,
|
|
21
|
+
* but does hold whatever the layouts above it rendered.
|
|
22
|
+
*/
|
|
23
|
+
export declare function redirect(location: Href, status?: number): never;
|
|
24
|
+
/** The redirect asked for during the current render, if any. */
|
|
25
|
+
export declare function currentRedirect(): Redirection | null;
|
|
26
|
+
/**
|
|
27
|
+
* Run a render with somewhere for a redirect to be recorded, and report one.
|
|
28
|
+
*
|
|
29
|
+
* `taken()` is read twice by a streaming host: once when the shell resolves,
|
|
30
|
+
* to answer with a status code, and again when the stream ends, for a
|
|
31
|
+
* redirect that arrived too late for one.
|
|
32
|
+
*/
|
|
33
|
+
export declare function withRedirect<T>(run: (taken: () => Redirection | null) => Promise<T>): Promise<T>;
|
|
34
|
+
//# sourceMappingURL=redirect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../src/redirect.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC3G,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AA8BtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,SAAM,GAAG,KAAK,CAwB5D;AAED,gEAAgE;AAChE,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAEpD;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,WAAW,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GACnD,OAAO,CAAC,CAAC,CAAC,CAYZ"}
|