@rsc-kit/core 0.20.2 → 0.20.3
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/dist/host.d.ts +7 -4
- package/dist/host.js +23 -1
- package/dist/host.js.map +1 -1
- package/dist/js/DefaultRouteError.js +8 -3
- package/dist/js/DefaultRouteError.js.map +1 -1
- package/dist/js/Link.d.ts +1 -1
- package/dist/js/Link.js +20 -2
- package/dist/js/Link.js.map +1 -1
- package/dist/js/createViteRscApp.js +9 -4
- package/dist/js/createViteRscApp.js.map +1 -1
- package/dist/js/navigate.js +17 -5
- package/dist/js/navigate.js.map +1 -1
- package/dist/js/staleAssets.d.ts +10 -0
- package/dist/js/staleAssets.js +27 -6
- package/dist/js/staleAssets.js.map +1 -1
- package/dist/js/viewportPrefetch.d.ts +21 -0
- package/dist/js/viewportPrefetch.js +67 -0
- package/dist/js/viewportPrefetch.js.map +1 -0
- package/dist/vite.js +54 -1
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
package/dist/host.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ import type { RouteManifest } from "./manifest.js";
|
|
|
18
18
|
export interface RscEngine {
|
|
19
19
|
/** The route table this bundle was built from. */
|
|
20
20
|
manifest?(): RouteManifest;
|
|
21
|
+
/** A short id of this build's client, for the version the host answers with when given none. */
|
|
22
|
+
buildId?(): Promise<string>;
|
|
21
23
|
installHostFn(fn: (name: string, ...args: unknown[]) => unknown): void;
|
|
22
24
|
handleRscStream(component: string, props?: Record<string, unknown>, layouts?: {
|
|
23
25
|
component: string;
|
|
@@ -143,10 +145,11 @@ export interface RscHostOptions {
|
|
|
143
145
|
/** Serve a built browser asset. Return null for anything not found. */
|
|
144
146
|
assets?: (pathname: string, request: Request) => Promise<Response | null> | Response | null;
|
|
145
147
|
/**
|
|
146
|
-
* Identifies this build to the client, which
|
|
147
|
-
* navigation and
|
|
148
|
-
*
|
|
149
|
-
*
|
|
148
|
+
* Identifies this build to the client, which says it back on every
|
|
149
|
+
* navigation and is sent to load the document when it differs. For an
|
|
150
|
+
* engine with no `buildId` of its own; the generated one has, and every
|
|
151
|
+
* document it renders says that id, so a version named here would
|
|
152
|
+
* disagree with what the client was told and refuse every navigation.
|
|
150
153
|
*/
|
|
151
154
|
version?: string;
|
|
152
155
|
/**
|
package/dist/host.js
CHANGED
|
@@ -286,7 +286,13 @@ function matchPage(routes, url) {
|
|
|
286
286
|
return matchRoute(routes, url.pathname, hostOf.get(url) ?? null);
|
|
287
287
|
}
|
|
288
288
|
export function createRscHandler(options) {
|
|
289
|
-
const { engine, assets
|
|
289
|
+
const { engine, assets } = options;
|
|
290
|
+
// The build's own id, which is also what every document says it is - the
|
|
291
|
+
// two must agree, or a client's honest claim is a 409 on every request.
|
|
292
|
+
// A version named by the app applies only to an engine with no id of its
|
|
293
|
+
// own. Resolved on the first request: the engine reads it from a build
|
|
294
|
+
// product it only has at runtime.
|
|
295
|
+
let version = engine.buildId ? undefined : options.version;
|
|
290
296
|
const maxActionBody = options.maxActionBody ?? DEFAULT_MAX_ACTION_BODY;
|
|
291
297
|
const compress = options.compress ?? true;
|
|
292
298
|
// Annotated rather than inferred: the narrowing below is lost inside the
|
|
@@ -421,6 +427,8 @@ export function createRscHandler(options) {
|
|
|
421
427
|
return [version ?? "", url.pathname + url.search, ...varies].join("\n");
|
|
422
428
|
}
|
|
423
429
|
return async function handle(request) {
|
|
430
|
+
if (version === undefined && engine.buildId)
|
|
431
|
+
version = await engine.buildId();
|
|
424
432
|
return await withRequest(request, () => withCache(() =>
|
|
425
433
|
// Open for the whole request and sealed the moment an answer exists,
|
|
426
434
|
// so middleware — which runs before any rendering — can put headers on
|
|
@@ -583,6 +591,20 @@ export function createRscHandler(options) {
|
|
|
583
591
|
const formPost = await formPostOf(request, url);
|
|
584
592
|
if (!formPost && request.method !== "GET" && request.method !== "HEAD")
|
|
585
593
|
return null;
|
|
594
|
+
// A client saying which build it runs, and it is not this one: its
|
|
595
|
+
// manifest cannot load what this build's payload names - a client
|
|
596
|
+
// component added since is "client reference not found" and the route's
|
|
597
|
+
// error boundary, on a page that worked a click ago. Under a service
|
|
598
|
+
// worker that serves the last build's document first, that is every
|
|
599
|
+
// returning visitor's first navigation after a deploy, not an open tab.
|
|
600
|
+
// A 409 sends the client to load the document instead, from this build.
|
|
601
|
+
const claimed = request.headers.get(HEADER.version);
|
|
602
|
+
if (claimed !== null && claimed !== "" && version && claimed !== version && request.headers.get(HEADER.rsc) !== null) {
|
|
603
|
+
return new Response(null, {
|
|
604
|
+
status: 409,
|
|
605
|
+
headers: withVersion({ "X-RSC-Location": url.pathname + url.search, "Cache-Control": "no-store" }),
|
|
606
|
+
});
|
|
607
|
+
}
|
|
586
608
|
// One named region of this page, asked for without mutating anything to
|
|
587
609
|
// earn it. What an action invalidated does not come through here — that
|
|
588
610
|
// travels back inside the action's own answer, which is the whole point of
|