@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
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "./revalidate-chain.js";
|
|
9
9
|
import { encodeClientRevalidationDecisions } from "./revalidation-protocol.js";
|
|
10
10
|
import type { ClientUrlPatterns } from "./types.js";
|
|
11
|
+
import type { TransitionWhenFn } from "../types/segments.js";
|
|
11
12
|
|
|
12
13
|
export interface ClientUrlNavigationIntent {
|
|
13
14
|
readonly routeId: string;
|
|
@@ -16,6 +17,26 @@ export interface ClientUrlNavigationIntent {
|
|
|
16
17
|
/** Absolute destination pathname (mount included) and search ("?..." or ""). */
|
|
17
18
|
readonly pathname: string;
|
|
18
19
|
readonly search: string;
|
|
20
|
+
/**
|
|
21
|
+
* transition({ when }) gated this navigation off at the swap: the
|
|
22
|
+
* destination presents urgently instead of in a transition lane.
|
|
23
|
+
*/
|
|
24
|
+
readonly transitionGatedOff?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** What the bridge needs to decide transition({ when }) at the swap. */
|
|
28
|
+
export interface ClientUrlDestination {
|
|
29
|
+
/** Definition-local params of the destination match. */
|
|
30
|
+
readonly params: Readonly<Record<string, string>>;
|
|
31
|
+
/** Canonical route name (include prefix applied); undefined when unnamed. */
|
|
32
|
+
readonly routeName: string | undefined;
|
|
33
|
+
/** The destination route's own `when`, from its "use client" definition. */
|
|
34
|
+
readonly when: TransitionWhenFn | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Param names the ORIGIN route matched inside the group: the committed
|
|
37
|
+
* params minus these are the mount's (include prefix) params.
|
|
38
|
+
*/
|
|
39
|
+
readonly originLocalParamNames: readonly string[];
|
|
19
40
|
}
|
|
20
41
|
|
|
21
42
|
interface ActiveClientUrlGroup {
|
|
@@ -24,6 +45,8 @@ interface ActiveClientUrlGroup {
|
|
|
24
45
|
readonly mount: string;
|
|
25
46
|
/** include() route-name prefix ("" at root) for canonical name composition. */
|
|
26
47
|
readonly namePrefix: string;
|
|
48
|
+
/** The group route on screen (ClientUrlsRoot's committed routeId). */
|
|
49
|
+
readonly routeId: string | undefined;
|
|
27
50
|
readonly setIntent: (intent: ClientUrlNavigationIntent | null) => void;
|
|
28
51
|
intent: ClientUrlNavigationIntent | null;
|
|
29
52
|
}
|
|
@@ -48,6 +71,12 @@ export function setActiveInterceptTargets(
|
|
|
48
71
|
|
|
49
72
|
export interface ClientUrlNavigationPresentation {
|
|
50
73
|
readonly routeId: string;
|
|
74
|
+
/**
|
|
75
|
+
* The transition({ when }) decision made at the optimistic swap (true =
|
|
76
|
+
* gated off), or undefined when nothing was swapped (a same-route
|
|
77
|
+
* navigation decides at the canonical commit).
|
|
78
|
+
*/
|
|
79
|
+
readonly transitionGatedOff: boolean | undefined;
|
|
51
80
|
clear(): void;
|
|
52
81
|
}
|
|
53
82
|
|
|
@@ -75,11 +104,13 @@ export function registerClientUrlGroup(
|
|
|
75
104
|
mount: string,
|
|
76
105
|
namePrefix: string,
|
|
77
106
|
setIntent: (intent: ClientUrlNavigationIntent | null) => void,
|
|
107
|
+
routeId?: string,
|
|
78
108
|
): () => void {
|
|
79
109
|
const group: ActiveClientUrlGroup = {
|
|
80
110
|
definition,
|
|
81
111
|
mount,
|
|
82
112
|
namePrefix,
|
|
113
|
+
routeId,
|
|
83
114
|
setIntent,
|
|
84
115
|
intent: null,
|
|
85
116
|
};
|
|
@@ -93,6 +124,7 @@ export function registerClientUrlGroup(
|
|
|
93
124
|
export function beginClientUrlNavigation(
|
|
94
125
|
targetUrl: URL,
|
|
95
126
|
signal: AbortSignal,
|
|
127
|
+
decideTransition?: (destination: ClientUrlDestination) => boolean,
|
|
96
128
|
): ClientUrlNavigationPresentation | null {
|
|
97
129
|
const group = activeGroup;
|
|
98
130
|
if (!group) return null;
|
|
@@ -110,11 +142,28 @@ export function beginClientUrlNavigation(
|
|
|
110
142
|
const record = group.definition.routes.find(
|
|
111
143
|
(candidate) => candidate.id === match.routeKey,
|
|
112
144
|
);
|
|
113
|
-
|
|
114
|
-
|
|
145
|
+
const canonicalName = record?.name
|
|
146
|
+
? group.namePrefix
|
|
115
147
|
? `${group.namePrefix}.${record.name}`
|
|
116
|
-
: record.name
|
|
117
|
-
|
|
148
|
+
: record.name
|
|
149
|
+
: undefined;
|
|
150
|
+
if (canonicalName && activeInterceptTargets.has(canonicalName)) return null;
|
|
151
|
+
|
|
152
|
+
// A same-route intent never swaps (ClientUrlsRoot), so transition({ when })
|
|
153
|
+
// decides at the canonical commit; a cross-route one decides here, at the
|
|
154
|
+
// navigation's first presentation.
|
|
155
|
+
let transitionGatedOff: boolean | undefined;
|
|
156
|
+
if (decideTransition && match.routeKey !== group.routeId) {
|
|
157
|
+
const originLocal = stripMountPrefix(window.location.pathname, group.mount);
|
|
158
|
+
const originMatch =
|
|
159
|
+
originLocal === null ? null : group.definition.match(originLocal);
|
|
160
|
+
const when = record?.transition?.when;
|
|
161
|
+
transitionGatedOff = decideTransition({
|
|
162
|
+
params: match.params,
|
|
163
|
+
routeName: canonicalName,
|
|
164
|
+
when: typeof when === "function" ? when : undefined,
|
|
165
|
+
originLocalParamNames: Object.keys(originMatch?.params ?? {}),
|
|
166
|
+
});
|
|
118
167
|
}
|
|
119
168
|
|
|
120
169
|
const intent: ClientUrlNavigationIntent = {
|
|
@@ -122,6 +171,7 @@ export function beginClientUrlNavigation(
|
|
|
122
171
|
params: match.params,
|
|
123
172
|
pathname: targetUrl.pathname,
|
|
124
173
|
search: targetUrl.search,
|
|
174
|
+
transitionGatedOff,
|
|
125
175
|
};
|
|
126
176
|
group.intent = intent;
|
|
127
177
|
group.setIntent(intent);
|
|
@@ -142,6 +192,7 @@ export function beginClientUrlNavigation(
|
|
|
142
192
|
|
|
143
193
|
return {
|
|
144
194
|
routeId: match.routeKey,
|
|
195
|
+
transitionGatedOff,
|
|
145
196
|
clear() {
|
|
146
197
|
signal.removeEventListener("abort", clear);
|
|
147
198
|
clear();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { requestHeaders } from "../server/request-headers.js";
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import type { SearchSchemaValue } from "../search-params.js";
|
|
3
4
|
import { getLoaderLazy } from "../server/loader-registry.js";
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
ClientUrlsLoading,
|
|
28
29
|
ClientUrlsRoot,
|
|
29
30
|
} from "./client-root.js";
|
|
31
|
+
import { createClientUrlsWhenRef } from "../transition-when-ref.js";
|
|
30
32
|
import type {
|
|
31
33
|
ClientTransitionConfig,
|
|
32
34
|
ClientUrlInterceptRecord,
|
|
@@ -94,9 +96,12 @@ export interface ClientUrlProjectionRoute {
|
|
|
94
96
|
* document renders await them before first flush. Absent (= none) in
|
|
95
97
|
* projections serialized before the option existed. */
|
|
96
98
|
readonly awaitedLoaderIndices?: readonly number[];
|
|
97
|
-
/** Data-only transition config (
|
|
98
|
-
*
|
|
99
|
+
/** Data-only transition config (never `when`); absent in projections
|
|
100
|
+
* serialized before transition support. */
|
|
99
101
|
readonly transition?: Readonly<ClientTransitionConfig>;
|
|
102
|
+
/** The route's transition() declares a browser-run `when`. Materialization
|
|
103
|
+
* attaches a clientUrls when reference (definition + route id). */
|
|
104
|
+
readonly transitionWhen?: true;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
export interface ClientUrlProjectionIntercept {
|
|
@@ -249,11 +254,12 @@ function serializeTransition(
|
|
|
249
254
|
): Readonly<ClientTransitionConfig> | undefined {
|
|
250
255
|
const source = route.transition;
|
|
251
256
|
if (!source) return undefined;
|
|
252
|
-
// The DSL already validated shape
|
|
253
|
-
//
|
|
257
|
+
// The DSL already validated shape; re-copy defensively so the projection is
|
|
258
|
+
// a plain JSON value (class maps included). `when` is a function: the
|
|
259
|
+
// projection records only that it exists (transitionWhen).
|
|
254
260
|
const config: Record<string, unknown> = {};
|
|
255
261
|
for (const [key, value] of Object.entries(source)) {
|
|
256
|
-
if (value === undefined) continue;
|
|
262
|
+
if (value === undefined || key === "when") continue;
|
|
257
263
|
config[key] =
|
|
258
264
|
typeof value === "object" && value !== null
|
|
259
265
|
? Object.freeze({ ...(value as Record<string, string>) })
|
|
@@ -289,6 +295,9 @@ function serializeRoute(route: ClientUrlRouteRecord): ClientUrlProjectionRoute {
|
|
|
289
295
|
? { awaitedLoaderIndices: Object.freeze(awaitedLoaderIndices) }
|
|
290
296
|
: {}),
|
|
291
297
|
...(transition ? { transition } : {}),
|
|
298
|
+
...(typeof route.transition?.when === "function"
|
|
299
|
+
? { transitionWhen: true as const }
|
|
300
|
+
: {}),
|
|
292
301
|
});
|
|
293
302
|
}
|
|
294
303
|
|
|
@@ -433,7 +442,7 @@ function clientDecisionsFor(
|
|
|
433
442
|
return decisionsByRequest.get(request) ?? null;
|
|
434
443
|
}
|
|
435
444
|
const decoded = decodeClientRevalidationDecisions(
|
|
436
|
-
request.
|
|
445
|
+
requestHeaders(request).get(CLIENT_REVALIDATION_HEADER),
|
|
437
446
|
);
|
|
438
447
|
decisionsByRequest.set(request, decoded);
|
|
439
448
|
return decoded;
|
|
@@ -561,9 +570,20 @@ function materializeRouteItems(
|
|
|
561
570
|
),
|
|
562
571
|
]
|
|
563
572
|
: []),
|
|
564
|
-
//
|
|
565
|
-
// hand-written server transition(config)
|
|
566
|
-
|
|
573
|
+
// Per-route transition config: same child position as a
|
|
574
|
+
// hand-written server transition(config). A declared `when` rides
|
|
575
|
+
// as a reference to the definition + route id; the browser calls
|
|
576
|
+
// the function the "use client" module declares.
|
|
577
|
+
...(route.transition
|
|
578
|
+
? [
|
|
579
|
+
transition({
|
|
580
|
+
...route.transition,
|
|
581
|
+
...(route.transitionWhen
|
|
582
|
+
? { when: createClientUrlsWhenRef(reference, route.id) }
|
|
583
|
+
: {}),
|
|
584
|
+
}),
|
|
585
|
+
]
|
|
586
|
+
: []),
|
|
567
587
|
],
|
|
568
588
|
) as AllUseItems,
|
|
569
589
|
);
|
|
@@ -596,7 +616,8 @@ function materializeRouteItems(
|
|
|
596
616
|
const isInGroupOrigin = ({ from }: InterceptSelectorContext): boolean =>
|
|
597
617
|
mount === "/"
|
|
598
618
|
? true
|
|
599
|
-
: from.pathname === mount ||
|
|
619
|
+
: from.url.pathname === mount ||
|
|
620
|
+
from.url.pathname.startsWith(`${mount}/`);
|
|
600
621
|
const slotNames = [...new Set(intercepts.map((record) => record.slotName))];
|
|
601
622
|
const buildInterceptItems = (): AllUseItems[] =>
|
|
602
623
|
intercepts.map(
|
package/src/client-urls/types.ts
CHANGED
|
@@ -123,14 +123,21 @@ export interface ClientUrlLoaderRecord {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
|
-
* The
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
126
|
+
* The TransitionConfig subset a clientUrls() route may declare: ViewTransition
|
|
127
|
+
* classes/name, the boundary opt-out, and the browser-run `when` gate. The
|
|
128
|
+
* projection carries only a "has when" marker; the browser calls the function
|
|
129
|
+
* this module declares (transition-when-ref.ts resolveTransitionWhen).
|
|
130
130
|
*/
|
|
131
131
|
export type ClientTransitionConfig = Pick<
|
|
132
132
|
TransitionConfig,
|
|
133
|
-
|
|
133
|
+
| "enter"
|
|
134
|
+
| "exit"
|
|
135
|
+
| "update"
|
|
136
|
+
| "share"
|
|
137
|
+
| "default"
|
|
138
|
+
| "name"
|
|
139
|
+
| "viewTransition"
|
|
140
|
+
| "when"
|
|
134
141
|
>;
|
|
135
142
|
|
|
136
143
|
export interface ClientUrlRouteRecord {
|
package/src/client.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { requestHeaders } from "../server/request-headers.js";
|
|
1
2
|
import type { HostOverrideConfig } from "./types.js";
|
|
2
3
|
import type { RouterRequestInput } from "../router/router-interfaces.js";
|
|
3
4
|
import { matchPattern, parseRequest } from "./pattern-matcher.js";
|
|
@@ -9,7 +10,7 @@ import {
|
|
|
9
10
|
import { parseCookiesFromHeader } from "../server/cookie-parse.js";
|
|
10
11
|
|
|
11
12
|
export function parseCookies(request: Request): Record<string, string> {
|
|
12
|
-
return parseCookiesFromHeader(request.
|
|
13
|
+
return parseCookiesFromHeader(requestHeaders(request).get("cookie"));
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export function getCookie(request: Request, name: string): string | undefined {
|
package/src/index.rsc.ts
CHANGED
package/src/index.ts
CHANGED
package/src/loader-redirect.tsx
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
3
|
import { useEffect } from "react";
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
NavigateOptionsInternal,
|
|
6
|
+
RouterNavigateOptions,
|
|
7
|
+
} from "./browser/types.js";
|
|
5
8
|
import { useRouter } from "./browser/react/use-router.js";
|
|
6
9
|
import { validateExternalRedirect } from "./browser/validate-redirect-origin.js";
|
|
7
10
|
import { resolveSameOriginRedirect } from "./redirect-origin.js";
|
|
@@ -48,8 +51,9 @@ export function LoaderRedirect({
|
|
|
48
51
|
// so it must not log a "blocked" error on its way to the branch below.
|
|
49
52
|
const sameOrigin = resolveSameOriginRedirect(to, origin);
|
|
50
53
|
if (sameOrigin) {
|
|
51
|
-
const options:
|
|
52
|
-
|
|
54
|
+
const options:
|
|
55
|
+
| (RouterNavigateOptions & Pick<NavigateOptionsInternal, "_skipCache">)
|
|
56
|
+
| undefined = state ? { state, _skipCache: true } : undefined;
|
|
53
57
|
void router.replace(sameOrigin, options);
|
|
54
58
|
return;
|
|
55
59
|
}
|