@rangojs/router 0.15.1 → 0.17.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 +254 -89
- package/dist/testing/vitest.js +252 -0
- package/dist/types/browser/navigation-transaction.d.ts +6 -0
- package/dist/types/browser/partial-update.d.ts +11 -0
- package/dist/types/browser/react/ScrollRestoration.d.ts +6 -6
- package/dist/types/browser/rsc-router.d.ts +1 -1
- package/dist/types/browser/scroll-restoration.d.ts +7 -0
- package/dist/types/cache/cache-exec-scope.d.ts +18 -1
- package/dist/types/cache/cache-scope.d.ts +34 -5
- package/dist/types/cache/handle-capture.d.ts +41 -3
- package/dist/types/cache/handle-snapshot.d.ts +53 -13
- package/dist/types/cache/segment-codec.d.ts +10 -3
- package/dist/types/cache/taint.d.ts +1 -1
- package/dist/types/cache/types.d.ts +15 -3
- package/dist/types/client.d.ts +4 -4
- package/dist/types/client.rsc.d.ts +4 -5
- package/dist/types/components/DefaultDocument.d.ts +5 -2
- package/dist/types/context-var.d.ts +6 -5
- package/dist/types/escape-script.d.ts +1 -1
- package/dist/types/handles/MetaTags.d.ts +5 -4
- package/dist/types/handles/Scripts.d.ts +8 -7
- package/dist/types/handles/meta.d.ts +2 -2
- package/dist/types/handles/script.d.ts +17 -16
- package/dist/types/href-client.d.ts +1 -1
- package/dist/types/html.d.ts +12 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +3 -2
- package/dist/types/loader-store.d.ts +52 -0
- package/dist/types/reverse.d.ts +36 -4
- package/dist/types/route-definition/dsl-helpers.d.ts +3 -3
- package/dist/types/route-definition/helpers-types.d.ts +36 -10
- package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
- package/dist/types/route-types.d.ts +3 -1
- package/dist/types/router/debug-manifest.d.ts +3 -2
- package/dist/types/router/error-handling.d.ts +20 -0
- package/dist/types/router/handler-context.d.ts +6 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +46 -5
- package/dist/types/router/middleware-types.d.ts +3 -2
- package/dist/types/router/router-context.d.ts +3 -1
- package/dist/types/router/router-interfaces.d.ts +24 -2
- package/dist/types/router/router-options.d.ts +8 -5
- package/dist/types/router/segment-resolution/fresh.d.ts +10 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +37 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +9 -19
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +3 -3
- package/dist/types/router/segment-resolution/mask-nested.d.ts +7 -7
- package/dist/types/router/segment-resolution/revalidation.d.ts +6 -2
- package/dist/types/router/segment-wrappers.d.ts +1 -1
- package/dist/types/rsc/response-route-handler.d.ts +1 -1
- package/dist/types/rsc/rsc-rendering.d.ts +1 -2
- package/dist/types/rsc/shell-capture-constants.d.ts +8 -0
- package/dist/types/rsc/shell-capture.d.ts +5 -4
- package/dist/types/rsc/ssr-setup.d.ts +6 -6
- package/dist/types/rsc/types.d.ts +10 -0
- package/dist/types/server/context.d.ts +33 -3
- package/dist/types/server/handle-store.d.ts +26 -2
- package/dist/types/server/request-context.d.ts +24 -21
- package/dist/types/ssr/index.d.ts +15 -0
- package/dist/types/static-handler.d.ts +4 -1
- package/dist/types/testing/generated-routes.d.ts +2 -2
- package/dist/types/testing/internal/context.d.ts +1 -1
- package/dist/types/testing/render-route.d.ts +32 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +28 -5
- package/dist/types/testing/vitest.d.ts +35 -1
- package/dist/types/theme/ThemeScript.d.ts +3 -3
- package/dist/types/thenable-status.d.ts +9 -0
- package/dist/types/types/cache-types.d.ts +14 -10
- package/dist/types/types/handler-context.d.ts +14 -0
- package/dist/types/types/loader-types.d.ts +8 -6
- package/dist/types/urls/response-types.d.ts +3 -12
- package/dist/types/use-loader.d.ts +12 -3
- package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
- package/dist/types/vite/rango.d.ts +1 -1
- package/dist/vite/index.js +884 -768
- package/package.json +4 -4
- package/skills/api-client/SKILL.md +22 -10
- package/skills/breadcrumbs/SKILL.md +65 -22
- package/skills/bundle-analysis/SKILL.md +22 -22
- package/skills/cache-guide/SKILL.md +207 -97
- package/skills/caching/SKILL.md +295 -93
- package/skills/catalog.json +16 -16
- package/skills/client-urls/SKILL.md +53 -31
- package/skills/cloudflare/SKILL.md +72 -20
- package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
- package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
- package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
- package/skills/comparison/SKILL.md +5 -0
- package/skills/comparison/references/framework-comparison.md +39 -33
- package/skills/composability/SKILL.md +38 -29
- package/skills/css/SKILL.md +10 -13
- package/skills/debug-manifest/SKILL.md +74 -31
- package/skills/defer-hydration/SKILL.md +2 -1
- package/skills/deployment-caching/SKILL.md +6 -1
- package/skills/document-cache/SKILL.md +92 -28
- package/skills/fonts/SKILL.md +16 -8
- package/skills/handler-use/SKILL.md +53 -17
- package/skills/hooks/SKILL.md +28 -20
- package/skills/hooks/data.md +43 -1
- package/skills/hooks/handle-and-actions.md +31 -16
- package/skills/hooks/navigation.md +39 -10
- package/skills/hooks/outlets.md +13 -6
- package/skills/hooks/state.md +37 -15
- package/skills/hooks/urls.md +7 -5
- package/skills/host-router/SKILL.md +64 -12
- package/skills/i18n/SKILL.md +60 -34
- package/skills/intercept/SKILL.md +161 -26
- package/skills/layout/SKILL.md +106 -50
- package/skills/links/SKILL.md +51 -19
- package/skills/loader/SKILL.md +242 -106
- package/skills/middleware/SKILL.md +119 -23
- package/skills/migrate-nextjs/SKILL.md +100 -45
- package/skills/migrate-nextjs/backend-host-swap.md +5 -2
- package/skills/migrate-react-router/SKILL.md +49 -38
- package/skills/migrate-react-router/component-migration.md +25 -6
- package/skills/migrate-react-router/data-and-actions.md +18 -5
- package/skills/migrate-react-router/route-mapping.md +12 -6
- package/skills/mime-routes/SKILL.md +12 -7
- package/skills/observability/SKILL.md +28 -14
- package/skills/parallel/SKILL.md +75 -39
- package/skills/ppr/SKILL.md +345 -150
- package/skills/prerender/SKILL.md +189 -100
- package/skills/rango/SKILL.md +65 -34
- package/skills/react-compiler/SKILL.md +6 -5
- package/skills/response-routes/SKILL.md +133 -25
- package/skills/route/SKILL.md +165 -60
- package/skills/router-setup/SKILL.md +418 -240
- package/skills/scripts/SKILL.md +31 -20
- package/skills/server-actions/SKILL.md +220 -59
- package/skills/shell-manifest/SKILL.md +12 -7
- package/skills/streams-and-websockets/SKILL.md +32 -14
- package/skills/tailwind/SKILL.md +37 -33
- package/skills/testing/SKILL.md +68 -32
- package/skills/testing/cache-prerender.md +55 -29
- package/skills/testing/client-components.md +59 -6
- package/skills/testing/e2e-parity.md +12 -2
- package/skills/testing/flight.md +19 -11
- package/skills/testing/handles.md +8 -5
- package/skills/testing/loader.md +8 -5
- package/skills/testing/middleware.md +8 -3
- package/skills/testing/predicates.md +120 -0
- package/skills/testing/render-handler.md +70 -22
- package/skills/testing/response-routes.md +11 -4
- package/skills/testing/reverse-and-types.md +20 -14
- package/skills/testing/server-actions.md +12 -3
- package/skills/testing/server-tree.md +9 -0
- package/skills/testing/setup.md +9 -5
- package/skills/theme/SKILL.md +106 -29
- package/skills/typesafety/SKILL.md +20 -9
- package/skills/typesafety/env-and-bindings.md +126 -47
- package/skills/typesafety/generated-files-and-cli.md +26 -14
- package/skills/typesafety/params-and-search.md +44 -19
- package/skills/typesafety/route-types.md +50 -14
- package/skills/use-cache/SKILL.md +200 -82
- package/skills/vercel/SKILL.md +21 -11
- package/skills/view-transitions/SKILL.md +41 -20
- package/src/__augment-tests__/augmented.check.ts +26 -1
- package/src/browser/index.ts +2 -2
- package/src/browser/navigation-bridge.ts +3 -4
- package/src/browser/navigation-transaction.ts +22 -2
- package/src/browser/partial-update.ts +75 -80
- package/src/browser/react/ScrollRestoration.tsx +6 -6
- package/src/browser/rsc-router.tsx +1 -1
- package/src/browser/scroll-restoration.ts +53 -6
- package/src/cache/cache-exec-scope.ts +37 -4
- package/src/cache/cache-key-utils.ts +1 -6
- package/src/cache/cache-runtime.ts +230 -61
- package/src/cache/cache-scope.ts +76 -12
- package/src/cache/document-cache.ts +15 -0
- package/src/cache/handle-capture.ts +90 -10
- package/src/cache/handle-snapshot.ts +132 -28
- package/src/cache/segment-codec.ts +26 -7
- package/src/cache/tag-invalidation.ts +4 -3
- package/src/cache/taint.ts +1 -1
- package/src/cache/types.ts +16 -3
- package/src/client.rsc.tsx +10 -9
- package/src/client.tsx +5 -4
- package/src/components/DefaultDocument.tsx +7 -2
- package/src/context-var.ts +6 -5
- package/src/escape-script.ts +1 -1
- package/src/handles/MetaTags.tsx +13 -11
- package/src/handles/Scripts.tsx +11 -10
- package/src/handles/meta.ts +2 -2
- package/src/handles/script.ts +17 -16
- package/src/href-client.ts +1 -1
- package/src/html.ts +12 -0
- package/src/index.rsc.ts +5 -0
- package/src/index.ts +1 -0
- package/src/loader-store.ts +106 -0
- package/src/prerender/build-shell-capture.ts +8 -11
- package/src/reverse.ts +44 -4
- package/src/route-definition/dsl-helpers.ts +134 -42
- package/src/route-definition/helpers-types.ts +36 -10
- package/src/route-definition/resolve-handler-use.ts +121 -6
- package/src/route-types.ts +2 -3
- package/src/router/debug-manifest.ts +10 -2
- package/src/router/error-handling.ts +51 -15
- package/src/router/handler-context.ts +34 -25
- package/src/router/intercept-resolution.ts +125 -39
- package/src/router/loader-resolution.ts +56 -11
- package/src/router/match-api.ts +12 -17
- package/src/router/match-middleware/background-revalidation.ts +161 -96
- package/src/router/match-middleware/cache-lookup.ts +93 -10
- package/src/router/match-middleware/cache-store.ts +17 -90
- package/src/router/middleware-types.ts +3 -5
- package/src/router/middleware.ts +52 -9
- package/src/router/prerender-match.ts +53 -19
- package/src/router/route-snapshot.ts +11 -1
- package/src/router/router-context.ts +2 -0
- package/src/router/router-interfaces.ts +25 -2
- package/src/router/router-options.ts +8 -5
- package/src/router/segment-resolution/fresh.ts +44 -12
- package/src/router/segment-resolution/loader-cache.ts +205 -45
- package/src/router/segment-resolution/loader-mask.ts +12 -22
- package/src/router/segment-resolution/loader-snapshot.ts +6 -6
- package/src/router/segment-resolution/mask-nested.ts +7 -7
- package/src/router/segment-resolution/revalidation.ts +34 -6
- package/src/router/segment-wrappers.ts +4 -0
- package/src/rsc/render-pipeline.ts +3 -0
- package/src/rsc/response-route-handler.ts +11 -3
- package/src/rsc/rsc-rendering.ts +8 -45
- package/src/rsc/shell-capture-constants.ts +13 -0
- package/src/rsc/shell-capture.ts +111 -90
- package/src/rsc/ssr-setup.ts +14 -8
- package/src/rsc/types.ts +11 -0
- package/src/server/context.ts +88 -11
- package/src/server/cookie-store.ts +5 -4
- package/src/server/handle-store.ts +232 -7
- package/src/server/request-context.ts +35 -30
- package/src/ssr/index.tsx +40 -7
- package/src/ssr-suspension-warning.ts +2 -13
- package/src/static-handler.ts +4 -1
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/generated-routes.ts +2 -2
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/internal/flight-client-globals.ts +7 -5
- package/src/testing/render-route.tsx +85 -24
- package/src/testing/run-loader.ts +5 -1
- package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
- package/src/testing/vitest.ts +62 -1
- package/src/theme/ThemeProvider.tsx +14 -12
- package/src/theme/ThemeScript.tsx +3 -3
- package/src/thenable-status.ts +16 -0
- package/src/types/cache-types.ts +14 -10
- package/src/types/handler-context.ts +14 -0
- package/src/types/loader-types.ts +8 -6
- package/src/urls/response-types.ts +3 -23
- package/src/use-loader.tsx +24 -4
- package/src/vite/plugins/use-cache-transform.ts +118 -74
- package/src/vite/rango.ts +7 -3
|
@@ -102,10 +102,10 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
102
102
|
* intercept("@modal", "card", () => <CardModal />),
|
|
103
103
|
* ])
|
|
104
104
|
*
|
|
105
|
-
* // With loaders and revalidation
|
|
105
|
+
* // With loaders and revalidation (revalidate() goes on the loader;
|
|
106
|
+
* // an intercept-level revalidate() throws)
|
|
106
107
|
* intercept("@modal", "card", () => <CardModal />, () => [
|
|
107
|
-
* loader(CardModalLoader),
|
|
108
|
-
* revalidate(() => false),
|
|
108
|
+
* loader(CardModalLoader, () => [revalidate(() => false)]),
|
|
109
109
|
* ])
|
|
110
110
|
*
|
|
111
111
|
* // Conditional activation via the config object's `when` selector
|
|
@@ -127,7 +127,11 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
127
127
|
* @param handler - Component or handler for intercepted render
|
|
128
128
|
* @param config - Optional InterceptConfig (e.g. `{ when }`), or the use
|
|
129
129
|
* callback directly when there is no config
|
|
130
|
-
* @param use - Optional callback for
|
|
130
|
+
* @param use - Optional callback for loader(), middleware(), loading(),
|
|
131
|
+
* transition() and a layout() modal chrome without use() items.
|
|
132
|
+
* revalidate() (goes on the loader), errorBoundary()/notFoundBoundary()
|
|
133
|
+
* (go on the enclosing layout) and cache() (goes on the target route)
|
|
134
|
+
* throw here.
|
|
131
135
|
*/
|
|
132
136
|
intercept: {
|
|
133
137
|
<K extends keyof ResolvedRouteMap<T> & string>(slotName: `@${string}`, routeName: `.${K}`, handler: ReactNode | Handler<ExtractRouteParams<T, K>, {}, TEnv>, config?: import("../server/context.js").InterceptConfig<TEnv> | (() => UseItems<InterceptUseItem>), use?: () => UseItems<InterceptUseItem>): InterceptItem;
|
|
@@ -183,6 +187,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
183
187
|
* ({ defaultShouldRevalidate: true })
|
|
184
188
|
* )
|
|
185
189
|
* ```
|
|
190
|
+
* Not valid directly inside intercept() use() (throws at definition time):
|
|
191
|
+
* intercepts only revalidate their loaders, so attach it there with
|
|
192
|
+
* `loader(Def, () => [revalidate(...)])`.
|
|
186
193
|
* @param fn - Function returning either:
|
|
187
194
|
* - `boolean` (hard decision — short-circuits the chain),
|
|
188
195
|
* - `{ defaultShouldRevalidate: boolean }` (soft — updates the suggestion
|
|
@@ -245,16 +252,19 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
245
252
|
* ```typescript
|
|
246
253
|
* errorBoundary(<ErrorFallback />)
|
|
247
254
|
*
|
|
248
|
-
* // With dynamic error handler
|
|
249
|
-
* errorBoundary(({ error
|
|
255
|
+
* // With dynamic error handler (server fallback: receives only { error })
|
|
256
|
+
* errorBoundary(({ error }) => (
|
|
250
257
|
* <div>
|
|
251
258
|
* <h2>Something went wrong</h2>
|
|
252
259
|
* <p>{error.message}</p>
|
|
253
|
-
* <
|
|
260
|
+
* <a href="/">Go home</a>
|
|
254
261
|
* </div>
|
|
255
262
|
* ))
|
|
256
263
|
* ```
|
|
257
|
-
*
|
|
264
|
+
* Not valid inside intercept() use() (throws at definition time): an
|
|
265
|
+
* intercept has no boundary of its own, and its loader errors resolve
|
|
266
|
+
* against the enclosing layout/path boundary.
|
|
267
|
+
* @param fallback - Static JSX or handler receiving `{ error }`
|
|
258
268
|
*/
|
|
259
269
|
errorBoundary: (fallback: ReactNode | ErrorBoundaryHandler) => ErrorBoundaryItem;
|
|
260
270
|
/**
|
|
@@ -270,6 +280,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
270
280
|
* </div>
|
|
271
281
|
* ))
|
|
272
282
|
* ```
|
|
283
|
+
* Not valid inside intercept() use() (throws at definition time): an
|
|
284
|
+
* intercept has no boundary of its own, and notFound() from its loaders
|
|
285
|
+
* resolves against the enclosing layout/path boundary.
|
|
273
286
|
* @param fallback - Static JSX or handler receiving not-found info
|
|
274
287
|
*/
|
|
275
288
|
notFoundBoundary: (fallback: ReactNode | NotFoundBoundaryHandler) => NotFoundBoundaryItem;
|
|
@@ -285,6 +298,9 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
285
298
|
* Note: Loaders are NOT cached by default. Use cache() inside loader()
|
|
286
299
|
* to explicitly opt-in to loader caching.
|
|
287
300
|
*
|
|
301
|
+
* Not valid inside intercept() use() (throws at definition time): an
|
|
302
|
+
* intercept navigation is cached under the target route's cache() scope.
|
|
303
|
+
*
|
|
288
304
|
* ```typescript
|
|
289
305
|
* // Using app-level defaults (ttl inherited from store.defaults)
|
|
290
306
|
* cache(() => [
|
|
@@ -319,6 +335,12 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
319
335
|
* route("archive/:year"), // uses KV store
|
|
320
336
|
* ])
|
|
321
337
|
*
|
|
338
|
+
* // Among a path's children: caches that path (handler, layouts, parallels)
|
|
339
|
+
* path("/product/:id", ProductPage, { name: "product" }, () => [
|
|
340
|
+
* cache({ ttl: 60 }),
|
|
341
|
+
* layout(<ProductChrome />), // cached with the path
|
|
342
|
+
* ])
|
|
343
|
+
*
|
|
322
344
|
* // Opt-in loader caching
|
|
323
345
|
* route("product/:id", ProductHandler, () => [
|
|
324
346
|
* loader(ProductLoader), // NOT cached (default)
|
|
@@ -343,8 +365,12 @@ export type RouteHelpers<T extends RouteDefinition, TEnv> = {
|
|
|
343
365
|
* through React's startTransition, so a same-route nav (same route,
|
|
344
366
|
* different params, e.g. /product/1 -> /product/2) holds the previous
|
|
345
367
|
* content while the new loader resolves instead of flashing the route's
|
|
346
|
-
* loading() skeleton (see segment-system.tsx inTransitionScope).
|
|
347
|
-
*
|
|
368
|
+
* loading() skeleton (see segment-system.tsx inTransitionScope). Held
|
|
369
|
+
* useLoader readers of the re-run loaders report isLoading: true until
|
|
370
|
+
* the new data commits (use-loader.tsx). The pin is per loader family
|
|
371
|
+
* (`$$id`), not per segment — a layout reader of the same createLoader
|
|
372
|
+
* the child is re-running is flagged too. This is also the precondition
|
|
373
|
+
* for any view-transition animation.
|
|
348
374
|
* 2. <ViewTransition> (experimental React only): the segment content is also
|
|
349
375
|
* wrapped in React's <ViewTransition>, so the held swap cross-fades/morphs.
|
|
350
376
|
* Layered on by default; pass { viewTransition: false } to keep #1 without
|
|
@@ -6,6 +6,28 @@ import type { AllUseItems } from "../route-types.js";
|
|
|
6
6
|
* ReactNode handlers return undefined (no .use possible).
|
|
7
7
|
*/
|
|
8
8
|
export declare function resolveHandlerUse(handler: unknown): (() => any[]) | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Validate every item an intercept's merged use() returned (explicit use()
|
|
11
|
+
* and handler.use) against MOUNT_SITE_ALLOWED_TYPES.intercept, plus two
|
|
12
|
+
* structural rules:
|
|
13
|
+
* - a nested layout() is only the modal chrome (intercept() keeps its
|
|
14
|
+
* handler), so it may not carry use() items of its own;
|
|
15
|
+
* - a cache entry in `capturedLayouts` means cache() ran in the scope even if
|
|
16
|
+
* it was not returned; its orphan form re-parents the following siblings
|
|
17
|
+
* onto that entry, so it is rejected the same way. Inside a path, cache()
|
|
18
|
+
* writes `sinks.cache` instead (dsl-helpers.ts cache()).
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateInterceptUseItems(items: AllUseItems[], capturedLayouts: readonly {
|
|
21
|
+
type: string;
|
|
22
|
+
}[], slotName: string, routeName: string, sinks: {
|
|
23
|
+
readonly revalidate: readonly unknown[];
|
|
24
|
+
readonly errorBoundary: readonly unknown[];
|
|
25
|
+
readonly notFoundBoundary: readonly unknown[];
|
|
26
|
+
readonly intercept: readonly unknown[];
|
|
27
|
+
readonly parallel: Readonly<Record<string, unknown>>;
|
|
28
|
+
/** Set by cache() when the intercept is declared inside a path. */
|
|
29
|
+
readonly cache?: unknown;
|
|
30
|
+
}): void;
|
|
9
31
|
/**
|
|
10
32
|
* Validate that items from handler.use() are valid for the given mount site.
|
|
11
33
|
* Throws a descriptive error if any item is not allowed.
|
|
@@ -16,4 +38,4 @@ export declare function validateHandlerUseItems(items: AllUseItems[], mountSite:
|
|
|
16
38
|
* handler.use items come first (defaults), explicit items second (overrides).
|
|
17
39
|
* Returns undefined if both are absent.
|
|
18
40
|
*/
|
|
19
|
-
export declare function mergeHandlerUse(handlerUse: (() => any[]) | undefined, explicitUse: (() => any[]) | undefined, mountSite: string): (() => any[]) | undefined;
|
|
41
|
+
export declare function mergeHandlerUse(handlerUse: (() => any[]) | undefined, explicitUse: (() => any[]) | undefined, mountSite: string | null): (() => any[]) | undefined;
|
|
@@ -89,6 +89,8 @@ export type CacheItem = {
|
|
|
89
89
|
export type TransitionItem = {
|
|
90
90
|
name: string;
|
|
91
91
|
type: "transition";
|
|
92
|
+
/** Wrapper form only: the children it wraps (see hasRoutesInItem). */
|
|
93
|
+
uses?: AllUseItems[];
|
|
92
94
|
};
|
|
93
95
|
/**
|
|
94
96
|
* Typed transition item that carries child routes as phantom type
|
|
@@ -154,7 +156,7 @@ export type RouteUseItem = LayoutItem | ParallelItem | InterceptItem | Middlewar
|
|
|
154
156
|
/** Items that can be used inside a response route (path.json(), etc.) */
|
|
155
157
|
export type ResponseRouteUseItem = MiddlewareItem | CacheItem;
|
|
156
158
|
export type ParallelUseItem = RevalidateItem | LoaderItem | LoadingItem | ErrorBoundaryItem | NotFoundBoundaryItem | TransitionItem;
|
|
157
|
-
export type InterceptUseItem = MiddlewareItem |
|
|
159
|
+
export type InterceptUseItem = MiddlewareItem | LoaderItem | LoadingItem | LayoutItem | RouteItem | TransitionItem;
|
|
158
160
|
export type LoaderUseItem = RevalidateItem | CacheItem;
|
|
159
161
|
/**
|
|
160
162
|
* Allow composition factories in use() callbacks.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type SerializedManifest } from "../debug.js";
|
|
2
2
|
import type { RouteEntry } from "../types";
|
|
3
3
|
/**
|
|
4
|
-
* Build a serialized manifest from
|
|
5
|
-
* Used by the `debugManifest()` method on the router instance.
|
|
4
|
+
* Build a serialized manifest from the eager route entries for debug
|
|
5
|
+
* inspection. Used by the `debugManifest()` method on the router instance.
|
|
6
|
+
* include() children are not expanded (lazy placeholders are skipped).
|
|
6
7
|
*/
|
|
7
8
|
export declare function buildDebugManifest<TEnv = any>(routesEntries: RouteEntry<TEnv>[]): Promise<SerializedManifest>;
|
|
@@ -42,10 +42,30 @@ export interface InvokeOnErrorContext<TEnv = any> {
|
|
|
42
42
|
* @param logPrefix - Prefix for console.error messages (e.g., "Router" or "RSC")
|
|
43
43
|
*/
|
|
44
44
|
export declare function invokeOnError<TEnv = any>(onError: OnErrorCallback<TEnv> | undefined, error: unknown, phase: ErrorPhase, context: InvokeOnErrorContext<TEnv>, logPrefix?: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* First non-undefined `pick(orphan)` over the routeless entries in
|
|
47
|
+
* `entry.layout` and, recursively, in theirs: depth-first in render order
|
|
48
|
+
* (resolveOrphanLayout in segment-resolution/fresh.ts). Since #922 a routeless
|
|
49
|
+
* entry nested in another renders (a layout() after a bare cache() marker, a
|
|
50
|
+
* layout() in a routeless wrapper); a one-level scan missed the boundaries and
|
|
51
|
+
* intercepts it declares (#926).
|
|
52
|
+
*
|
|
53
|
+
* `skip` is the entry an upward walk came from. Only a bare cache() marker is
|
|
54
|
+
* both in its layout's layout[] and in the chain, and its subtree was already
|
|
55
|
+
* scanned at its chain position.
|
|
56
|
+
*/
|
|
57
|
+
export declare function findInOrphans<T>(entry: EntryData, pick: (orphan: EntryData) => T | undefined, skip?: EntryData | null): T | undefined;
|
|
58
|
+
/** `findInOrphans` pick: the orphan when it declares an errorBoundary(). */
|
|
59
|
+
export declare const withErrorBoundary: (entry: EntryData) => EntryData | undefined;
|
|
45
60
|
/**
|
|
46
61
|
* Find the nearest error boundary by walking up the entry chain
|
|
47
62
|
* Also checks sibling layouts (orphan layouts) for error boundaries
|
|
48
63
|
* Returns the first fallback found, or the default error boundary if configured
|
|
64
|
+
*
|
|
65
|
+
* An orphan's parent is null, so from an orphan the walk continues at its
|
|
66
|
+
* orphanOwner (EntryData). Without that step, errors from an intercept declared
|
|
67
|
+
* in a routeless layout, or from that layout's loaders, stopped at the orphan
|
|
68
|
+
* and skipped every ancestor boundary (#898).
|
|
49
69
|
*/
|
|
50
70
|
export declare function findNearestErrorBoundary(entry: EntryData | null, defaultErrorBoundary?: ReactNode | ErrorBoundaryHandler): ReactNode | ErrorBoundaryHandler | null;
|
|
51
71
|
/**
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
* Creates the handler context object passed to route handlers, middleware, and loaders.
|
|
5
5
|
*/
|
|
6
6
|
import type { InternalHandlerContext } from "../types";
|
|
7
|
+
/**
|
|
8
|
+
* `headers` whose mutating methods run `assertWrite(method)` first. Shared by
|
|
9
|
+
* the handler ctx (createHandlerContext) and the middleware ctx
|
|
10
|
+
* (createMiddlewareContext).
|
|
11
|
+
*/
|
|
12
|
+
export declare function guardHeaderWrites(headers: Headers, assertWrite: (method: string | symbol) => void): Headers;
|
|
7
13
|
/**
|
|
8
14
|
* Strip internal _rsc* query params from a URL.
|
|
9
15
|
* Returns a new URL with only user-facing params.
|
|
@@ -82,13 +82,13 @@
|
|
|
82
82
|
* ISOLATION FROM RESPONSE
|
|
83
83
|
* =======================
|
|
84
84
|
*
|
|
85
|
-
* Background revalidation
|
|
86
|
-
*
|
|
85
|
+
* Background revalidation re-renders through rerenderAndCacheRoute (shared
|
|
86
|
+
* with proactive caching in cache-store.ts):
|
|
87
|
+
* - Derived request context with its own handleStore, transition({ when })
|
|
88
|
+
* predicates and no perf metrics (the shared fields are never touched;
|
|
89
|
+
* the foreground is still producing the page)
|
|
87
90
|
* - Fresh handlerContext + loaderPromises (prevents reusing memoized
|
|
88
91
|
* loader results from the foreground pass)
|
|
89
|
-
* - handleStore is saved/restored in try/finally
|
|
90
|
-
*
|
|
91
|
-
* This matches the proactive caching pattern in cache-store.ts.
|
|
92
92
|
*
|
|
93
93
|
*
|
|
94
94
|
* FRESH RESOLUTION (NO REVALIDATION)
|
|
@@ -101,7 +101,48 @@
|
|
|
101
101
|
*/
|
|
102
102
|
import type { ResolvedSegment } from "../../types.js";
|
|
103
103
|
import type { MatchContext, MatchPipelineState } from "../match-context.js";
|
|
104
|
+
import { type RouterContext } from "../router-context.js";
|
|
105
|
+
import type { CacheScope } from "../../cache/cache-scope.js";
|
|
104
106
|
import type { GeneratorMiddleware } from "./cache-lookup.js";
|
|
107
|
+
import { type RequestContext } from "../../server/request-context.js";
|
|
108
|
+
/**
|
|
109
|
+
* Re-render a cached route in the background and write it with
|
|
110
|
+
* cacheScope.cacheRoute: the stale-hit refresh below and proactive caching
|
|
111
|
+
* (cache-store.ts). Returns the number of segments written.
|
|
112
|
+
*
|
|
113
|
+
* A render whose status is not 200 (an error or notFound boundary resolved)
|
|
114
|
+
* is not written and returns 0, as a non-200 MISS is not cached
|
|
115
|
+
* (cache-store.ts): the entry it would replace keeps serving until a later
|
|
116
|
+
* refresh succeeds or it expires. Nothing is held in process; a store's own
|
|
117
|
+
* revalidation marker (CFCacheStore's REVALIDATING) re-arms after
|
|
118
|
+
* MAX_REVALIDATION_INTERVAL, as after a refresh that throws.
|
|
119
|
+
*
|
|
120
|
+
* Runs on a DERIVED request context that owns the per-render state the
|
|
121
|
+
* foreground reads while it is still producing the page (a stale HIT re-runs
|
|
122
|
+
* its loaders; a proactive render starts once the Response exists, while its
|
|
123
|
+
* body streams):
|
|
124
|
+
* - _handleStore: read late (loader pushes and aux-lane tracking in
|
|
125
|
+
* loader-resolution.ts, nested cache restores and captures in
|
|
126
|
+
* cache-scope.ts), so a swap sent live pushes into this render.
|
|
127
|
+
* setupLoaderAccess binds the store at setup, so it runs inside the
|
|
128
|
+
* derived context too.
|
|
129
|
+
* - _transitionWhen: fresh resolution appends transition({ when })
|
|
130
|
+
* predicates; the foreground's gateTransitions reads the array after the
|
|
131
|
+
* match, and a stale HIT (which replays the stored transition) must not
|
|
132
|
+
* evaluate this render's predicates.
|
|
133
|
+
* - _metricsStore: undefined, and the DSL store below has `metrics` unset
|
|
134
|
+
* (track() reads that one), so nothing lands on the foreground's perf
|
|
135
|
+
* timeline. ctx.Store.run closes over ctx.Store, so the derived store
|
|
136
|
+
* needs its own run.
|
|
137
|
+
* - response writes (headers, cookies, status, onResponse callbacks) go to
|
|
138
|
+
* a throwaway context (whose status gates the write, above) and are
|
|
139
|
+
* dropped: a layout above the cache() boundary is outside the header
|
|
140
|
+
* guard and an error boundary sets a status, so they would otherwise
|
|
141
|
+
* reach the live response.
|
|
142
|
+
* runWithRequestContext also re-establishes the request ALS, which a waitUntil
|
|
143
|
+
* task on workerd loses; the DSL store is a different ALS (build context).
|
|
144
|
+
*/
|
|
145
|
+
export declare function rerenderAndCacheRoute<TEnv>(ctx: MatchContext<TEnv>, requestCtx: RequestContext<TEnv>, cacheScope: CacheScope, routerCtx: RouterContext<TEnv>): Promise<number>;
|
|
105
146
|
/**
|
|
106
147
|
* Creates background revalidation middleware
|
|
107
148
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ContextVar } from "../context-var.js";
|
|
2
2
|
import type { DefaultReverseRouteMap, DefaultRouteName, DefaultVars } from "../types/global-namespace.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { GlobalReverseFunction } from "../reverse.js";
|
|
4
4
|
import type { Theme } from "../theme/types.js";
|
|
5
5
|
import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
|
|
6
6
|
import type { RequestScope } from "../types/request-scope.js";
|
|
@@ -51,7 +51,8 @@ export interface MiddlewareContext<TEnv = any, TParams = Record<string, string |
|
|
|
51
51
|
theme?: Theme;
|
|
52
52
|
setTheme?: (theme: Theme) => void;
|
|
53
53
|
setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void;
|
|
54
|
-
|
|
54
|
+
/** Global route names only; see {@link GlobalReverseFunction}. */
|
|
55
|
+
reverse: GlobalReverseFunction<DefaultReverseRouteMap>;
|
|
55
56
|
}
|
|
56
57
|
export type MiddlewareFn<TEnv = any, TParams = Record<string, string | undefined>> = (ctx: MiddlewareContext<TEnv, TParams>, next: () => Promise<Response>) => Response | void | Promise<Response | void>;
|
|
57
58
|
export interface MiddlewareEntry<TEnv = any> {
|
|
@@ -49,7 +49,9 @@ export interface RouterContext<TEnv = any> {
|
|
|
49
49
|
getMetricsStore: () => MetricsStore | undefined;
|
|
50
50
|
createCacheScope: (cacheConfig: any, parent: CacheScope | null) => CacheScope | null;
|
|
51
51
|
findInterceptForRoute: (routeKey: string, parentEntry: EntryData | null, selectorContext: InterceptSelectorContext, isAction: boolean) => InterceptResult | null;
|
|
52
|
-
resolveAllSegmentsWithRevalidation: (entries: EntryData[], routeKey: string, params: Record<string, string>, handlerContext: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: any | undefined, interceptResult: InterceptResult | null, localRouteName: string, pathname: string, stale?: boolean
|
|
52
|
+
resolveAllSegmentsWithRevalidation: (entries: EntryData[], routeKey: string, params: Record<string, string>, handlerContext: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: any | undefined, interceptResult: InterceptResult | null, localRouteName: string, pathname: string, stale?: boolean,
|
|
53
|
+
/** The matched route's full chain when `entries` is part of it (ResolveSegmentOptions.chain). */
|
|
54
|
+
chain?: readonly EntryData[]) => Promise<{
|
|
53
55
|
segments: ResolvedSegment[];
|
|
54
56
|
matchedIds: string[];
|
|
55
57
|
}>;
|
|
@@ -137,6 +137,22 @@ export interface Rango<TEnv = any, TRoutes extends Record<string, unknown> = Rec
|
|
|
137
137
|
* ```
|
|
138
138
|
*/
|
|
139
139
|
readonly routeMap: TRoutes;
|
|
140
|
+
/**
|
|
141
|
+
* Serialize the route manifest for inspection: every route and layout the
|
|
142
|
+
* router's `.routes()` / `urls` mounts register, with shortCodes, parent
|
|
143
|
+
* links, and loader/middleware/error-boundary/parallel/intercept flags.
|
|
144
|
+
*
|
|
145
|
+
* Server-only development aid. It re-evaluates each mount's `urls()` tree.
|
|
146
|
+
* Groups mounted with `include()` are lazy and are not expanded: their
|
|
147
|
+
* routes are absent from the result.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const manifest = await router.debugManifest();
|
|
152
|
+
* console.log(manifest.totalRoutes, Object.keys(manifest.routes));
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
debugManifest(): Promise<SerializedManifest>;
|
|
140
156
|
/**
|
|
141
157
|
* Handle an RSC request.
|
|
142
158
|
*
|
|
@@ -147,7 +163,13 @@ export interface Rango<TEnv = any, TRoutes extends Record<string, unknown> = Rec
|
|
|
147
163
|
* ```tsx
|
|
148
164
|
* import { router } from "./router";
|
|
149
165
|
*
|
|
150
|
-
*
|
|
166
|
+
* // Workers call fetch(request, env, ctx); `{ fetch: router.fetch }` would
|
|
167
|
+
* // drop env and ctx.
|
|
168
|
+
* export default {
|
|
169
|
+
* fetch(request, env, ctx) {
|
|
170
|
+
* return router.fetch(request, { env, ctx });
|
|
171
|
+
* },
|
|
172
|
+
* } satisfies ExportedHandler;
|
|
151
173
|
* ```
|
|
152
174
|
*
|
|
153
175
|
* @example Direct export
|
|
@@ -238,7 +260,7 @@ export interface RangoInternal<TEnv = any, TRoutes extends Record<string, unknow
|
|
|
238
260
|
readonly notFound?: RangoOptions<TEnv>["notFound"];
|
|
239
261
|
/**
|
|
240
262
|
* Resolved theme configuration (null if theme not enabled)
|
|
241
|
-
* Used by NavigationProvider to include ThemeProvider and by
|
|
263
|
+
* Used by NavigationProvider to include ThemeProvider and by `Html.Meta` to render theme script
|
|
242
264
|
*/
|
|
243
265
|
readonly themeConfig: import("../theme/types.js").ResolvedThemeConfig | null;
|
|
244
266
|
/**
|
|
@@ -146,8 +146,10 @@ export interface RangoOptions<TEnv = any> {
|
|
|
146
146
|
*
|
|
147
147
|
* Must be a client component ("use client") that accepts { children }.
|
|
148
148
|
*
|
|
149
|
-
* If not provided, a default document
|
|
150
|
-
* `<
|
|
149
|
+
* If not provided, a default document is used: `Html.Meta` and `Html.Scripts`
|
|
150
|
+
* in `<head>`, `Html.Scripts position="body"` before `{children}` and
|
|
151
|
+
* `Html.ScrollRestoration` after it. Pass your own to set `getKey` or to
|
|
152
|
+
* leave back/forward scrolling to the browser.
|
|
151
153
|
*
|
|
152
154
|
* @example
|
|
153
155
|
* ```typescript
|
|
@@ -181,7 +183,8 @@ export interface RangoOptions<TEnv = any> {
|
|
|
181
183
|
defaultErrorBoundary?: ReactNode | ErrorBoundaryHandler;
|
|
182
184
|
/**
|
|
183
185
|
* Default not-found boundary fallback used when no notFoundBoundary is defined in the route tree
|
|
184
|
-
* If not provided,
|
|
186
|
+
* If not provided, notFound() renders the `notFound` option, else a plain
|
|
187
|
+
* `<h1>Not Found</h1>` (status 404)
|
|
185
188
|
*/
|
|
186
189
|
defaultNotFoundBoundary?: ReactNode | NotFoundBoundaryHandler;
|
|
187
190
|
/**
|
|
@@ -190,7 +193,7 @@ export interface RangoOptions<TEnv = any> {
|
|
|
190
193
|
* This is rendered within your document/app shell with a 404 status code.
|
|
191
194
|
* Use this for a custom 404 page that maintains your app's look and feel.
|
|
192
195
|
*
|
|
193
|
-
* If not provided, a
|
|
196
|
+
* If not provided, a plain `<h1>Not Found</h1>` is rendered.
|
|
194
197
|
*
|
|
195
198
|
* Can be a static ReactNode or a function receiving the pathname.
|
|
196
199
|
*
|
|
@@ -337,7 +340,7 @@ export interface RangoOptions<TEnv = any> {
|
|
|
337
340
|
* When provided, enables:
|
|
338
341
|
* - ctx.theme and ctx.setTheme() in route handlers
|
|
339
342
|
* - useTheme() hook for client components
|
|
340
|
-
* - FOUC prevention via inline script in
|
|
343
|
+
* - FOUC prevention via inline script in `<Html.Meta />`
|
|
341
344
|
* - Automatic ThemeProvider wrapping in NavigationProvider
|
|
342
345
|
*
|
|
343
346
|
* @example
|
|
@@ -27,6 +27,16 @@ export interface ResolveSegmentOptions {
|
|
|
27
27
|
* so error boundaries keep catching at request time.
|
|
28
28
|
*/
|
|
29
29
|
throwOnError?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The matched route's full entry chain. resolveAllSegments defaults it to
|
|
32
|
+
* its `entries`; withCacheLookup passes it when it resolves only the entries
|
|
33
|
+
* above a cache() boundary. An orphan list can hold an entry of the chain: a
|
|
34
|
+
* bare cache() marker sits in its layout's layout[] (it wraps that layout's
|
|
35
|
+
* routes) and is the parent of the routes after it. For those routes it
|
|
36
|
+
* resolves once, as a chain entry, below the cache() header latch (issue
|
|
37
|
+
* #918: resolved twice on a MISS, once and discarded on a HIT).
|
|
38
|
+
*/
|
|
39
|
+
chain?: readonly EntryData[];
|
|
30
40
|
}
|
|
31
41
|
/**
|
|
32
42
|
* Resolve segments from EntryData.
|
|
@@ -16,8 +16,15 @@
|
|
|
16
16
|
* On hit: returns cached data directly, skips loader execution.
|
|
17
17
|
* On stale hit (SWR): returns stale data, schedules background revalidation.
|
|
18
18
|
* On miss: executes loader, schedules non-blocking cache write.
|
|
19
|
+
*
|
|
20
|
+
* Handle pushes (`ctx.use(Handle)(...)` in the loader body) are a side effect
|
|
21
|
+
* the HIT must reproduce: the MISS records the pushes of the body and of the
|
|
22
|
+
* loaders it awaits via ctx.use into the entry's `handles` blob (the
|
|
23
|
+
* "use cache" capture/encode), and every HIT — stale included — replays
|
|
24
|
+
* them, each loader's pushes at most once per request (a dependency another
|
|
25
|
+
* reader already ran keeps its live pushes). See replayLoaderHandles.
|
|
19
26
|
*/
|
|
20
|
-
import type
|
|
27
|
+
import { type LoaderEntry } from "../../server/context.js";
|
|
21
28
|
import type { HandlerContext } from "../../types.js";
|
|
22
29
|
/**
|
|
23
30
|
* Resolve loader data with optional caching.
|
|
@@ -29,5 +36,34 @@ import type { HandlerContext } from "../../types.js";
|
|
|
29
36
|
* (observePhase; see instrument.ts). A cache HIT returns without calling ctx.use,
|
|
30
37
|
* so it emits no loader phase (the loader did not execute; the hit is only a
|
|
31
38
|
* LoaderCache debug log).
|
|
39
|
+
*
|
|
40
|
+
* PPR loader lane rule — the canonical source statement; other sites point
|
|
41
|
+
* here (consumer docs: skills/ppr/SKILL.md "The loader lane rule";
|
|
42
|
+
* docs/design/loader-container-bake.md). This is the single funnel every
|
|
43
|
+
* loader segment path routes through (fresh resolveLoaders, cache-hit
|
|
44
|
+
* resolveLoadersOnly, revalidation resolveLoadersOnlyWithRevalidation, and
|
|
45
|
+
* intercept loaders in intercept-resolution.ts, which pass no bake key and
|
|
46
|
+
* never run under a shell capture), so the lane is decided here, per LOADER,
|
|
47
|
+
* never by the entry's loading():
|
|
48
|
+
*
|
|
49
|
+
* - BAKE lane: `loader(Def, { ssr: false })` (awaitBeforeFlush) with a
|
|
50
|
+
* `bakeSegmentKey` from the caller. The loader EXECUTES at capture (the
|
|
51
|
+
* flag's "data in the HTML before first flush" maps to the frozen prelude)
|
|
52
|
+
* and its settled non-promise data bakes into the shell. Promises nested in
|
|
53
|
+
* plain objects/arrays are masked (mask-nested.ts) and stay live holes at
|
|
54
|
+
* the consumer's own Suspense — per-request material must be promise-shaped
|
|
55
|
+
* (the #692 cross-session scar). The masked container registers on
|
|
56
|
+
* `_shellCaptureLoaderRecords`: it holds the capture gate (bounded by
|
|
57
|
+
* `ppr.captureTimeout`) and pins into the snapshot's loader family, and on a
|
|
58
|
+
* HIT the recorded container is overlaid onto the fresh run (below) so the
|
|
59
|
+
* payload matches the frozen prelude byte-for-byte. cookies()/headers() in
|
|
60
|
+
* its body (nested promise bodies included) trip the capture guard.
|
|
61
|
+
* - LIVE lane: every other loader, whatever its entry's loading(). Never
|
|
62
|
+
* executes at capture: the slot gets a never-resolving promise
|
|
63
|
+
* (loader-mask.ts) and postpones at the reader's boundary — loading() or an
|
|
64
|
+
* inline Suspense — then streams fresh per request. A masked read with NO
|
|
65
|
+
* boundary above it root-postpones and the <body> sanity gate refuses the
|
|
66
|
+
* shell (eternal-MISS warning). A route whose loaders are ALL `ssr: false`
|
|
67
|
+
* needs no loading(): nothing masks.
|
|
32
68
|
*/
|
|
33
69
|
export declare function resolveLoaderData<TEnv>(loaderEntry: LoaderEntry, ctx: HandlerContext<any, TEnv>, pathname: string, bakeSegmentKey?: string | null): Promise<any>;
|
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
* PPR shell-capture loader masking.
|
|
3
3
|
*
|
|
4
4
|
* During a shell CAPTURE re-render (Axis 2, see docs/design/ppr-shell-resume.md)
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* a
|
|
8
|
-
*
|
|
9
|
-
* shell (prelude) captures only the fallback; the resumed serve pass runs the
|
|
10
|
-
* loaders fresh through the unchanged execution path and streams their output
|
|
11
|
-
* into the holes.
|
|
5
|
+
* live-lane loaders (lane rule: see resolveLoaderData, loader-cache.ts) must
|
|
6
|
+
* NOT execute; their value slot gets a never-resolving promise so the
|
|
7
|
+
* consuming Suspense subtree postpones as a hole, and the serve pass runs them
|
|
8
|
+
* fresh into it.
|
|
12
9
|
*
|
|
13
10
|
* Capture mode is signalled by `requestCtx._shellCaptureRun`, set to true ONLY on
|
|
14
11
|
* the derived request context of the background capture task (shell-capture.ts) —
|
|
@@ -28,17 +25,10 @@ import { type RequestContext } from "../../server/request-context.js";
|
|
|
28
25
|
export declare function isShellCaptureActive(reqCtx?: RequestContext<any> | undefined): boolean;
|
|
29
26
|
export { createMaskedLoaderPromise } from "./mask-nested.js";
|
|
30
27
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* the frozen prelude — while every other loader is LIVE (masked at capture,
|
|
37
|
-
* fresh on every serve), postponing at loading() or an inline Suspense.
|
|
38
|
-
* This helper still gates which entries pass a bake segment key for the
|
|
39
|
-
* legacy loading()-less shape and the HIT-tail seed overlay.
|
|
40
|
-
*
|
|
41
|
-
* Mirrors segment-system's isRenderableLoading so the mask decision and the
|
|
42
|
-
* tree's boundary placement can never disagree.
|
|
28
|
+
* True when the entry's loading() is renderable (mirrors segment-system's
|
|
29
|
+
* isRenderableLoading). Not the lane decision (lane rule: see
|
|
30
|
+
* resolveLoaderData, loader-cache.ts): callers only use it to decide whether
|
|
31
|
+
* an unflagged loader's segment key rides as the bake/seed key, which is inert
|
|
32
|
+
* at capture.
|
|
43
33
|
*/
|
|
44
34
|
export declare function entryLoadingMasksLoaders(loading: unknown): boolean;
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Loader-family capture snapshot: elide + overlay for bake-lane loader
|
|
3
3
|
* containers (docs/design/loader-container-bake.md).
|
|
4
4
|
*
|
|
5
|
-
* A loader
|
|
6
|
-
* capture; its settled container bakes into the prelude
|
|
7
|
-
*
|
|
5
|
+
* A bake-lane loader (lane rule: see resolveLoaderData, loader-cache.ts)
|
|
6
|
+
* executes during shell capture; its settled container bakes into the prelude
|
|
7
|
+
* while nested promises postpone as holes. To keep a HIT's fresh
|
|
8
8
|
* payload byte-identical to that frozen prelude, the capture pins the container
|
|
9
9
|
* in the shell snapshot:
|
|
10
10
|
*
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Capture-side nested-thenable masking — the mechanism behind "nested-promise
|
|
3
3
|
* shape is the liveness declaration" for BOTH bake-lane loader containers
|
|
4
|
-
* (loader-cache.ts) and pushed handle containers (
|
|
5
|
-
*
|
|
4
|
+
* (loader-cache.ts) and pushed handle containers (the capture handle store's
|
|
5
|
+
* push wrap in rsc/shell-capture.ts).
|
|
6
6
|
*
|
|
7
|
-
* Deliberately a LEAF module:
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Deliberately a LEAF module: loader-mask (the other natural home) imports
|
|
8
|
+
* request-context, so any funnel importing the mask from there inherits that
|
|
9
|
+
* graph. This module imports only is-thenable.
|
|
10
10
|
*/
|
|
11
11
|
/**
|
|
12
12
|
* A promise that never settles — the masked stand-in for a per-request value
|
|
@@ -21,8 +21,8 @@ export declare function createMaskedLoaderPromise<T = unknown>(): Promise<T>;
|
|
|
21
21
|
* Deep-copy a container with every NESTED thenable replaced by a masked
|
|
22
22
|
* (never-resolving) promise. Applied during shell capture to (a) bake-lane
|
|
23
23
|
* loader containers (loader-cache.ts) and (b) pushed handle containers
|
|
24
|
-
* (
|
|
25
|
-
* per-request data by promise SHAPE.
|
|
24
|
+
* (shell-capture.ts capture store push wrap) — the two rango-owned funnels
|
|
25
|
+
* where consumers declare per-request data by promise SHAPE.
|
|
26
26
|
*
|
|
27
27
|
* Why: a nested promise that happened to SETTLE before the capture's quiet
|
|
28
28
|
* window closed used to bake its value into the SHARED shell (and, for
|
|
@@ -66,7 +66,9 @@ export declare function resolveEntryHandlerWithRevalidation<TEnv>(entry: Exclude
|
|
|
66
66
|
*/
|
|
67
67
|
export declare function resolveSegmentWithRevalidation<TEnv>(entry: Exclude<EntryData, {
|
|
68
68
|
type: "parallel";
|
|
69
|
-
}>, routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean
|
|
69
|
+
}>, routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentIds: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, deps: SegmentResolutionDeps<TEnv>, actionContext?: ActionContext, stale?: boolean,
|
|
70
|
+
/** The matched route's full chain; see ResolveSegmentOptions.chain (fresh.ts). */
|
|
71
|
+
chain?: readonly EntryData[]): Promise<SegmentRevalidationResult>;
|
|
70
72
|
/**
|
|
71
73
|
* Resolve orphan layout with revalidation.
|
|
72
74
|
*/
|
|
@@ -79,7 +81,9 @@ parentRouteEntry?: EntryData): Promise<SegmentRevalidationResult>;
|
|
|
79
81
|
export declare function resolveAllSegmentsWithRevalidation<TEnv>(entries: EntryData[], routeKey: string, params: Record<string, string>, context: HandlerContext<any, TEnv>, clientSegmentSet: Set<string>, prevParams: Record<string, string>, request: Request, prevUrl: URL, nextUrl: URL, actionContext: ActionContext | undefined, interceptResult: {
|
|
80
82
|
intercept: any;
|
|
81
83
|
entry: EntryData;
|
|
82
|
-
} | null, localRouteName: string, pathname: string, deps: SegmentResolutionDeps<TEnv>, stale?: boolean
|
|
84
|
+
} | null, localRouteName: string, pathname: string, deps: SegmentResolutionDeps<TEnv>, stale?: boolean,
|
|
85
|
+
/** The matched route's full chain; see ResolveSegmentOptions.chain (fresh.ts). */
|
|
86
|
+
chain?: readonly EntryData[]): Promise<{
|
|
83
87
|
segments: ResolvedSegment[];
|
|
84
88
|
matchedIds: string[];
|
|
85
89
|
}>;
|
|
@@ -27,7 +27,7 @@ export interface SegmentWrappers<TEnv = any> {
|
|
|
27
27
|
} | undefined, interceptResult: {
|
|
28
28
|
intercept: InterceptEntry;
|
|
29
29
|
entry: EntryData;
|
|
30
|
-
} | null, localRouteName: string, pathname: string) => Promise<{
|
|
30
|
+
} | null, localRouteName: string, pathname: string, stale?: boolean, chain?: readonly EntryData[]) => Promise<{
|
|
31
31
|
segments: ResolvedSegment[];
|
|
32
32
|
matchedIds: string[];
|
|
33
33
|
}>;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* dispatch, route middleware execution, and response caching with SWR.
|
|
7
7
|
*/
|
|
8
8
|
import type { MiddlewareFn } from "../router/middleware.js";
|
|
9
|
-
import type
|
|
9
|
+
import { type EntryData } from "../server/context.js";
|
|
10
10
|
import type { HandlerContext } from "./handler-context.js";
|
|
11
11
|
export interface ResponseRouteMatch {
|
|
12
12
|
responseType: string;
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* RSC Rendering Handler (Navigation)
|
|
3
3
|
*
|
|
4
4
|
* Handles RSC rendering for both partial (client-side navigation) and full
|
|
5
|
-
* (initial page load) requests.
|
|
6
|
-
* static generation.
|
|
5
|
+
* (initial page load) requests.
|
|
7
6
|
*/
|
|
8
7
|
import { getRequestContext } from "../server/request-context.js";
|
|
9
8
|
import type { HandlerContext } from "./handler-context.js";
|
|
@@ -42,3 +42,11 @@ export declare const SHELL_CAPTURE_MAX_WAIT_MS = 15000;
|
|
|
42
42
|
* check on the stampede guard, keyed off the same constant.
|
|
43
43
|
*/
|
|
44
44
|
export declare const SHELL_CAPTURE_TASK_HARD_CAP_MS = 25000;
|
|
45
|
+
/**
|
|
46
|
+
* Shared PPR loader-lane hint, appended to every capture warning or error
|
|
47
|
+
* whose fix depends on the lane (shell-capture.ts warnings, the cookie-store.ts
|
|
48
|
+
* capture guard). Lives in this import-free leaf so cookie-store.ts can import
|
|
49
|
+
* it without pulling the capture orchestration module. Source anchor for the
|
|
50
|
+
* rule: resolveLoaderData (router/segment-resolution/loader-cache.ts).
|
|
51
|
+
*/
|
|
52
|
+
export declare const PPR_LANE_HINT: string;
|