@rangojs/router 0.21.0 → 0.22.1
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/bin/rango.js +13 -1
- package/dist/types/browser/event-controller.d.ts +30 -13
- package/dist/types/browser/navigation-store.d.ts +9 -0
- package/dist/types/browser/partial-update.d.ts +2 -1
- package/dist/types/browser/prefetch/default-strategy.d.ts +16 -20
- package/dist/types/browser/react/NavigationProvider.d.ts +14 -1
- package/dist/types/browser/react/context.d.ts +14 -0
- package/dist/types/browser/rsc-router.d.ts +13 -2
- package/dist/types/browser/types.d.ts +10 -0
- package/dist/types/build/generate-manifest.d.ts +2 -0
- package/dist/types/cache/background-task.d.ts +22 -0
- package/dist/types/cache/cache-key-utils.d.ts +50 -5
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +1 -1
- package/dist/types/cache/cf/cf-cache-store.d.ts +7 -1
- package/dist/types/cache/document-cache.d.ts +8 -5
- package/dist/types/cache/handle-snapshot.d.ts +23 -0
- package/dist/types/cache/index.d.ts +1 -1
- package/dist/types/cache/invalidation-order.d.ts +14 -0
- package/dist/types/cache/memory-segment-store.d.ts +33 -1
- package/dist/types/cache/shell-snapshot.d.ts +10 -1
- package/dist/types/cache/store-scope.d.ts +22 -0
- package/dist/types/cache/tag-invalidation.d.ts +7 -6
- package/dist/types/cache/types.d.ts +63 -14
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +7 -1
- package/dist/types/errors.d.ts +6 -0
- package/dist/types/handles/deferred-resolution.d.ts +7 -0
- package/dist/types/internal-suspense-audit.d.ts +1 -0
- package/dist/types/loader-store.d.ts +4 -8
- package/dist/types/outlet-provider.d.ts +2 -1
- package/dist/types/prerender/cloudflare.d.ts +49 -0
- package/dist/types/prerender/create-prerender-trigger.d.ts +121 -0
- package/dist/types/prerender/index.d.ts +12 -0
- package/dist/types/prerender/memory-prerender-store.d.ts +29 -0
- package/dist/types/prerender/on-demand.d.ts +272 -0
- package/dist/types/prerender/producer-guard.d.ts +33 -0
- package/dist/types/prerender/shell-manifest-key.d.ts +1 -18
- package/dist/types/prerender/warm-request.d.ts +65 -0
- package/dist/types/prerender/warm.d.ts +65 -0
- package/dist/types/prerender/writable-store.d.ts +170 -0
- package/dist/types/prerender.d.ts +27 -0
- package/dist/types/reverse.d.ts +1 -1
- package/dist/types/route-content-wrapper.d.ts +3 -1
- package/dist/types/router/error-handling.d.ts +2 -0
- package/dist/types/router/handler-context.d.ts +1 -1
- package/dist/types/router/match-middleware/cache-lookup.d.ts +14 -0
- package/dist/types/router/pattern-matching.d.ts +2 -0
- package/dist/types/router/prefetch-default.d.ts +4 -4
- package/dist/types/router/prerender-match.d.ts +23 -1
- package/dist/types/router/route-trie-builder.d.ts +8 -1
- package/dist/types/router/router-context.d.ts +1 -0
- package/dist/types/router/router-interfaces.d.ts +30 -0
- package/dist/types/router/router-options.d.ts +24 -0
- package/dist/types/router/segment-resolution/fresh.d.ts +7 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +2 -1
- package/dist/types/router/segment-resolution/revalidation.d.ts +5 -1
- package/dist/types/router/segment-resolution/streamed-handler-boundary.d.ts +43 -0
- package/dist/types/router/trie-matching.d.ts +2 -0
- package/dist/types/rsc/shell-build-manifest.d.ts +6 -4
- package/dist/types/rsc/shell-capture-constants.d.ts +20 -5
- package/dist/types/rsc/shell-capture.d.ts +14 -1
- package/dist/types/rsc/shell-serve.d.ts +2 -2
- package/dist/types/rsc/ssr-module-loader.d.ts +15 -0
- package/dist/types/rsc/types.d.ts +8 -0
- package/dist/types/segment-boundary-content.d.ts +17 -0
- package/dist/types/segment-loader-promise.d.ts +2 -6
- package/dist/types/server/build-version-table.d.ts +9 -0
- package/dist/types/server/context.d.ts +12 -4
- package/dist/types/server/handle-store.d.ts +2 -0
- package/dist/types/server/request-context.d.ts +63 -2
- package/dist/types/suspense-audit-react.d.ts +26 -0
- package/dist/types/suspense-audit.d.ts +157 -0
- package/dist/types/testing/action-form.d.ts +34 -0
- package/dist/types/testing/flight.entry.d.ts +2 -0
- package/dist/types/testing/index.d.ts +4 -0
- package/dist/types/testing/internal/server-modules.d.ts +8 -0
- package/dist/types/testing/serve-shell-request.d.ts +34 -4
- package/dist/types/testing/shell-status.d.ts +14 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +9 -6
- package/dist/types/thenable-status.d.ts +6 -0
- package/dist/types/types/handler-context.d.ts +7 -0
- package/dist/types/types/route-entry.d.ts +5 -0
- package/dist/types/urls/path-helper.d.ts +18 -0
- package/dist/types/vite/discovery/state.d.ts +11 -0
- package/dist/types/vite/inject-client-debug.d.ts +6 -25
- package/dist/types/vite/utils/bundle-analysis.d.ts +6 -2
- package/dist/vite/index.js +180 -497
- package/package.json +13 -3
- package/skills/cache-guide/SKILL.md +18 -17
- package/skills/caching/SKILL.md +40 -4
- package/skills/catalog.json +1 -1
- package/skills/cloudflare/SKILL.md +131 -0
- package/skills/comparison/references/framework-comparison.md +1 -1
- package/skills/deployment-caching/SKILL.md +33 -12
- package/skills/document-cache/SKILL.md +16 -14
- package/skills/hooks/SKILL.md +22 -0
- package/skills/hooks/handle-and-actions.md +3 -4
- package/skills/hooks/navigation.md +10 -0
- package/skills/hooks/state.md +5 -4
- package/skills/host-router/SKILL.md +18 -0
- package/skills/loader/SKILL.md +6 -4
- package/skills/middleware/SKILL.md +1 -1
- package/skills/migrate-nextjs/SKILL.md +82 -9
- package/skills/ppr/SKILL.md +31 -8
- package/skills/prerender/SKILL.md +645 -8
- package/skills/rango/SKILL.md +1 -0
- package/skills/response-routes/SKILL.md +5 -5
- package/skills/route/SKILL.md +29 -0
- package/skills/testing/SKILL.md +2 -1
- package/skills/testing/cache-prerender.md +18 -17
- package/skills/testing/serve-shell-request.md +104 -8
- package/skills/use-cache/SKILL.md +9 -5
- package/skills/vercel/SKILL.md +2 -0
- package/skills/view-transitions/SKILL.md +9 -4
- package/src/browser/event-controller.ts +69 -25
- package/src/browser/link-interceptor.ts +2 -2
- package/src/browser/navigation-bridge.ts +75 -35
- package/src/browser/navigation-store.ts +26 -0
- package/src/browser/navigation-transaction.ts +9 -2
- package/src/browser/network-error-handler.ts +2 -0
- package/src/browser/partial-update.ts +48 -12
- package/src/browser/prefetch/default-strategy.ts +22 -42
- package/src/browser/react/Link.tsx +37 -42
- package/src/browser/react/NavigationProvider.tsx +63 -3
- package/src/browser/react/context.ts +17 -0
- package/src/browser/react/location-state.ts +5 -19
- package/src/browser/react/use-action.ts +4 -1
- package/src/browser/react/use-handle.ts +4 -20
- package/src/browser/react/use-link-status.ts +4 -3
- package/src/browser/react/use-navigation.ts +4 -1
- package/src/browser/react/use-params.ts +4 -1
- package/src/browser/react/use-pathname.ts +4 -1
- package/src/browser/react/use-search-params.ts +5 -3
- package/src/browser/react/use-segments.ts +36 -54
- package/src/browser/rsc-router.tsx +79 -39
- package/src/browser/segment-reconciler.ts +3 -3
- package/src/browser/server-action-bridge.ts +26 -6
- package/src/browser/types.ts +11 -0
- package/src/build/generate-manifest.ts +17 -0
- package/src/build/merge-full-manifests.ts +5 -0
- package/src/build/route-trie.ts +1 -0
- package/src/cache/background-task.ts +61 -0
- package/src/cache/cache-key-utils.ts +91 -12
- package/src/cache/cache-policy.ts +11 -2
- package/src/cache/cache-runtime.ts +23 -23
- package/src/cache/cache-scope.ts +38 -36
- package/src/cache/cf/cf-cache-store.ts +16 -11
- package/src/cache/document-cache.ts +35 -14
- package/src/cache/handle-snapshot.ts +50 -0
- package/src/cache/index.ts +1 -0
- package/src/cache/invalidation-order.ts +53 -0
- package/src/cache/memory-segment-store.ts +52 -1
- package/src/cache/shell-snapshot.ts +17 -0
- package/src/cache/store-scope.ts +36 -0
- package/src/cache/tag-invalidation.ts +7 -5
- package/src/cache/types.ts +69 -14
- package/src/cache/vercel/vercel-cache-store.ts +20 -6
- package/src/client.tsx +40 -3
- package/src/errors.ts +13 -6
- package/src/handles/deferred-resolution.ts +7 -2
- package/src/internal-suspense-audit.ts +12 -0
- package/src/loader-store.ts +4 -9
- package/src/outlet-provider.tsx +25 -1
- package/src/prerender/cloudflare.ts +130 -0
- package/src/prerender/create-prerender-trigger.ts +780 -0
- package/src/prerender/index.ts +39 -0
- package/src/prerender/memory-prerender-store.ts +115 -0
- package/src/prerender/on-demand.ts +339 -0
- package/src/prerender/producer-guard.ts +66 -0
- package/src/prerender/shell-manifest-key.ts +12 -17
- package/src/prerender/warm-request.ts +154 -0
- package/src/prerender/warm.ts +193 -0
- package/src/prerender/writable-store.ts +278 -0
- package/src/prerender.ts +29 -0
- package/src/reverse.ts +1 -1
- package/src/route-content-wrapper.tsx +107 -13
- package/src/router/error-handling.ts +12 -12
- package/src/router/find-match.ts +1 -0
- package/src/router/handler-context.ts +2 -0
- package/src/router/intercept-resolution.ts +15 -8
- package/src/router/loader-resolution.ts +2 -10
- package/src/router/match-middleware/background-revalidation.ts +2 -0
- package/src/router/match-middleware/cache-lookup.ts +230 -38
- package/src/router/pattern-matching.ts +14 -0
- package/src/router/prefetch-default.ts +4 -4
- package/src/router/prerender-match.ts +460 -352
- package/src/router/route-trie-builder.ts +9 -0
- package/src/router/router-context.ts +1 -0
- package/src/router/router-interfaces.ts +33 -0
- package/src/router/router-options.ts +30 -0
- package/src/router/segment-resolution/fresh.ts +20 -19
- package/src/router/segment-resolution/loader-cache.ts +15 -17
- package/src/router/segment-resolution/revalidation.ts +34 -24
- package/src/router/segment-resolution/streamed-handler-boundary.ts +133 -0
- package/src/router/trie-matching.ts +3 -0
- package/src/router.ts +107 -1
- package/src/rsc/handler.ts +51 -4
- package/src/rsc/progressive-enhancement.ts +5 -1
- package/src/rsc/response-cache-serve.ts +10 -4
- package/src/rsc/rsc-rendering.ts +53 -11
- package/src/rsc/shell-build-manifest.ts +10 -8
- package/src/rsc/shell-capture-constants.ts +39 -7
- package/src/rsc/shell-capture.ts +108 -19
- package/src/rsc/shell-serve.ts +12 -6
- package/src/rsc/ssr-module-loader.ts +26 -0
- package/src/rsc/types.ts +8 -0
- package/src/segment-boundary-content.ts +25 -0
- package/src/segment-loader-promise.ts +28 -38
- package/src/segment-system.tsx +117 -57
- package/src/server/build-version-table.ts +15 -0
- package/src/server/context.ts +40 -17
- package/src/server/cookie-store.ts +5 -0
- package/src/server/handle-store.ts +13 -0
- package/src/server/loader-registry.ts +6 -1
- package/src/server/request-context.ts +87 -1
- package/src/ssr/ssr-root.tsx +20 -13
- package/src/suspense-audit-react.tsx +98 -0
- package/src/suspense-audit.ts +1030 -0
- package/src/testing/action-form.ts +66 -0
- package/src/testing/flight-runtime.d.ts +27 -0
- package/src/testing/flight.entry.ts +3 -0
- package/src/testing/index.ts +19 -0
- package/src/testing/internal/server-modules.ts +32 -0
- package/src/testing/render-route.tsx +25 -12
- package/src/testing/serve-shell-request.ts +190 -34
- package/src/testing/shell-status.ts +17 -6
- package/src/testing/vitest-stubs/plugin-rsc.ts +37 -11
- package/src/thenable-status.ts +10 -0
- package/src/types/handler-context.ts +7 -0
- package/src/types/route-entry.ts +6 -0
- package/src/urls/path-helper.ts +69 -9
- package/src/use-loader.tsx +57 -30
- package/src/vite/discovery/bundle-postprocess.ts +4 -0
- package/src/vite/discovery/discover-routers.ts +15 -0
- package/src/vite/discovery/shell-prerender-phase.ts +5 -5
- package/src/vite/discovery/state.ts +17 -1
- package/src/vite/inject-client-debug.ts +42 -20
- package/src/vite/plugins/virtual-entries.ts +8 -1
- package/src/vite/router-discovery.ts +14 -0
- package/src/vite/utils/bundle-analysis.ts +39 -7
- package/dist/types/browser/react/subscribe-to-nothing.d.ts +0 -7
- package/dist/types/segment-content-promise.d.ts +0 -13
- package/src/browser/react/subscribe-to-nothing.ts +0 -7
- package/src/segment-content-promise.ts +0 -67
package/dist/types/reverse.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export type ParamsFor<TRoutes, TName extends keyof TRoutes> = ExtractParams<Rout
|
|
|
31
31
|
/**
|
|
32
32
|
* Check if an object type has any keys
|
|
33
33
|
*/
|
|
34
|
-
type IsEmptyObject<T> = keyof T extends never ? true : false;
|
|
34
|
+
export type IsEmptyObject<T> = keyof T extends never ? true : false;
|
|
35
35
|
/**
|
|
36
36
|
* Extract search schema from a route entry.
|
|
37
37
|
* Returns {} if no search schema is defined.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
2
|
import { Component } from "react";
|
|
3
3
|
import type { ResolvedSegment } from "./types.js";
|
|
4
4
|
/**
|
|
@@ -70,6 +70,7 @@ export declare function RouteContentWrapper({ content, fallback, segmentId, }: {
|
|
|
70
70
|
fallback?: ReactNode;
|
|
71
71
|
segmentId?: string;
|
|
72
72
|
}): ReactNode;
|
|
73
|
+
export declare function AuditedRouteContent({ content, fallback, segmentId, }: ComponentProps<typeof RouteContentWrapper>): ReactNode;
|
|
73
74
|
/**
|
|
74
75
|
* LoaderBoundary - Client component that resolves loader promises and renders OutletProvider
|
|
75
76
|
*
|
|
@@ -102,3 +103,4 @@ export interface LoaderBoundaryProps {
|
|
|
102
103
|
children: ReactNode;
|
|
103
104
|
}
|
|
104
105
|
export declare function LoaderBoundary({ loaderDataPromise, loaderIds, loaderStreams, awaitedLoaderIds, fallback, outletKey, outletContent, segment, parallel, children, }: LoaderBoundaryProps): ReactNode;
|
|
106
|
+
export declare function AuditedLoaderBoundary({ fallback, children, ...resolver }: LoaderBoundaryProps): ReactNode;
|
|
@@ -78,6 +78,8 @@ export declare function findNearestNotFoundBoundary(entry: EntryData | null, def
|
|
|
78
78
|
* Sanitizes error details in production
|
|
79
79
|
*/
|
|
80
80
|
export declare function createErrorInfo(error: unknown, segmentId: string, segmentType: ErrorInfo["segmentType"]): ErrorInfo;
|
|
81
|
+
/** Invoke an errorBoundary() fallback that may be a handler or a plain node. */
|
|
82
|
+
export declare function renderErrorFallback(fallback: ReactNode | ErrorBoundaryHandler, errorInfo: ErrorInfo): ReactNode;
|
|
81
83
|
/**
|
|
82
84
|
* Create an error segment with the fallback component
|
|
83
85
|
* Renders the fallback with error info and reset function
|
|
@@ -37,7 +37,7 @@ export declare function createHandlerContext<TEnv>(params: Record<string, string
|
|
|
37
37
|
* search, reverse, and use(handle) work. Request-time properties
|
|
38
38
|
* (request, env, headers, cookies, get, set, res) throw with a clear error.
|
|
39
39
|
*/
|
|
40
|
-
export declare function createPrerenderContext<TEnv>(params: Record<string, string>, pathname: string, routeMap: Record<string, string>, routeName?: string, buildVars?: Record<string, any>, isPassthroughRoute?: boolean, buildEnv?: TEnv, devMode?: boolean): InternalHandlerContext<any, TEnv>;
|
|
40
|
+
export declare function createPrerenderContext<TEnv>(params: Record<string, string>, pathname: string, routeMap: Record<string, string>, routeName?: string, buildVars?: Record<string, any>, isPassthroughRoute?: boolean, buildEnv?: TEnv, devMode?: boolean, onDemand?: boolean): InternalHandlerContext<any, TEnv>;
|
|
41
41
|
/**
|
|
42
42
|
* Create a StaticContext for Static() handlers at build time.
|
|
43
43
|
*
|
|
@@ -94,6 +94,16 @@
|
|
|
94
94
|
import type { ResolvedSegment } from "../../types.js";
|
|
95
95
|
import { type EntryData } from "../../server/context.js";
|
|
96
96
|
import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
97
|
+
import type { PrerenderStore } from "../../prerender/store.js";
|
|
98
|
+
import type { PrerenderTargetObject, ResolvedPrerender } from "../../prerender/on-demand.js";
|
|
99
|
+
import { type RequestContext } from "../../server/request-context.js";
|
|
100
|
+
/**
|
|
101
|
+
* @internal Replace the prerender store this module serves from, and return
|
|
102
|
+
* the one it replaced. For serveShellRequest (testing/serve-shell-request.ts),
|
|
103
|
+
* which installs the production store over the artifacts it bakes for a call
|
|
104
|
+
* and puts the previous one back after it.
|
|
105
|
+
*/
|
|
106
|
+
export declare function setPrerenderStoreForTests(store: PrerenderStore | null | undefined): PrerenderStore | null | undefined;
|
|
97
107
|
/**
|
|
98
108
|
* Whether the prerender store holds a baked entry for this route + params.
|
|
99
109
|
* Consulted by the PPR replay gate (matchPartialWithPprReplay), which must
|
|
@@ -106,6 +116,10 @@ import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
|
106
116
|
* subsequent get() share one underlying load.
|
|
107
117
|
*/
|
|
108
118
|
export declare function prerenderEntryExists(routeKey: string | undefined, params: Record<string, string>, pathname: string, entries: EntryData[]): Promise<boolean>;
|
|
119
|
+
/** @internal Tests only (testing/serve-shell-request.ts resetShellTestState). */
|
|
120
|
+
export declare function resetOverlayRevalidationsForTests(): void;
|
|
121
|
+
/** @internal Exported for the eviction unit test. */
|
|
122
|
+
export declare function scheduleOverlayRevalidation<TEnv>(serializedKey: string, onRevalidate: NonNullable<ResolvedPrerender["config"]["onRevalidate"]>, target: PrerenderTargetObject, reqCtx: RequestContext<TEnv>, now?: number): void;
|
|
109
123
|
/**
|
|
110
124
|
* Async generator middleware type
|
|
111
125
|
*/
|
|
@@ -134,6 +134,8 @@ export interface RouteMatchResult<TEnv = any> {
|
|
|
134
134
|
pr?: true;
|
|
135
135
|
/** Passthrough: handler kept for live fallback on unknown params (from trie) */
|
|
136
136
|
pt?: true;
|
|
137
|
+
/** On-demand prerender eligible (router.prerender() refreshable) */
|
|
138
|
+
od?: true;
|
|
137
139
|
/** Response type for non-RSC routes (json, text, image, any) */
|
|
138
140
|
responseType?: string;
|
|
139
141
|
/** Negotiate variants: response-type routes sharing this path */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resolve the router-wide default Link prefetch strategy once, at router init.
|
|
3
|
-
* The resolved value ships to the client in payload metadata; the
|
|
4
|
-
*
|
|
5
|
-
* default-strategy.ts) and every `<Link>` without an explicit
|
|
6
|
-
* falls back to it.
|
|
3
|
+
* The resolved value ships to the client in payload metadata; the router
|
|
4
|
+
* store carries it (`NavigationStoreContext.defaultPrefetch`, see
|
|
5
|
+
* browser/prefetch/default-strategy.ts) and every `<Link>` without an explicit
|
|
6
|
+
* `prefetch` prop falls back to it.
|
|
7
7
|
*
|
|
8
8
|
* The type lives HERE (not in browser/react/Link.tsx) because both seats need
|
|
9
9
|
* it: this server-side resolver and the client Link/default-strategy modules.
|
|
@@ -5,10 +5,19 @@ import type { PartialPrerenderProps } from "../urls/pattern-types.js";
|
|
|
5
5
|
import type { HandlerContext, ResolvedSegment } from "../types";
|
|
6
6
|
import type { SerializedSegmentData } from "../cache/types.js";
|
|
7
7
|
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
8
|
+
import type { RouterVersions } from "../router-versions.js";
|
|
9
|
+
import type { OnDemandRouteConfig } from "../prerender/on-demand.js";
|
|
8
10
|
export interface PrerenderMatchDeps<TEnv = any> {
|
|
9
11
|
/** Owning router id; scopes bake-time root-scope/search-schema lookups the
|
|
10
12
|
* same way reqCtx._routerId does at runtime (issue #762). */
|
|
11
13
|
routerId?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The owning router's cache versions. Set on the requestless on-demand
|
|
16
|
+
* producer's context as `_versions`, so cache stores built inside the render
|
|
17
|
+
* key under the router's pair like a live request does instead of the
|
|
18
|
+
* whole-build fallback (server/build-version-table.ts getCacheVersions).
|
|
19
|
+
*/
|
|
20
|
+
versions?: RouterVersions;
|
|
12
21
|
findMatch: (pathname: string) => RouteMatchResult<TEnv> | null | Promise<RouteMatchResult<TEnv> | null>;
|
|
13
22
|
buildRouterContext: () => RouterContext<TEnv>;
|
|
14
23
|
mergedRouteMap: Record<string, string>;
|
|
@@ -20,7 +29,15 @@ export interface PrerenderMatchDeps<TEnv = any> {
|
|
|
20
29
|
*/
|
|
21
30
|
export declare function matchForPrerender<TEnv = any>(pathname: string, params: Record<string, string>, deps: PrerenderMatchDeps<TEnv>, buildVars?: Record<string, any>, isPassthroughRoute?: boolean, buildEnv?: TEnv,
|
|
22
31
|
/** Dev-only: check getParams() for passthrough routes to skip unknown params. */
|
|
23
|
-
devMode?: boolean
|
|
32
|
+
devMode?: boolean,
|
|
33
|
+
/**
|
|
34
|
+
* Requestless on-demand refresh (router.prerender()). Arms the personalization
|
|
35
|
+
* guard: cookies()/headers()/response mutations throw a
|
|
36
|
+
* PrerenderPersonalizationError so the caller maps a personalized render to
|
|
37
|
+
* skipped-personalized instead of baking a shared payload. `buildEnv` here is
|
|
38
|
+
* the live trigger env, not the shared build env.
|
|
39
|
+
*/
|
|
40
|
+
onDemand?: boolean): Promise<{
|
|
24
41
|
segments: SerializedSegmentData[];
|
|
25
42
|
/** RSC-encoded handle map ("" when none) — see handle-snapshot.ts. Encoded in
|
|
26
43
|
* the producer (where the Flight codec resolves) so the node-side build/dev
|
|
@@ -33,6 +50,11 @@ devMode?: boolean): Promise<{
|
|
|
33
50
|
* the sinks store it as-is (no longer merge raw records). */
|
|
34
51
|
interceptHandles?: string;
|
|
35
52
|
passthrough?: true;
|
|
53
|
+
/** On-demand only: the render hit `notFound()` and nothing else failed. */
|
|
54
|
+
notFound?: true;
|
|
55
|
+
/** Route-level onDemand config (ttl/tags) read off the route entry; only set
|
|
56
|
+
* when `onDemand` and the route declared an onDemand object literal. */
|
|
57
|
+
onDemandConfig?: OnDemandRouteConfig;
|
|
36
58
|
/**
|
|
37
59
|
* The matched route entry's `ppr` path option, surfaced so the build
|
|
38
60
|
* collection can flag Prerender+ppr routes as build-time shell candidates
|
|
@@ -31,6 +31,12 @@ export interface TrieLeaf {
|
|
|
31
31
|
pr?: true;
|
|
32
32
|
/** Passthrough: handler kept in bundle for live fallback on unknown params */
|
|
33
33
|
pt?: true;
|
|
34
|
+
/**
|
|
35
|
+
* On-demand prerender eligible: the route opted into router.prerender()
|
|
36
|
+
* refresh. Distinct from `pr` — an od route may have no build-baked entry yet
|
|
37
|
+
* still needs a writable-overlay lookup at serve time.
|
|
38
|
+
*/
|
|
39
|
+
od?: true;
|
|
34
40
|
/** Response type for non-RSC routes (json, text, image, any) */
|
|
35
41
|
rt?: string;
|
|
36
42
|
/** Negotiate variants: response-type routes sharing this path */
|
|
@@ -73,5 +79,6 @@ export interface TrieNode {
|
|
|
73
79
|
* @param prerenderRouteNames - Optional set of prerendered route names (sets leaf.pr)
|
|
74
80
|
* @param passthroughRouteNames - Optional set of passthrough route names (sets leaf.pt)
|
|
75
81
|
* @param responseTypeRoutes - Optional map of route name to response type (sets leaf.rt)
|
|
82
|
+
* @param onDemandRouteNames - Optional set of on-demand-eligible route names (sets leaf.od)
|
|
76
83
|
*/
|
|
77
|
-
export declare function buildRouteTrie(routeManifest: Record<string, string>, routeToStaticPrefix: Record<string, string>, routeTrailingSlash?: Record<string, string>, prerenderRouteNames?: Set<string>, passthroughRouteNames?: Set<string>, responseTypeRoutes?: Record<string, string>): TrieNode;
|
|
84
|
+
export declare function buildRouteTrie(routeManifest: Record<string, string>, routeToStaticPrefix: Record<string, string>, routeTrailingSlash?: Record<string, string>, prerenderRouteNames?: Set<string>, passthroughRouteNames?: Set<string>, responseTypeRoutes?: Record<string, string>, onDemandRouteNames?: Set<string>): TrieNode;
|
|
@@ -45,6 +45,7 @@ export interface RouterContext<TEnv = any> {
|
|
|
45
45
|
getContext: () => {
|
|
46
46
|
getOrCreateStore: (key: string) => any;
|
|
47
47
|
runWithStore: <T>(store: any, namespace: string, parent: any, fn: () => T) => T;
|
|
48
|
+
runIsolated: <T>(forRoute: string, fn: () => T) => T;
|
|
48
49
|
};
|
|
49
50
|
getMetricsStore: () => MetricsStore | undefined;
|
|
50
51
|
createCacheScope: (cacheConfig: any, parent: CacheScope | null) => CacheScope | null;
|
|
@@ -184,6 +184,28 @@ export interface Rango<TEnv = any, TRoutes extends Record<string, unknown> = Rec
|
|
|
184
184
|
* ```
|
|
185
185
|
*/
|
|
186
186
|
fetch(request: Request, input?: RouterRequestInput<TEnv>): Promise<Response>;
|
|
187
|
+
/**
|
|
188
|
+
* Bind `{ env, ctx }` and get the on-demand (ISR-style) prerender runner, to refresh from a running app —
|
|
189
|
+
* fetch handler, cron, queue, workflow, webhook, or server action.
|
|
190
|
+
*
|
|
191
|
+
* Requestless: the producer renders with route params and env only, never the
|
|
192
|
+
* caller's cookies/headers/session. Only routes that opted in via
|
|
193
|
+
* `Prerender(..., { onDemand })` are persistable; others return a skipped
|
|
194
|
+
* result. Configure the store via the `prerender` router option.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* const prerender = router.prerender({ env, ctx });
|
|
199
|
+
* await prerender("/products/42");
|
|
200
|
+
* await prerender(
|
|
201
|
+
* { route: "products.detail", params: { id: "42" } },
|
|
202
|
+
* { throwOnError: true },
|
|
203
|
+
* );
|
|
204
|
+
* await prerender.many(targets, { concurrency: 4 });
|
|
205
|
+
* await prerender.markStale(["product:42"]);
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
prerender: import("../prerender/on-demand.js").PrerenderFn<TEnv, TRoutes>;
|
|
187
209
|
}
|
|
188
210
|
/**
|
|
189
211
|
* Internal Rango router interface — the full framework-facing API.
|
|
@@ -254,6 +276,12 @@ export interface RangoInternal<TEnv = any, TRoutes extends Record<string, unknow
|
|
|
254
276
|
* Cache configuration
|
|
255
277
|
*/
|
|
256
278
|
readonly cache?: RangoOptions<TEnv>["cache"];
|
|
279
|
+
/**
|
|
280
|
+
* Prerender store configuration (the writable durable overlay for on-demand
|
|
281
|
+
* prerender). Stored separately from the `prerender` trigger method so the RSC
|
|
282
|
+
* handler can resolve it per request. @internal
|
|
283
|
+
*/
|
|
284
|
+
readonly _prerenderConfig?: RangoOptions<TEnv>["prerender"];
|
|
257
285
|
/**
|
|
258
286
|
* Not found component to render when no route matches
|
|
259
287
|
*/
|
|
@@ -471,6 +499,8 @@ export interface RangoInternal<TEnv = any, TRoutes extends Record<string, unknow
|
|
|
471
499
|
* Handle an RSC request.
|
|
472
500
|
*/
|
|
473
501
|
fetch(request: Request, input?: RouterRequestInput<TEnv>): Promise<Response>;
|
|
502
|
+
/** On-demand prerender binder: router.prerender({ env, ctx }) returns the runner. */
|
|
503
|
+
prerender: import("../prerender/on-demand.js").PrerenderFn<TEnv, TRoutes>;
|
|
474
504
|
}
|
|
475
505
|
/**
|
|
476
506
|
* Assert a public Rango into the internal type.
|
|
@@ -314,6 +314,30 @@ export interface RangoOptions<TEnv = any> {
|
|
|
314
314
|
enabled?: boolean;
|
|
315
315
|
searchParams?: CacheSearchParams;
|
|
316
316
|
});
|
|
317
|
+
/**
|
|
318
|
+
* Writable prerender store for on-demand (ISR-style) prerender refresh.
|
|
319
|
+
*
|
|
320
|
+
* A durable overlay in front of the bundled build manifest. When provided,
|
|
321
|
+
* `router.prerender(target, { env, ctx })` renders a route requestlessly and
|
|
322
|
+
* writes a versioned payload here; the serve path reads the overlay before the
|
|
323
|
+
* bundled manifest. Same union shape as `cache`: a plain config object or a
|
|
324
|
+
* factory resolved per request/per call (never at `createRouter()` time), so
|
|
325
|
+
* multi-tenant apps never memoize one request's binding for another.
|
|
326
|
+
*
|
|
327
|
+
* @example Cloudflare KV overlay with SWR revalidation
|
|
328
|
+
* ```typescript
|
|
329
|
+
* import { createKVPrerenderStore } from "@rangojs/router/prerender/cloudflare";
|
|
330
|
+
*
|
|
331
|
+
* const router = createRouter<AppEnv>({
|
|
332
|
+
* prerender: (env) => ({
|
|
333
|
+
* store: createKVPrerenderStore(env.PRERENDER_KV),
|
|
334
|
+
* ttl: 3600,
|
|
335
|
+
* onRevalidate: (target, e) => e.PRERENDER_QUEUE.send({ target }),
|
|
336
|
+
* }),
|
|
337
|
+
* });
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
prerender?: import("../prerender/on-demand.js").PrerenderConfig<TEnv> | ((env: TEnv, ctx?: ExecutionContext) => import("../prerender/on-demand.js").PrerenderConfig<TEnv>);
|
|
317
341
|
/**
|
|
318
342
|
* Named cache profiles for "use cache" directive.
|
|
319
343
|
* Profile names map to TTL/SWR configuration.
|
|
@@ -37,6 +37,13 @@ export interface ResolveSegmentOptions {
|
|
|
37
37
|
* #918: resolved twice on a MISS, once and discarded on a HIT).
|
|
38
38
|
*/
|
|
39
39
|
chain?: readonly EntryData[];
|
|
40
|
+
/**
|
|
41
|
+
* The matched chain entry being resolved: where the sync path catches a
|
|
42
|
+
* handler error, so a streamed handler (or slot owned by a routeless layout)
|
|
43
|
+
* recovers into the same boundary. resolveSegment sets it for the entry it
|
|
44
|
+
* resolves; nested resolutions keep the outer value.
|
|
45
|
+
*/
|
|
46
|
+
boundaryEntry?: EntryData;
|
|
40
47
|
}
|
|
41
48
|
/**
|
|
42
49
|
* Resolve segments from EntryData.
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* 1. options.key(requestCtx) — full override, stored namespaced as
|
|
10
10
|
* loader:{loaderId}:key:{encodeURIComponent(result)} (#1009)
|
|
11
11
|
* 2. store.keyGenerator(requestCtx, defaultKey) — store-level modification
|
|
12
|
-
* 3. loader:{loaderId}:{host}{pathname}:{sortedParams} — default
|
|
12
|
+
* 3. loader:{loaderId}:{routerId}@{host}{pathname}:{sortedParams} — default
|
|
13
|
+
* (a loader's ctx is one router's: cache-key-utils.ts, the router rule)
|
|
13
14
|
*
|
|
14
15
|
* Values are serialized via RSC Flight (serializeResult/deserializeResult),
|
|
15
16
|
* supporting ReactNode, Promises, null, and all RSC-serializable types.
|
|
@@ -51,6 +51,8 @@ export declare function resolveParallelSegmentsWithRevalidation<TEnv>(entry: Ent
|
|
|
51
51
|
* to it: loader sub-ids are filtered out and slots are re-grouped by parent).
|
|
52
52
|
*/
|
|
53
53
|
loaderOrder?: "after" | "before";
|
|
54
|
+
/** Matched chain entry being resolved; see ResolveSegmentOptions.boundaryEntry. */
|
|
55
|
+
boundaryEntry?: EntryData;
|
|
54
56
|
}): Promise<SegmentRevalidationResult>;
|
|
55
57
|
/**
|
|
56
58
|
* Resolve entry handler (layout, cache, or route) with revalidation.
|
|
@@ -74,7 +76,9 @@ chain?: readonly EntryData[]): Promise<SegmentRevalidationResult>;
|
|
|
74
76
|
*/
|
|
75
77
|
export declare function resolveOrphanLayoutWithRevalidation<TEnv>(orphan: EntryData, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, routeKey: string, belongsToRoute: boolean, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean,
|
|
76
78
|
/** Parent route entry — its loaders are inherited so parallel slots can access them. */
|
|
77
|
-
parentRouteEntry?: EntryData
|
|
79
|
+
parentRouteEntry?: EntryData,
|
|
80
|
+
/** Matched chain entry being resolved (see ResolveSegmentOptions.boundaryEntry); defaults to parentRouteEntry. */
|
|
81
|
+
boundaryEntry?: EntryData | undefined): Promise<SegmentRevalidationResult>;
|
|
78
82
|
/**
|
|
79
83
|
* Resolve all segments for a route with revalidation logic (for matchPartial).
|
|
80
84
|
*/
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streamed handlers (loading()): track, observe, and recover a rejection into
|
|
3
|
+
* the declared errorBoundary() / notFoundBoundary() fallback.
|
|
4
|
+
*
|
|
5
|
+
* Invariants:
|
|
6
|
+
* - No status write and no onError call: the status is committed at first
|
|
7
|
+
* flush, and trackHandler already reports each rejection once.
|
|
8
|
+
* - The recovered promise resolves, so Flight reports no error. The writers
|
|
9
|
+
* that refuse a failed render through Flight errors need the failure
|
|
10
|
+
* recorded here: `_renderErrors` for the document cache and a prerender
|
|
11
|
+
* warm, `_recoveredHandlerErrors` for cacheRoute (cache(), and the doc record
|
|
12
|
+
* a PPR capture needs). The shell capture and the SWR re-render own both,
|
|
13
|
+
* so a derived render never writes into (or reads) the foreground's.
|
|
14
|
+
* - Nothing to render to rethrows the original rejection: no boundary found, a
|
|
15
|
+
* thrown Response (redirect), a Skip, a throwing fallback.
|
|
16
|
+
* - No recovery when `recover` is false (prerender throwOnError, the intercept
|
|
17
|
+
* background re-render): those lanes must reject so nothing is baked/cached.
|
|
18
|
+
*/
|
|
19
|
+
import type { ReactNode } from "react";
|
|
20
|
+
import type { EntryData } from "../../server/context.js";
|
|
21
|
+
import type { ErrorInfo, HandlerContext } from "../../types/index.js";
|
|
22
|
+
import type { SegmentResolutionDeps } from "../types.js";
|
|
23
|
+
export interface StreamedHandlerOptions<TEnv> {
|
|
24
|
+
/**
|
|
25
|
+
* Entry to look boundaries up from: the matched chain entry being resolved
|
|
26
|
+
* (where the sync path catches, whatever routeless layout owns a slot), or
|
|
27
|
+
* the intercept's declaring entry.
|
|
28
|
+
*/
|
|
29
|
+
boundaryEntry: EntryData;
|
|
30
|
+
segmentId: string;
|
|
31
|
+
segmentType: ErrorInfo["segmentType"];
|
|
32
|
+
context: HandlerContext<any, TEnv>;
|
|
33
|
+
routeKey?: string;
|
|
34
|
+
params: Record<string, string>;
|
|
35
|
+
/** False where the rejection must reach the caller (prerender, intercept background re-render). */
|
|
36
|
+
recover: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Track a streamed handler promise and return the segment component: the
|
|
40
|
+
* tracked promise itself when there is nothing to recover to, else a promise
|
|
41
|
+
* that resolves to the declared fallback on rejection.
|
|
42
|
+
*/
|
|
43
|
+
export declare function trackStreamedHandler<TEnv>(deps: SegmentResolutionDeps<TEnv>, result: Promise<unknown>, options: StreamedHandlerOptions<TEnv>): ReactNode;
|
|
@@ -18,6 +18,8 @@ export interface TrieMatchResult {
|
|
|
18
18
|
pr?: true;
|
|
19
19
|
/** Passthrough: handler kept for live fallback on unknown params */
|
|
20
20
|
pt?: true;
|
|
21
|
+
/** On-demand prerender eligible (router.prerender() refreshable) */
|
|
22
|
+
od?: true;
|
|
21
23
|
/** Response type for non-RSC routes (json, text, image, any) */
|
|
22
24
|
responseType?: string;
|
|
23
25
|
/** Negotiate variants: response-type routes sharing this path */
|
|
@@ -36,7 +36,7 @@ export interface BuildShellEntry {
|
|
|
36
36
|
tags?: string[];
|
|
37
37
|
}
|
|
38
38
|
interface ShellManifestModule {
|
|
39
|
-
/** Manifest key (
|
|
39
|
+
/** Manifest key (router id + pathname, shell-manifest-key.ts) -> asset specifier. */
|
|
40
40
|
default: Record<string, string>;
|
|
41
41
|
loadShellAsset: (spec: string) => Promise<{
|
|
42
42
|
default: BuildShellEntry;
|
|
@@ -80,11 +80,13 @@ export interface DevShellLookup {
|
|
|
80
80
|
* request is search-less, like the entries lookupBuildShell serves): a
|
|
81
81
|
* manifest entry for the path in production, a Prerender route in dev. No
|
|
82
82
|
* asset load and no dev capture: it only decides whether a request that
|
|
83
|
-
* cannot read the build shell deserves a warning.
|
|
83
|
+
* cannot read the build shell deserves a warning. The manifest entry is the
|
|
84
|
+
* one staged for the router `routerId` (shell-manifest-key.ts).
|
|
84
85
|
*/
|
|
85
|
-
export declare function hasBuildShell(pathname: string, dev?: DevShellLookup): Promise<boolean>;
|
|
86
|
+
export declare function hasBuildShell(routerId: string, pathname: string, dev?: DevShellLookup): Promise<boolean>;
|
|
86
87
|
/**
|
|
87
88
|
* Look up the baked shell entry for a request, applying every serve gate:
|
|
89
|
+
* the serving router's own entry only (`routerId`, shell-manifest-key.ts),
|
|
88
90
|
* search-less requests only (the build captured the bare pathname; a
|
|
89
91
|
* search-bearing URL has its own shell identity owned by runtime capture),
|
|
90
92
|
* version validity, payload integrity, and tag-invalidation markers. Returns
|
|
@@ -96,5 +98,5 @@ export declare function hasBuildShell(pathname: string, dev?: DevShellLookup): P
|
|
|
96
98
|
* exclusion) matches the baked shell — ad-click traffic is exactly the
|
|
97
99
|
* traffic the shell was prerendered for.
|
|
98
100
|
*/
|
|
99
|
-
export declare function lookupBuildShell(url: URL, buildVersion: string, store: SegmentCacheStore, dev?: DevShellLookup, filter?: SearchParamsFilter): Promise<BuildShellHit | null>;
|
|
101
|
+
export declare function lookupBuildShell(routerId: string, url: URL, buildVersion: string, store: SegmentCacheStore, dev?: DevShellLookup, filter?: SearchParamsFilter): Promise<BuildShellHit | null>;
|
|
100
102
|
export {};
|
|
@@ -56,13 +56,14 @@ export type PprReplayBypassReason = (typeof PPR_REPLAY_BYPASS_REASONS)[number];
|
|
|
56
56
|
*/
|
|
57
57
|
export declare function shellSearchSeed(url: URL, filter?: SearchParamsFilter): string;
|
|
58
58
|
/**
|
|
59
|
-
* Shell cache key: host + pathname + sorted search + a `:shell`
|
|
60
|
-
* (so it can never collide with a document-cache key; the
|
|
61
|
-
* the shell family internally).
|
|
59
|
+
* Shell cache key: router id + host + pathname + sorted search + a `:shell`
|
|
60
|
+
* namespace suffix (so it can never collide with a document-cache key; the
|
|
61
|
+
* store further isolates the shell family internally).
|
|
62
62
|
*
|
|
63
63
|
* The key includes the request HOST: in a multi-tenant host-router deployment
|
|
64
64
|
* (one worker, one shared KV/runtime-cache store) a host-less key would serve
|
|
65
|
-
* tenant A's captured shell to tenant B's users.
|
|
65
|
+
* tenant A's captured shell to tenant B's users. It starts with the serving
|
|
66
|
+
* ROUTER for the same reason (cache-key-utils.ts, the router rule).
|
|
66
67
|
*
|
|
67
68
|
* `filter` is the request's compiled `cache.searchParams` config
|
|
68
69
|
* (ctx._searchParamsFilter): excluded params collapse onto one shell slot.
|
|
@@ -70,7 +71,7 @@ export declare function shellSearchSeed(url: URL, filter?: SearchParamsFilter):
|
|
|
70
71
|
* and lookup makes every shell request a permanent miss. The testing helper
|
|
71
72
|
* `shellCacheKey` (testing/shell-status.ts) builds its key with it too.
|
|
72
73
|
*/
|
|
73
|
-
export declare function buildShellKey(url: URL, filter?: SearchParamsFilter): string;
|
|
74
|
+
export declare function buildShellKey(routerId: string, url: URL, filter?: SearchParamsFilter): string;
|
|
74
75
|
/**
|
|
75
76
|
* The shell key for one request partition (cache-scope.ts
|
|
76
77
|
* resolveShellPartition): the route cache() `key()` or store keyGenerator
|
|
@@ -133,6 +134,20 @@ export declare const POST_QUIESCE_TASK_HOPS = 16;
|
|
|
133
134
|
* check on the stampede guard, keyed off the same constant.
|
|
134
135
|
*/
|
|
135
136
|
export declare const SHELL_CAPTURE_TASK_HARD_CAP_MS = 25000;
|
|
137
|
+
/**
|
|
138
|
+
* Why a capture attempt refused to store its shell
|
|
139
|
+
* (ShellCaptureDebugEvent.refusal, `caches.refusal` on a `router.prerender()`
|
|
140
|
+
* result): `identity` (a request-scoped read: cookies(), headers(), the
|
|
141
|
+
* theme, a `{ cache: false }` variable), `dynamic` (`ctx.dynamic()`),
|
|
142
|
+
* `loader` (a `{ ssr: false }` loader rejected, or settled with
|
|
143
|
+
* redirect()/notFound()), `no-record` (no doc record: the route's cache()
|
|
144
|
+
* refused the write, or the handler output failed), `handles` (a pushed
|
|
145
|
+
* handle value did not finish encoding), `size` (over the store's value
|
|
146
|
+
* limit), `record-expired` (the route cache() record the capture wrote ran
|
|
147
|
+
* out first), `invalidated` (a tag of the shell was invalidated after the
|
|
148
|
+
* capture started), `uncacheable` (the store cannot hold the entry).
|
|
149
|
+
*/
|
|
150
|
+
export type ShellCaptureRefusal = "identity" | "dynamic" | "loader" | "no-record" | "handles" | "size" | "record-expired" | "invalidated" | "uncacheable";
|
|
136
151
|
/**
|
|
137
152
|
* Shared PPR loader-lane hint, appended to every capture warning or error
|
|
138
153
|
* whose fix depends on the lane (shell-capture.ts warnings, the cookie-store.ts
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* (variables, cache store). Guarding is serve-time.
|
|
20
20
|
*/
|
|
21
21
|
import { type MatchResult } from "../types.js";
|
|
22
|
+
import { type ShellCaptureRefusal } from "./shell-capture-constants.js";
|
|
22
23
|
import { type RequestContext, type RouteRecordWindow } from "../server/request-context.js";
|
|
23
24
|
import { type HandleStore } from "../server/handle-store.js";
|
|
24
25
|
import type { SegmentCacheStore } from "../cache/types.js";
|
|
@@ -170,6 +171,8 @@ export interface ShellCaptureDebugEvent {
|
|
|
170
171
|
untaggedBake?: true;
|
|
171
172
|
/** Outcome reported by a store that supports shell-write acknowledgements. */
|
|
172
173
|
storeWrite?: "stored" | "invalidated" | "uncacheable";
|
|
174
|
+
/** Why a `refused` attempt refused. */
|
|
175
|
+
refusal?: ShellCaptureRefusal;
|
|
173
176
|
/** Consecutive failure count in the key's backoff entry, when one exists. */
|
|
174
177
|
backoffFailures?: number;
|
|
175
178
|
/** Ms remaining in the key's backoff window, when one exists. */
|
|
@@ -335,6 +338,15 @@ export interface ShellCaptureDescriptor {
|
|
|
335
338
|
* re-render the page and drop the isolate's memo of the shell just stored.
|
|
336
339
|
*/
|
|
337
340
|
storedSeqAtRead?: number;
|
|
341
|
+
/**
|
|
342
|
+
* A `router.prerender()` warm's capture (rsc-rendering.ts shellServePlan):
|
|
343
|
+
* one explicit call that must store, so the guards that shed a herd of
|
|
344
|
+
* visitors do not apply to it. scheduleShellCapture skips the in-flight
|
|
345
|
+
* dedup and the refused-capture backoff, and attemptCapture waits longer on
|
|
346
|
+
* the write barrier. Every correctness guard, the inert-store skip and the
|
|
347
|
+
* queue limits still decide.
|
|
348
|
+
*/
|
|
349
|
+
force?: true;
|
|
338
350
|
}
|
|
339
351
|
/** The latest stored capture's sequence number for `key` in this isolate, or 0. */
|
|
340
352
|
export declare function lastStoredCaptureSeq(key: string): number;
|
|
@@ -400,7 +412,7 @@ type CaptureTaskOutcome = "stored" | "redirect" | "no-shell";
|
|
|
400
412
|
* the warning. A plain mutable bag, not a return value: captureAndStoreShell's
|
|
401
413
|
* outcome type stays a string union producer B consumes unchanged.
|
|
402
414
|
*/
|
|
403
|
-
type CaptureAttemptStats = Pick<ShellCaptureDebugEvent, "barrierWaitMs" | "writeSettleMs" | "preludeBytes" | "snapshotBytes" | "snapshotSkipped" | "untaggedBake" | "storeWrite" | "recordSettleMs" | "entryBytes"> & {
|
|
415
|
+
type CaptureAttemptStats = Pick<ShellCaptureDebugEvent, "barrierWaitMs" | "writeSettleMs" | "preludeBytes" | "snapshotBytes" | "snapshotSkipped" | "untaggedBake" | "storeWrite" | "refusal" | "recordSettleMs" | "entryBytes"> & {
|
|
404
416
|
/**
|
|
405
417
|
* Why a no-shell attempt ran out of ppr.captureTimeout (the match, the
|
|
406
418
|
* handler output, or the prerender after them). A set cause skips the
|
|
@@ -462,6 +474,7 @@ export type CaptureRecordOutcome = {
|
|
|
462
474
|
reason: string;
|
|
463
475
|
} | {
|
|
464
476
|
kind: "refused";
|
|
477
|
+
refusal: ShellCaptureRefusal;
|
|
465
478
|
};
|
|
466
479
|
/**
|
|
467
480
|
* Record-first capture: the doc record is both the settle signal and the
|
|
@@ -274,7 +274,7 @@ export declare function warnPprWindowCappedOnce(routeName: string, ppr: {
|
|
|
274
274
|
* Whether a partitioned request needs no build-shell probe: its route was
|
|
275
275
|
* already warned, or its path was already found without one.
|
|
276
276
|
*/
|
|
277
|
-
export declare function partitionBuildShellCheckDone(pathname: string, routeName: string | undefined): boolean;
|
|
277
|
+
export declare function partitionBuildShellCheckDone(routerId: string, pathname: string, routeName: string | undefined): boolean;
|
|
278
278
|
/**
|
|
279
279
|
* Record a partitioned request's build-shell probe, and warn once per route
|
|
280
280
|
* when it found one: the route has a build-time shell its requests cannot
|
|
@@ -285,7 +285,7 @@ export declare function partitionBuildShellCheckDone(pathname: string, routeName
|
|
|
285
285
|
* declared-intent-cannot-be-honored doctrine as the warnings above; a path
|
|
286
286
|
* with no build shell stays silent.
|
|
287
287
|
*/
|
|
288
|
-
export declare function notePartitionBuildShellCheck(pathname: string, routeName: string | undefined, found: boolean): void;
|
|
288
|
+
export declare function notePartitionBuildShellCheck(routerId: string, pathname: string, routeName: string | undefined, found: boolean): void;
|
|
289
289
|
/**
|
|
290
290
|
* @internal Reset the serve path's once-per-key warnings (the shell path's
|
|
291
291
|
* one registry), its build-shell probe memo and buffered tail timings. Tests
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SSR module loader a handler created without `loadSSRModule` falls back
|
|
3
|
+
* to in tests (`router.fetch` creates its handler that way). A leaf with no
|
|
4
|
+
* runtime imports: testing/serve-shell-request.ts installs its stub here when
|
|
5
|
+
* it loads, without importing rsc/handler.ts (which binds build-only virtual
|
|
6
|
+
* modules a flight-only test config does not alias).
|
|
7
|
+
*/
|
|
8
|
+
import type { LoadSSRModule } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* @internal Tests only: `router.prerender()` warms through `router.fetch`,
|
|
11
|
+
* and the rsc Vitest project cannot run `import.meta.viteRsc.loadModule`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function setDefaultSSRModuleLoaderForTests(loader: LoadSSRModule | undefined): void;
|
|
14
|
+
/** @internal Undefined everywhere but in tests. */
|
|
15
|
+
export declare function defaultSSRModuleLoaderForTests(): LoadSSRModule | undefined;
|
|
@@ -103,6 +103,14 @@ export interface RscPayload {
|
|
|
103
103
|
ok: boolean;
|
|
104
104
|
data: unknown;
|
|
105
105
|
};
|
|
106
|
+
/**
|
|
107
|
+
* useActionState form state of a progressive-enhancement POST re-render
|
|
108
|
+
* (the value the SSR render received). Present only on that document; the
|
|
109
|
+
* browser entry passes it to hydrateRoot so the hydrated hook matches the
|
|
110
|
+
* server HTML instead of resetting to its initial state. A promise so a
|
|
111
|
+
* state Flight cannot serialize rejects this slot alone.
|
|
112
|
+
*/
|
|
113
|
+
formState?: Promise<ReactFormState>;
|
|
106
114
|
}
|
|
107
115
|
/**
|
|
108
116
|
* React form state type for useActionState progressive enhancement
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* What a RouteContentWrapper receives as `content`.
|
|
4
|
+
*
|
|
5
|
+
* Browser: hand over the settled value. React treats a promise as fulfilled
|
|
6
|
+
* only after it has read it, and a boundary on screen handed a promise it has
|
|
7
|
+
* not read, in a render that cannot wait, shows its fallback. A component that
|
|
8
|
+
* is already a promise (a Flight-streamed segment) is returned as is, since
|
|
9
|
+
* it can really be pending.
|
|
10
|
+
*
|
|
11
|
+
* Server: a fresh `Promise.resolve(component)` per call, so Suspense emits the
|
|
12
|
+
* fallback in the streamed HTML. A shared resolved promise would carry React's
|
|
13
|
+
* `.status` across requests and skip it.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export declare function getBoundaryContent(component: ReactNode): ReactNode;
|
|
@@ -10,12 +10,8 @@ import type { ResolvedSegment } from "./types.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function buildLoaderPromise(loaders: ResolvedSegment[]): Promise<any[]>;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* loader.loaderData ref changes — keeps React's `use()` in "known fulfilled"
|
|
16
|
-
* state and prevents a fresh Promise.all from suspending (and briefly
|
|
17
|
-
* committing the Suspense fallback) on every partial update that doesn't
|
|
18
|
-
* actually change loader data.
|
|
13
|
+
* The aggregate for a set of loader segments, memoized on their `loaderData`
|
|
14
|
+
* refs: the settled array once it has fulfilled, the promise before that.
|
|
19
15
|
*
|
|
20
16
|
* @internal
|
|
21
17
|
*/
|
|
@@ -8,6 +8,15 @@ import { type RouterVersions, type RouterVersionsTable } from "../router-version
|
|
|
8
8
|
* 3. `VERSION` for both: the dev stamp, bumped on every RSC module edit.
|
|
9
9
|
*/
|
|
10
10
|
export declare function resolveRouterVersions(routerId: string | undefined, override?: string): RouterVersions;
|
|
11
|
+
/**
|
|
12
|
+
* The version an on-demand prerender overlay key carries: the router's data
|
|
13
|
+
* version, because the overlay stores segment data, as the segment cache does
|
|
14
|
+
* (a client-only deploy keeps both). The write side (`router.prerender`,
|
|
15
|
+
* router.ts) and the read side (rsc/handler.ts) both call this with
|
|
16
|
+
* `createRouter({ version })`, the only override the trigger can see, so they
|
|
17
|
+
* cannot disagree; a `createRSCHandler({ version })` does not move it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolvePrerenderVersion(routerId: string | undefined, routerVersion: string | undefined): string;
|
|
11
20
|
/**
|
|
12
21
|
* The versions of the router serving the current request, for a cache store
|
|
13
22
|
* building a key. A store operation with no request context (a detached task
|