@rangojs/router 0.18.0 → 0.19.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/dist/types/browser/event-controller.d.ts +3 -3
- package/dist/types/browser/history-state.d.ts +2 -0
- package/dist/types/browser/navigation-transaction.d.ts +20 -2
- package/dist/types/browser/partial-update.d.ts +16 -1
- package/dist/types/browser/prefetch/cache.d.ts +6 -6
- package/dist/types/browser/react/Link.d.ts +19 -9
- package/dist/types/browser/react/context.d.ts +2 -2
- package/dist/types/browser/react/location-state-shared.d.ts +95 -56
- package/dist/types/browser/react/location-state.d.ts +1 -1
- package/dist/types/browser/transition-when.d.ts +80 -0
- package/dist/types/browser/types.d.ts +104 -9
- package/dist/types/build/generate-manifest.d.ts +8 -0
- package/dist/types/cache/background-task.d.ts +24 -2
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/cache-key-utils.d.ts +44 -13
- package/dist/types/cache/cache-policy.d.ts +1 -1
- package/dist/types/cache/cache-runtime.d.ts +7 -0
- package/dist/types/cache/cache-scope.d.ts +117 -35
- package/dist/types/cache/cache-tag.d.ts +24 -4
- package/dist/types/cache/cf/cf-cache-store.d.ts +55 -44
- package/dist/types/cache/cf/cf-shell-frame.d.ts +1 -1
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +0 -15
- package/dist/types/cache/document-cache.d.ts +10 -0
- package/dist/types/cache/handle-snapshot.d.ts +40 -8
- package/dist/types/cache/invalidation-order.d.ts +23 -0
- package/dist/types/cache/request-tag-mask.d.ts +54 -0
- package/dist/types/cache/shell-snapshot.d.ts +88 -141
- package/dist/types/cache/tag-invalidation.d.ts +38 -14
- package/dist/types/cache/types.d.ts +68 -61
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +23 -16
- package/dist/types/client-urls/navigation.d.ts +28 -2
- package/dist/types/client-urls/server-projection.d.ts +5 -2
- package/dist/types/client-urls/types.d.ts +5 -5
- package/dist/types/client.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/route-definition/helpers-types.d.ts +11 -11
- package/dist/types/route-name.d.ts +7 -0
- package/dist/types/router/error-handling.d.ts +1 -1
- package/dist/types/router/intercept-resolution.d.ts +2 -0
- package/dist/types/router/match-context.d.ts +5 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
- package/dist/types/router/router-options.d.ts +4 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +18 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +14 -40
- package/dist/types/router/segment-resolution/mask-nested.d.ts +11 -3
- package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
- package/dist/types/router/transition-when.d.ts +24 -10
- package/dist/types/rsc/attach-transition-when.d.ts +18 -0
- package/dist/types/rsc/full-payload.d.ts +14 -7
- package/dist/types/rsc/response-cache-serve.d.ts +15 -12
- package/dist/types/rsc/shell-build-manifest.d.ts +4 -3
- package/dist/types/rsc/shell-capture-constants.d.ts +77 -20
- package/dist/types/rsc/shell-capture.d.ts +78 -81
- package/dist/types/rsc/shell-serve.d.ts +19 -48
- package/dist/types/rsc/types.d.ts +2 -0
- package/dist/types/segment-system.d.ts +7 -0
- package/dist/types/server/context.d.ts +89 -61
- package/dist/types/server/cookie-store.d.ts +30 -18
- package/dist/types/server/handle-store.d.ts +52 -1
- package/dist/types/server/request-context.d.ts +66 -45
- package/dist/types/server/request-headers.d.ts +44 -0
- package/dist/types/server.d.ts +1 -0
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/index.d.ts +3 -2
- package/dist/types/testing/internal/action-id.d.ts +7 -0
- package/dist/types/testing/location-state-key.d.ts +24 -0
- package/dist/types/testing/render-route.d.ts +17 -1
- package/dist/types/testing/run-transition-when.d.ts +44 -69
- package/dist/types/testing/serve-shell-request.d.ts +7 -6
- package/dist/types/testing/shell-status.d.ts +34 -22
- package/dist/types/transition-when-ref.d.ts +79 -0
- package/dist/types/types/cache-types.d.ts +15 -3
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/segments.d.ts +86 -71
- package/dist/types/urls/path-helper-types.d.ts +3 -4
- package/dist/types/urls/pattern-types.d.ts +3 -4
- package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
- package/dist/vite/index.js +960 -97
- package/package.json +1 -1
- package/skills/cache-guide/SKILL.md +76 -49
- package/skills/caching/SKILL.md +167 -69
- package/skills/client-urls/SKILL.md +1 -1
- package/skills/comparison/references/framework-comparison.md +8 -5
- package/skills/document-cache/SKILL.md +24 -0
- package/skills/hooks/SKILL.md +3 -1
- package/skills/hooks/navigation.md +23 -2
- package/skills/hooks/state.md +98 -6
- package/skills/intercept/SKILL.md +29 -12
- package/skills/loader/SKILL.md +52 -21
- package/skills/middleware/SKILL.md +18 -0
- package/skills/migrate-nextjs/SKILL.md +3 -3
- package/skills/observability/SKILL.md +6 -5
- package/skills/parallel/SKILL.md +1 -1
- package/skills/ppr/SKILL.md +129 -77
- package/skills/prerender/SKILL.md +3 -3
- package/skills/rango/SKILL.md +25 -6
- package/skills/route/SKILL.md +2 -0
- package/skills/testing/SKILL.md +27 -25
- package/skills/testing/cache-prerender.md +9 -9
- package/skills/testing/client-components.md +45 -3
- package/skills/testing/loader.md +3 -2
- package/skills/testing/middleware.md +1 -0
- package/skills/testing/predicates.md +49 -49
- package/skills/testing/render-handler.md +1 -0
- package/skills/testing/serve-shell-request.md +14 -0
- package/skills/testing/server-actions.md +9 -3
- package/skills/theme/SKILL.md +8 -4
- package/skills/typesafety/env-and-bindings.md +8 -0
- package/skills/use-cache/SKILL.md +64 -19
- package/skills/view-transitions/SKILL.md +150 -29
- package/src/__augment-tests__/augmented.check.ts +23 -0
- package/src/browser/event-controller.ts +4 -4
- package/src/browser/history-state.ts +52 -1
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +77 -18
- package/src/browser/navigation-client.ts +4 -3
- package/src/browser/navigation-store.ts +43 -1
- package/src/browser/navigation-transaction.ts +31 -11
- package/src/browser/partial-update.ts +146 -35
- package/src/browser/prefetch/cache.ts +6 -6
- package/src/browser/prefetch/fetch.ts +2 -2
- package/src/browser/react/Link.tsx +38 -33
- package/src/browser/react/NavigationProvider.tsx +2 -2
- package/src/browser/react/context.ts +2 -2
- package/src/browser/react/location-state-shared.ts +241 -49
- package/src/browser/react/location-state.ts +5 -2
- package/src/browser/rsc-router.tsx +4 -0
- package/src/browser/server-action-bridge.ts +84 -15
- package/src/browser/transition-when.ts +205 -0
- package/src/browser/types.ts +124 -10
- package/src/build/generate-manifest.ts +77 -1
- package/src/cache/background-task.ts +55 -2
- package/src/cache/cache-exec-scope.ts +48 -1
- package/src/cache/cache-key-utils.ts +56 -16
- package/src/cache/cache-policy.ts +9 -4
- package/src/cache/cache-runtime.ts +197 -144
- package/src/cache/cache-scope.ts +304 -112
- package/src/cache/cache-tag.ts +105 -13
- package/src/cache/cf/cf-cache-store.ts +152 -76
- package/src/cache/cf/cf-shell-frame.ts +2 -2
- package/src/cache/cf/cf-tag-marker-memo.ts +11 -100
- package/src/cache/document-cache.ts +53 -7
- package/src/cache/handle-snapshot.ts +52 -9
- package/src/cache/invalidation-order.ts +84 -0
- package/src/cache/request-tag-mask.ts +147 -0
- package/src/cache/shell-snapshot.ts +130 -348
- package/src/cache/tag-invalidation.ts +57 -51
- package/src/cache/types.ts +71 -67
- package/src/cache/vercel/vercel-cache-store.ts +61 -58
- package/src/client-urls/client-root.tsx +8 -4
- package/src/client-urls/client-urls.ts +8 -6
- package/src/client-urls/navigation.ts +55 -4
- package/src/client-urls/server-projection.ts +31 -10
- package/src/client-urls/types.ts +12 -5
- package/src/client.tsx +2 -0
- package/src/host/cookie-handler.ts +2 -1
- package/src/index.rsc.ts +3 -0
- package/src/index.ts +3 -0
- package/src/loader-redirect.tsx +7 -3
- package/src/prerender/build-shell-capture.ts +155 -146
- package/src/route-definition/dsl-helpers.ts +2 -0
- package/src/route-definition/helpers-types.ts +11 -11
- package/src/route-name.ts +12 -0
- package/src/router/content-negotiation.ts +4 -1
- package/src/router/error-handling.ts +5 -2
- package/src/router/handler-context.ts +10 -7
- package/src/router/intercept-resolution.ts +11 -1
- package/src/router/loader-resolution.ts +28 -3
- package/src/router/logging.ts +5 -3
- package/src/router/match-api.ts +62 -34
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +9 -29
- package/src/router/match-middleware/background-revalidation.ts +3 -5
- package/src/router/match-middleware/cache-lookup.ts +35 -19
- package/src/router/match-middleware/cache-store.ts +15 -9
- package/src/router/match-result.ts +1 -0
- package/src/router/middleware.ts +2 -5
- package/src/router/navigation-snapshot.ts +6 -5
- package/src/router/prerender-match.ts +4 -0
- package/src/router/request-classification.ts +7 -4
- package/src/router/router-options.ts +4 -1
- package/src/router/segment-resolution/fresh.ts +0 -4
- package/src/router/segment-resolution/loader-cache.ts +150 -25
- package/src/router/segment-resolution/loader-mask.ts +3 -4
- package/src/router/segment-resolution/loader-snapshot.ts +15 -78
- package/src/router/segment-resolution/mask-nested.ts +47 -22
- package/src/router/segment-resolution/revalidation.ts +0 -3
- package/src/router/segment-resolution/view-transition-default.ts +6 -21
- package/src/router/telemetry.ts +6 -3
- package/src/router/transition-when.ts +34 -52
- package/src/router.ts +2 -1
- package/src/rsc/attach-transition-when.ts +47 -0
- package/src/rsc/full-payload.ts +30 -10
- package/src/rsc/handler.ts +12 -10
- package/src/rsc/loader-fetch.ts +2 -1
- package/src/rsc/manifest-init.ts +4 -0
- package/src/rsc/origin-guard.ts +8 -5
- package/src/rsc/progressive-enhancement.ts +7 -30
- package/src/rsc/response-cache-serve.ts +68 -80
- package/src/rsc/response-route-handler.ts +2 -2
- package/src/rsc/rsc-rendering.ts +206 -252
- package/src/rsc/server-action.ts +8 -20
- package/src/rsc/shell-build-manifest.ts +22 -20
- package/src/rsc/shell-capture-constants.ts +136 -20
- package/src/rsc/shell-capture.ts +352 -589
- package/src/rsc/shell-serve.ts +73 -109
- package/src/rsc/ssr-setup.ts +3 -2
- package/src/rsc/types.ts +2 -0
- package/src/segment-system.tsx +40 -7
- package/src/server/context.ts +189 -124
- package/src/server/cookie-store.ts +153 -127
- package/src/server/handle-store.ts +245 -27
- package/src/server/request-context.ts +123 -84
- package/src/server/request-headers.ts +134 -0
- package/src/server.ts +4 -0
- package/src/testing/dispatch.ts +4 -7
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/internal/action-id.ts +25 -0
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/location-state-key.ts +45 -0
- package/src/testing/render-handler.ts +1 -1
- package/src/testing/render-route.tsx +109 -16
- package/src/testing/run-client-revalidate.ts +3 -19
- package/src/testing/run-loader.ts +5 -1
- package/src/testing/run-transition-when.ts +109 -172
- package/src/testing/serve-shell-request.ts +10 -7
- package/src/testing/shell-status.ts +60 -56
- package/src/transition-when-ref.ts +220 -0
- package/src/types/cache-types.ts +15 -3
- package/src/types/index.ts +3 -0
- package/src/types/segments.ts +94 -91
- package/src/urls/path-helper-types.ts +3 -4
- package/src/urls/pattern-types.ts +3 -4
- package/src/vite/discovery/discover-routers.ts +3 -0
- package/src/vite/discovery/shell-prerender-phase.ts +0 -2
- package/src/vite/discovery/virtual-module-codegen.ts +16 -6
- package/src/vite/plugins/transition-when-hoist.ts +1064 -0
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +75 -5
- package/dist/types/rsc/transition-gate.d.ts +0 -23
- package/src/rsc/transition-gate.ts +0 -86
package/src/vite/rango.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
exposeRouterId,
|
|
11
11
|
} from "./plugins/expose-internal-ids.js";
|
|
12
12
|
import { useCacheTransform } from "./plugins/use-cache-transform.js";
|
|
13
|
+
import { transitionWhenHoistPlugin } from "./plugins/transition-when-hoist.js";
|
|
13
14
|
import { clientRefDedup } from "./plugins/client-ref-dedup.js";
|
|
14
15
|
import { VIRTUAL_IDS } from "./plugins/virtual-entries.js";
|
|
15
16
|
import {
|
|
@@ -563,6 +564,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
563
564
|
});
|
|
564
565
|
|
|
565
566
|
plugins.push(createLoaderDirectiveGuardPlugin());
|
|
567
|
+
plugins.push(transitionWhenHoistPlugin());
|
|
566
568
|
plugins.push(createLoaderScanStubPlugin());
|
|
567
569
|
plugins.push(exposeActionId());
|
|
568
570
|
plugins.push(
|
|
@@ -65,6 +65,8 @@ import {
|
|
|
65
65
|
} from "./discovery/client-urls-projection.js";
|
|
66
66
|
import { runShellPrerenderPhase } from "./discovery/shell-prerender-phase.js";
|
|
67
67
|
import { describeDiscoveryFailure } from "./discovery/discovery-errors.js";
|
|
68
|
+
import { findTransitionWhenError } from "../transition-when-ref.js";
|
|
69
|
+
import { transitionWhenHoistPlugin } from "./plugins/transition-when-hoist.js";
|
|
68
70
|
import {
|
|
69
71
|
createDevPrerenderCache,
|
|
70
72
|
devPrerenderCacheKey,
|
|
@@ -286,6 +288,9 @@ export async function createTempRscServer(
|
|
|
286
288
|
: []),
|
|
287
289
|
createVirtualStubPlugin(),
|
|
288
290
|
createCloudflareProtocolStubPlugin(),
|
|
291
|
+
// Inline transition({ when }) literals become client references here
|
|
292
|
+
// too, or discovery would see (and reject) the plain function.
|
|
293
|
+
transitionWhenHoistPlugin(),
|
|
289
294
|
// Dev prerender must use dev-mode IDs (path-based) to match the workerd
|
|
290
295
|
// runtime. forceBuild produces hashed IDs for production bundle consistency.
|
|
291
296
|
exposeInternalIds(options.forceBuild ? { forceBuild: true } : undefined),
|
|
@@ -443,6 +448,37 @@ export function createRouterDiscoveryPlugin(
|
|
|
443
448
|
let viteCommand: "serve" | "build" = "build";
|
|
444
449
|
let viteMode = "production";
|
|
445
450
|
|
|
451
|
+
// Dev: an invalid transition({ when }) is a definition error the user must
|
|
452
|
+
// see in the browser too, as the Vite error overlay. The overlay does not
|
|
453
|
+
// survive on its own: a reload clears it, and plugin-rsc closes every
|
|
454
|
+
// overlay on each "rsc:update" (the edit's own, the gen-file write's), each
|
|
455
|
+
// followed by the client's RSC refetch. So until a discovery succeeds the
|
|
456
|
+
// pending error is re-sent to every client that connects and after every
|
|
457
|
+
// request the dev server answers (configureServer).
|
|
458
|
+
let transitionWhenOverlay: {
|
|
459
|
+
message: string;
|
|
460
|
+
stack: string;
|
|
461
|
+
plugin: string;
|
|
462
|
+
} | null = null;
|
|
463
|
+
const sendTransitionWhenOverlay = (): void => {
|
|
464
|
+
if (!transitionWhenOverlay) return;
|
|
465
|
+
(s.devServer?.environments as any)?.client?.hot?.send({
|
|
466
|
+
type: "error",
|
|
467
|
+
err: transitionWhenOverlay,
|
|
468
|
+
});
|
|
469
|
+
};
|
|
470
|
+
const showTransitionWhenError = (err: unknown): Error | undefined => {
|
|
471
|
+
const whenError = findTransitionWhenError(err);
|
|
472
|
+
if (!whenError) return undefined;
|
|
473
|
+
transitionWhenOverlay = {
|
|
474
|
+
message: whenError.message,
|
|
475
|
+
stack: whenError.stack ?? "",
|
|
476
|
+
plugin: "@rangojs/router",
|
|
477
|
+
};
|
|
478
|
+
sendTransitionWhenOverlay();
|
|
479
|
+
return whenError;
|
|
480
|
+
};
|
|
481
|
+
|
|
446
482
|
return {
|
|
447
483
|
name: "@rangojs/router:discovery",
|
|
448
484
|
|
|
@@ -525,6 +561,32 @@ export function createRouterDiscoveryPlugin(
|
|
|
525
561
|
if ((globalThis as any).__rscRouterDiscoveryActive) return;
|
|
526
562
|
s.devServer = server;
|
|
527
563
|
|
|
564
|
+
(server.environments as any)?.client?.hot?.on?.(
|
|
565
|
+
"vite:client:connect",
|
|
566
|
+
(_payload: unknown, client: any) => {
|
|
567
|
+
if (transitionWhenOverlay) {
|
|
568
|
+
client?.send?.({ type: "error", err: transitionWhenOverlay });
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
);
|
|
572
|
+
// The http server's "request" event, not a middleware: plugin-rsc
|
|
573
|
+
// answers page and RSC requests before a middleware added here runs.
|
|
574
|
+
let overlayResendQueued = false;
|
|
575
|
+
server.httpServer?.on("request", (req, res) => {
|
|
576
|
+
// Documents and RSC fetches only (the refetch that follows each
|
|
577
|
+
// "rsc:update"), one send per burst.
|
|
578
|
+
const isPage =
|
|
579
|
+
req.url?.includes("_rsc") === true ||
|
|
580
|
+
req.headers.accept?.includes("text/html") === true;
|
|
581
|
+
if (transitionWhenOverlay && isPage && !overlayResendQueued) {
|
|
582
|
+
overlayResendQueued = true;
|
|
583
|
+
res.once("close", () => {
|
|
584
|
+
overlayResendQueued = false;
|
|
585
|
+
sendTransitionWhenOverlay();
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
|
|
528
590
|
let workerReadyEpoch: number | undefined;
|
|
529
591
|
const publishDevDiscoveryReady = (epoch: number) => {
|
|
530
592
|
if (epoch <= (workerReadyEpoch ?? -1)) return;
|
|
@@ -870,6 +932,7 @@ export function createRouterDiscoveryPlugin(
|
|
|
870
932
|
} else {
|
|
871
933
|
console.error(report.message);
|
|
872
934
|
}
|
|
935
|
+
showTransitionWhenError(err);
|
|
873
936
|
};
|
|
874
937
|
|
|
875
938
|
const discover = async () => {
|
|
@@ -1483,9 +1546,7 @@ export function createRouterDiscoveryPlugin(
|
|
|
1483
1546
|
const body = JSON.stringify({
|
|
1484
1547
|
entry: result.entry,
|
|
1485
1548
|
ttl,
|
|
1486
|
-
swr,
|
|
1487
1549
|
tags: result.tags,
|
|
1488
|
-
routeName,
|
|
1489
1550
|
});
|
|
1490
1551
|
devPrerenderCache.set(routerInstance, cacheKey, body);
|
|
1491
1552
|
res.setHeader("content-type", "application/json");
|
|
@@ -1629,6 +1690,7 @@ export function createRouterDiscoveryPlugin(
|
|
|
1629
1690
|
);
|
|
1630
1691
|
s.lastDiscoveryError = null;
|
|
1631
1692
|
}
|
|
1693
|
+
transitionWhenOverlay = null;
|
|
1632
1694
|
// Cloudflare dev: on a successful cycle drop the workerd runner's
|
|
1633
1695
|
// cached worker-entry chain so the next request re-evaluates
|
|
1634
1696
|
// createRouter() with the new routes. Fired here in the work path
|
|
@@ -1656,9 +1718,17 @@ export function createRouterDiscoveryPlugin(
|
|
|
1656
1718
|
message: err?.message ?? String(err),
|
|
1657
1719
|
at: Date.now(),
|
|
1658
1720
|
};
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1721
|
+
// An invalid transition({ when }) is a definition error the
|
|
1722
|
+
// user must see: terminal error plus the browser's Vite overlay,
|
|
1723
|
+
// not a warning while the last-good route tree keeps serving.
|
|
1724
|
+
const whenError = showTransitionWhenError(err);
|
|
1725
|
+
if (whenError) {
|
|
1726
|
+
console.error(whenError.message);
|
|
1727
|
+
} else {
|
|
1728
|
+
console.warn(
|
|
1729
|
+
`[rango] Runtime re-discovery failed: ${err.message}`,
|
|
1730
|
+
);
|
|
1731
|
+
}
|
|
1662
1732
|
debugDiscovery?.(
|
|
1663
1733
|
"hmr: lastDiscoveryError set (%s) — manifest preserved at last-good; recovery mode active (any in-scan source change will trigger rediscovery)",
|
|
1664
1734
|
err?.message,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { MatchResult } from "../types.js";
|
|
2
|
-
import type { getRequestContext } from "../server/request-context.js";
|
|
3
|
-
import type { OnErrorCallback } from "../types/error-types.js";
|
|
4
|
-
/**
|
|
5
|
-
* Apply transition({ when }) gates to a payload's segments.
|
|
6
|
-
*
|
|
7
|
-
* PPR predicates were evaluated from the manifest before cache lookup and route
|
|
8
|
-
* handlers; their request-specific decisions are projected onto a copy so they
|
|
9
|
-
* never mutate reusable cache/prerender/shell records. Ordinary-route predicates
|
|
10
|
-
* were collected during fresh resolution and are evaluated here after handlers.
|
|
11
|
-
* Both paths drop the segment transition when the predicate does not hold.
|
|
12
|
-
*
|
|
13
|
-
* Mutating the segments here is safe: the segment cache stores a serialized copy
|
|
14
|
-
* (segment-codec), written during match() BEFORE this gate runs, so dropping a
|
|
15
|
-
* transition never corrupts a cache entry. On an ordinary route, a cache hit
|
|
16
|
-
* skips resolution, collects no predicate, and replays the cached transition
|
|
17
|
-
* as-is (it was serialized before the gate). PPR routes are the exception: their
|
|
18
|
-
* manifest predicates were evaluated before lookup and apply to replayed data.
|
|
19
|
-
*
|
|
20
|
-
* Returns the same array for the ordinary post-handler path. A PPR drop returns a
|
|
21
|
-
* copy containing only the request-specific transition changes.
|
|
22
|
-
*/
|
|
23
|
-
export declare function gateTransitions(segments: MatchResult["segments"], ctx: ReturnType<typeof getRequestContext>, onError?: OnErrorCallback): MatchResult["segments"];
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import type { MatchResult } from "../types.js";
|
|
2
|
-
import type { getRequestContext } from "../server/request-context.js";
|
|
3
|
-
import { invokeOnError } from "../router/error-handling.js";
|
|
4
|
-
import type { OnErrorCallback } from "../types/error-types.js";
|
|
5
|
-
import { createTransitionWhenContext } from "../router/transition-when.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Apply transition({ when }) gates to a payload's segments.
|
|
9
|
-
*
|
|
10
|
-
* PPR predicates were evaluated from the manifest before cache lookup and route
|
|
11
|
-
* handlers; their request-specific decisions are projected onto a copy so they
|
|
12
|
-
* never mutate reusable cache/prerender/shell records. Ordinary-route predicates
|
|
13
|
-
* were collected during fresh resolution and are evaluated here after handlers.
|
|
14
|
-
* Both paths drop the segment transition when the predicate does not hold.
|
|
15
|
-
*
|
|
16
|
-
* Mutating the segments here is safe: the segment cache stores a serialized copy
|
|
17
|
-
* (segment-codec), written during match() BEFORE this gate runs, so dropping a
|
|
18
|
-
* transition never corrupts a cache entry. On an ordinary route, a cache hit
|
|
19
|
-
* skips resolution, collects no predicate, and replays the cached transition
|
|
20
|
-
* as-is (it was serialized before the gate). PPR routes are the exception: their
|
|
21
|
-
* manifest predicates were evaluated before lookup and apply to replayed data.
|
|
22
|
-
*
|
|
23
|
-
* Returns the same array for the ordinary post-handler path. A PPR drop returns a
|
|
24
|
-
* copy containing only the request-specific transition changes.
|
|
25
|
-
*/
|
|
26
|
-
export function gateTransitions(
|
|
27
|
-
segments: MatchResult["segments"],
|
|
28
|
-
ctx: ReturnType<typeof getRequestContext>,
|
|
29
|
-
onError?: OnErrorCallback,
|
|
30
|
-
): MatchResult["segments"] {
|
|
31
|
-
const pprDecisions = ctx._pprTransitionDecisions;
|
|
32
|
-
let gatedSegments = segments;
|
|
33
|
-
|
|
34
|
-
const dropTransition = (id: string): void => {
|
|
35
|
-
const index = gatedSegments.findIndex((segment) => segment.id === id);
|
|
36
|
-
if (index === -1) return;
|
|
37
|
-
if (!pprDecisions) {
|
|
38
|
-
gatedSegments[index].transition = undefined;
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (gatedSegments === segments) gatedSegments = [...segments];
|
|
42
|
-
gatedSegments[index] = {
|
|
43
|
-
...gatedSegments[index],
|
|
44
|
-
transition: undefined,
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
if (pprDecisions) {
|
|
49
|
-
for (const [id, keep] of pprDecisions) {
|
|
50
|
-
if (!keep) dropTransition(id);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
const predicates = ctx._transitionWhen;
|
|
54
|
-
if (predicates) {
|
|
55
|
-
for (const { id, when } of predicates) {
|
|
56
|
-
try {
|
|
57
|
-
// Assemble the ShouldRevalidateFn-shaped predicate context from the
|
|
58
|
-
// request context. Source fields (currentUrl/currentParams/fromRouteName)
|
|
59
|
-
// were stashed at match time from the navigation snapshot; action fields
|
|
60
|
-
// at the action-bearing gate call sites. nextUrl/nextParams/toRouteName/
|
|
61
|
-
// method/get/env come straight off ctx (setRequestContextParams ran
|
|
62
|
-
// before the gate). Source/action fields are undefined when absent —
|
|
63
|
-
// never fabricated (see TransitionWhenContext).
|
|
64
|
-
if (when(createTransitionWhenContext(ctx)) !== false) continue;
|
|
65
|
-
} catch (error) {
|
|
66
|
-
// A throwing predicate must not fail the response: report it and treat
|
|
67
|
-
// the transition as gated off (do not hold). invokeOnError no-ops when
|
|
68
|
-
// onError is undefined.
|
|
69
|
-
invokeOnError(
|
|
70
|
-
onError,
|
|
71
|
-
error,
|
|
72
|
-
"rendering",
|
|
73
|
-
{
|
|
74
|
-
request: ctx.request,
|
|
75
|
-
url: ctx.url,
|
|
76
|
-
params: ctx.params,
|
|
77
|
-
segmentId: id,
|
|
78
|
-
},
|
|
79
|
-
"RSC",
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
dropTransition(id);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return gatedSegments;
|
|
86
|
-
}
|