@rangojs/router 0.24.3 → 0.25.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 +1 -0
- package/dist/bin/rango.js +363 -39
- package/dist/testing/vitest.js +37 -4
- package/dist/types/browser/event-controller.d.ts +24 -5
- package/dist/types/browser/intercept-utils.d.ts +5 -2
- package/dist/types/browser/merge-segment-loaders.d.ts +0 -23
- package/dist/types/browser/navigation-transaction.d.ts +5 -5
- package/dist/types/browser/partial-update.d.ts +21 -13
- package/dist/types/browser/prefetch/cache.d.ts +8 -0
- package/dist/types/browser/rango-marker.d.ts +7 -0
- package/dist/types/browser/react/filter-segment-order.d.ts +10 -0
- package/dist/types/browser/react/use-handle.d.ts +20 -0
- package/dist/types/browser/react/use-href.d.ts +6 -0
- package/dist/types/browser/react/use-router.d.ts +6 -1
- package/dist/types/browser/response-adapter.d.ts +5 -3
- package/dist/types/browser/scroll-restoration.d.ts +9 -3
- package/dist/types/browser/segment-reconciler.d.ts +10 -13
- package/dist/types/browser/types.d.ts +38 -8
- package/dist/types/build/route-types/per-module-writer.d.ts +12 -0
- package/dist/types/cache/cf/cf-shell-frame.d.ts +2 -0
- package/dist/types/cache/types.d.ts +8 -0
- package/dist/types/client-urls/client-root.d.ts +4 -1
- package/dist/types/client-urls/client-urls.d.ts +28 -2
- package/dist/types/client-urls/navigation.d.ts +6 -8
- package/dist/types/client-urls/revalidate-registry.d.ts +1 -1
- package/dist/types/client-urls/server-projection.d.ts +20 -5
- package/dist/types/client-urls/types.d.ts +35 -17
- package/dist/types/client.d.ts +2 -2
- package/dist/types/client.rsc.d.ts +2 -2
- package/dist/types/decode-loader-results.d.ts +28 -7
- package/dist/types/href-client.d.ts +3 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/loader-redirect.d.ts +2 -3
- package/dist/types/outlet-context.d.ts +7 -6
- package/dist/types/prefetch-markers.d.ts +14 -5
- package/dist/types/route-content-wrapper.d.ts +17 -14
- package/dist/types/route-definition/helpers-types.d.ts +7 -2
- package/dist/types/route-definition/resolve-handler-use.d.ts +6 -1
- package/dist/types/route-definition/rewrite.d.ts +48 -5
- package/dist/types/route-types.d.ts +2 -2
- package/dist/types/router/handler-context.d.ts +14 -2
- package/dist/types/router/intercept-resolution.d.ts +19 -46
- package/dist/types/router/lazy-includes.d.ts +7 -0
- package/dist/types/router/match-middleware/intercept-resolution.d.ts +2 -2
- package/dist/types/router/middleware.d.ts +0 -16
- package/dist/types/router/navigation-snapshot.d.ts +2 -0
- package/dist/types/router/prefetch-cache-ttl.d.ts +8 -11
- package/dist/types/router/revalidation.d.ts +8 -1
- package/dist/types/router/router-context.d.ts +4 -16
- package/dist/types/router/router-interfaces.d.ts +0 -6
- package/dist/types/router/router-options.d.ts +4 -7
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +31 -8
- package/dist/types/router/segment-resolution/revalidation.d.ts +38 -4
- package/dist/types/router/segment-resolution.d.ts +1 -1
- package/dist/types/router/segment-wrappers.d.ts +3 -5
- package/dist/types/router/substitute-pattern-params.d.ts +19 -2
- package/dist/types/router/tracing.d.ts +2 -2
- package/dist/types/rsc/full-payload.d.ts +14 -2
- package/dist/types/rsc/helpers.d.ts +8 -0
- package/dist/types/rsc/manifest-init.d.ts +20 -0
- package/dist/types/rsc/prefetch-render-error.d.ts +22 -0
- package/dist/types/rsc/progressive-enhancement.d.ts +20 -0
- package/dist/types/rsc/rewrite-passes.d.ts +12 -2
- package/dist/types/rsc/server-action.d.ts +6 -0
- package/dist/types/rsc/shell-capture-constants.d.ts +10 -1
- package/dist/types/rsc/shell-capture.d.ts +7 -0
- package/dist/types/rsc/types.d.ts +5 -0
- package/dist/types/segment-system.d.ts +15 -0
- package/dist/types/server/context.d.ts +64 -4
- package/dist/types/server/request-context.d.ts +41 -4
- package/dist/types/server/request-headers.d.ts +12 -0
- package/dist/types/server/rewrite-trail.d.ts +8 -1
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +1 -1
- package/dist/types/testing/index.d.ts +1 -1
- package/dist/types/testing/internal/client-urls-projection.d.ts +4 -3
- package/dist/types/testing/render-route.d.ts +21 -11
- package/dist/types/testing/run-loader.d.ts +7 -0
- package/dist/types/testing/run-middleware.d.ts +7 -0
- package/dist/types/testing/run-revalidate.d.ts +5 -4
- package/dist/types/testing/serve-shell-request.d.ts +41 -4
- package/dist/types/testing/shell-status.d.ts +17 -0
- package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
- package/dist/types/testing/vitest.d.ts +10 -1
- package/dist/types/thenable-status.d.ts +0 -6
- package/dist/types/types/handler-context.d.ts +12 -1
- package/dist/types/types/loader-types.d.ts +4 -3
- package/dist/types/types/route-entry.d.ts +2 -1
- package/dist/types/urls/path-helper-types.d.ts +4 -2
- package/dist/types/urls/path-helper.d.ts +5 -0
- package/dist/types/vite/discovery/client-urls-projection.d.ts +55 -5
- package/dist/types/vite/discovery/state.d.ts +20 -0
- package/dist/types/vite/plugins/client-urls-revalidate-hoist.d.ts +28 -16
- package/dist/types/vite/plugins/hoist/source.d.ts +8 -7
- package/dist/types/vite/plugins/virtual-entries.d.ts +6 -0
- package/dist/types/vite/utils/prerender-utils.d.ts +7 -0
- package/dist/vite/index.js +6816 -6547
- package/package.json +1 -1
- package/skills/app-structure/SKILL.md +255 -0
- package/skills/app-structure/content-site.md +333 -0
- package/skills/app-structure/e-commerce.md +435 -0
- package/skills/app-structure/large-app.md +885 -0
- package/skills/app-structure/multi-app.md +280 -0
- package/skills/breadcrumbs/SKILL.md +6 -1
- package/skills/caching/SKILL.md +3 -1
- package/skills/catalog.json +12 -0
- package/skills/client-urls/SKILL.md +195 -32
- package/skills/composability/SKILL.md +10 -8
- package/skills/handler-use/SKILL.md +48 -9
- package/skills/hooks/handle-and-actions.md +104 -0
- package/skills/hooks/navigation.md +24 -10
- package/skills/hooks/urls.md +1 -1
- package/skills/i18n/SKILL.md +2 -1
- package/skills/intercept/SKILL.md +60 -29
- package/skills/layout/SKILL.md +6 -3
- package/skills/links/SKILL.md +151 -17
- package/skills/loader/SKILL.md +32 -10
- package/skills/middleware/SKILL.md +111 -15
- package/skills/observability/SKILL.md +11 -0
- package/skills/parallel/SKILL.md +5 -5
- package/skills/ppr/SKILL.md +43 -8
- package/skills/prerender/SKILL.md +1 -2
- package/skills/rango/SKILL.md +3 -0
- package/skills/response-routes/SKILL.md +4 -1
- package/skills/scripts/SKILL.md +12 -1
- package/skills/server-actions/SKILL.md +60 -20
- package/skills/testing/SKILL.md +1 -0
- package/skills/testing/client-components.md +13 -10
- package/skills/testing/loader.md +25 -24
- package/skills/testing/middleware.md +11 -11
- package/skills/testing/response-routes.md +4 -1
- package/skills/testing/serve-shell-request.md +85 -21
- package/skills/ux-architecture/SKILL.md +980 -0
- package/skills/view-transitions/SKILL.md +43 -10
- package/src/__augment-tests__/augmented.check.ts +28 -0
- package/src/browser/event-controller.ts +44 -18
- package/src/browser/intercept-utils.ts +3 -2
- package/src/browser/merge-segment-loaders.ts +0 -85
- package/src/browser/navigation-bridge.ts +119 -98
- package/src/browser/navigation-client.ts +20 -15
- package/src/browser/navigation-store.ts +4 -2
- package/src/browser/navigation-transaction.ts +9 -8
- package/src/browser/partial-update.ts +90 -32
- package/src/browser/prefetch/cache.ts +8 -0
- package/src/browser/prefetch/fetch.ts +13 -3
- package/src/browser/rango-marker.ts +13 -0
- package/src/browser/react/NavigationProvider.tsx +25 -7
- package/src/browser/react/filter-segment-order.ts +13 -0
- package/src/browser/react/use-action.ts +9 -15
- package/src/browser/react/use-handle.ts +63 -71
- package/src/browser/react/use-href.tsx +24 -5
- package/src/browser/react/use-link-status.ts +1 -1
- package/src/browser/react/use-navigation.ts +30 -40
- package/src/browser/react/use-reverse.ts +4 -17
- package/src/browser/react/use-router.ts +37 -6
- package/src/browser/react/use-segments.ts +8 -12
- package/src/browser/response-adapter.ts +11 -5
- package/src/browser/rsc-router.tsx +3 -1
- package/src/browser/scroll-restoration.ts +34 -20
- package/src/browser/segment-reconciler.ts +11 -29
- package/src/browser/server-action-bridge.ts +52 -16
- package/src/browser/types.ts +40 -8
- package/src/build/generate-manifest.ts +12 -1
- package/src/build/route-types/codegen.ts +6 -2
- package/src/build/route-types/per-module-writer.ts +94 -61
- package/src/cache/cache-runtime.ts +9 -0
- package/src/cache/cache-scope.ts +2 -1
- package/src/cache/cf/cf-cache-store.ts +2 -0
- package/src/cache/cf/cf-shell-frame.ts +3 -0
- package/src/cache/types.ts +8 -0
- package/src/cache/vercel/vercel-cache-store.ts +6 -1
- package/src/client-urls/client-root.tsx +10 -5
- package/src/client-urls/client-urls.ts +246 -166
- package/src/client-urls/navigation.ts +45 -38
- package/src/client-urls/revalidate-registry.ts +12 -3
- package/src/client-urls/server-projection.ts +286 -75
- package/src/client-urls/types.ts +40 -16
- package/src/client.rsc.tsx +11 -1
- package/src/client.tsx +9 -1
- package/src/decode-loader-results.ts +64 -31
- package/src/href-client.ts +3 -1
- package/src/index.rsc.ts +1 -0
- package/src/index.ts +12 -4
- package/src/loader-redirect.tsx +2 -3
- package/src/outlet-context.ts +7 -6
- package/src/prefetch-markers.ts +15 -5
- package/src/reverse.ts +3 -3
- package/src/route-content-wrapper.tsx +19 -17
- package/src/route-definition/dsl-helpers.ts +27 -7
- package/src/route-definition/helpers-types.ts +7 -2
- package/src/route-definition/resolve-handler-use.ts +23 -10
- package/src/route-definition/rewrite.ts +86 -19
- package/src/route-types.ts +1 -2
- package/src/router/find-match.ts +37 -1
- package/src/router/handler-context.ts +85 -40
- package/src/router/intercept-resolution.ts +161 -307
- package/src/router/lazy-includes.ts +43 -27
- package/src/router/loader-resolution.ts +21 -1
- package/src/router/manifest.ts +6 -8
- package/src/router/match-api.ts +11 -1
- package/src/router/match-middleware/background-revalidation.ts +2 -4
- package/src/router/match-middleware/cache-lookup.ts +16 -20
- package/src/router/match-middleware/intercept-resolution.ts +41 -60
- package/src/router/match-result.ts +31 -2
- package/src/router/middleware.ts +6 -147
- package/src/router/navigation-snapshot.ts +38 -2
- package/src/router/prefetch-cache-ttl.ts +10 -18
- package/src/router/prerender-match.ts +2 -1
- package/src/router/revalidation.ts +24 -3
- package/src/router/router-context.ts +5 -18
- package/src/router/router-interfaces.ts +0 -7
- package/src/router/router-options.ts +4 -7
- package/src/router/segment-resolution/fresh.ts +6 -2
- package/src/router/segment-resolution/helpers.ts +7 -1
- package/src/router/segment-resolution/prefetch-deferral.ts +62 -12
- package/src/router/segment-resolution/revalidation.ts +75 -35
- package/src/router/segment-resolution.ts +0 -1
- package/src/router/segment-wrappers.ts +8 -13
- package/src/router/substitute-pattern-params.ts +37 -2
- package/src/router/tracing.ts +2 -2
- package/src/router.ts +2 -9
- package/src/rsc/full-payload.ts +26 -4
- package/src/rsc/handler.ts +83 -41
- package/src/rsc/helpers.ts +13 -0
- package/src/rsc/manifest-init.ts +56 -3
- package/src/rsc/prefetch-render-error.ts +38 -0
- package/src/rsc/progressive-enhancement.ts +161 -211
- package/src/rsc/rewrite-passes.ts +56 -9
- package/src/rsc/rsc-rendering.ts +79 -23
- package/src/rsc/server-action.ts +25 -2
- package/src/rsc/shell-capture-constants.ts +22 -0
- package/src/rsc/shell-capture.ts +11 -0
- package/src/rsc/types.ts +5 -0
- package/src/segment-system.tsx +125 -119
- package/src/server/context.ts +96 -5
- package/src/server/handle-store.ts +3 -2
- package/src/server/request-context.ts +42 -3
- package/src/server/request-headers.ts +32 -0
- package/src/server/rewrite-trail.ts +55 -9
- package/src/ssr/ssr-root.tsx +6 -10
- package/src/testing/dispatch.ts +4 -5
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/flight.entry.ts +1 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/internal/client-urls-projection.ts +31 -11
- package/src/testing/render-route.tsx +83 -40
- package/src/testing/run-loader.ts +26 -2
- package/src/testing/run-middleware.ts +10 -0
- package/src/testing/run-revalidate.ts +13 -6
- package/src/testing/serve-shell-request.ts +77 -4
- package/src/testing/shell-status.ts +40 -0
- package/src/testing/vitest-stubs/version.ts +1 -0
- package/src/testing/vitest.ts +74 -7
- package/src/thenable-status.ts +0 -11
- package/src/types/handler-context.ts +12 -1
- package/src/types/loader-types.ts +4 -3
- package/src/types/route-entry.ts +2 -1
- package/src/urls/include-helper.ts +38 -11
- package/src/urls/path-helper-types.ts +4 -2
- package/src/urls/path-helper.ts +16 -3
- package/src/vite/discovery/client-urls-projection.ts +205 -16
- package/src/vite/discovery/discover-routers.ts +2 -2
- package/src/vite/discovery/prerender-collection.ts +2 -6
- package/src/vite/discovery/state.ts +26 -0
- package/src/vite/plugins/client-urls-revalidate-hoist.ts +190 -77
- package/src/vite/plugins/expose-internal-ids.ts +46 -40
- package/src/vite/plugins/hoist/source.ts +8 -7
- package/src/vite/plugins/transition-when-hoist.ts +1 -0
- package/src/vite/plugins/version-plugin.ts +7 -0
- package/src/vite/plugins/version.d.ts +7 -0
- package/src/vite/plugins/virtual-entries.ts +20 -0
- package/src/vite/rango.ts +4 -1
- package/src/vite/router-discovery.ts +39 -7
- package/src/vite/utils/prerender-utils.ts +17 -0
|
@@ -62,70 +62,107 @@ export function findUrlsVariableNames(code: string): string[] {
|
|
|
62
62
|
return names;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
export interface PerModuleRouteTypesPlan {
|
|
66
|
+
genPath: string;
|
|
67
|
+
/** A urls()/clientUrls() variable resolved to zero routes; content is empty. */
|
|
68
|
+
isPlaceholder: boolean;
|
|
69
|
+
content: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* routes.
|
|
73
|
+
* Pure half of the per-module writer: reads sources, never writes. Returns
|
|
74
|
+
* null when the file has no `urls(`/`clientUrls(` or no named routes and no
|
|
75
|
+
* urls() variable. Throws on failure.
|
|
70
76
|
*/
|
|
71
|
-
export function
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
export function planPerModuleRouteTypesForFile(
|
|
78
|
+
filePath: string,
|
|
79
|
+
): PerModuleRouteTypesPlan | null {
|
|
80
|
+
const source = readFileSync(filePath, "utf-8");
|
|
81
|
+
if (!source.includes("urls(") && !source.includes("clientUrls(")) return null;
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
const varNames = findUrlsVariableNames(source);
|
|
77
84
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
type Route = {
|
|
86
|
+
name: string;
|
|
87
|
+
pattern: string;
|
|
88
|
+
params?: Record<string, string>;
|
|
89
|
+
search?: Record<string, string>;
|
|
90
|
+
};
|
|
91
|
+
let routes: Route[];
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
93
|
+
if (varNames.length > 0) {
|
|
94
|
+
// Follow includes recursively via the combined route map builder.
|
|
95
|
+
// The visited set in buildCombinedRouteMapWithSearch prevents infinite loops.
|
|
96
|
+
// Share one per-file scan memo across all urls() variables so a shared
|
|
97
|
+
// include target is read+parsed once for this file, not once per variable.
|
|
98
|
+
routes = [];
|
|
99
|
+
const memo = createScanMemo();
|
|
100
|
+
for (const varName of varNames) {
|
|
101
|
+
const { routes: routeMap, searchSchemas } =
|
|
102
|
+
buildCombinedRouteMapWithSearch(
|
|
103
|
+
filePath,
|
|
104
|
+
varName,
|
|
105
|
+
undefined,
|
|
106
|
+
undefined,
|
|
107
|
+
undefined,
|
|
108
|
+
memo,
|
|
109
|
+
);
|
|
110
|
+
for (const [name, pattern] of Object.entries(routeMap)) {
|
|
111
|
+
const params = extractParamsFromPattern(pattern);
|
|
112
|
+
routes.push({
|
|
113
|
+
name,
|
|
114
|
+
pattern,
|
|
115
|
+
...(params ? { params } : {}),
|
|
116
|
+
...(searchSchemas[name] ? { search: searchSchemas[name] } : {}),
|
|
117
|
+
});
|
|
112
118
|
}
|
|
113
|
-
} else {
|
|
114
|
-
// Fallback: no urls() variable found, extract path() calls directly
|
|
115
|
-
routes = extractRoutesFromSource(source);
|
|
116
119
|
}
|
|
120
|
+
} else {
|
|
121
|
+
// Fallback: no urls() variable found, extract path() calls directly
|
|
122
|
+
routes = extractRoutesFromSource(source);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Match .ts/.tsx/.js/.jsx (same as router-processing.ts / router-transform.ts).
|
|
126
|
+
// Without the jsx? branch a .jsx/.js source produced genPath === filePath,
|
|
127
|
+
// overwriting the source file instead of writing a sibling .gen.ts.
|
|
128
|
+
const genPath = filePath.replace(/\.(tsx?|jsx?)$/, ".gen.ts");
|
|
117
129
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
if (routes.length === 0) {
|
|
131
|
+
if (varNames.length === 0) return null;
|
|
132
|
+
return {
|
|
133
|
+
genPath,
|
|
134
|
+
isPlaceholder: true,
|
|
135
|
+
content: generatePerModuleTypesSource([]),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
genPath,
|
|
140
|
+
isPlaceholder: false,
|
|
141
|
+
content: generatePerModuleTypesSource(routes),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Generate per-module route types for a single url module file.
|
|
147
|
+
* Follows include() calls recursively to produce the full route tree.
|
|
148
|
+
* No-ops if the file doesn't contain `urls(`/`clientUrls(` or has no named
|
|
149
|
+
* routes.
|
|
150
|
+
*/
|
|
151
|
+
export function writePerModuleRouteTypesForFile(filePath: string): void {
|
|
152
|
+
try {
|
|
153
|
+
const plan = planPerModuleRouteTypesForFile(filePath);
|
|
154
|
+
if (!plan) return;
|
|
155
|
+
const { genPath, isPlaceholder, content } = plan;
|
|
156
|
+
const exists = existsSync(genPath);
|
|
122
157
|
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
158
|
+
// A urls() variable whose static resolution yields zero routes gets an
|
|
159
|
+
// empty placeholder so an import of the sibling .gen.ts resolves. Nothing
|
|
160
|
+
// fills it in later: runtime discovery writes only *.named-routes.gen.ts
|
|
161
|
+
// (runtime-discovery.ts), so it stays `routes = {}` until a static run can
|
|
162
|
+
// resolve the module's includes and overwrites it.
|
|
163
|
+
if (isPlaceholder) {
|
|
164
|
+
if (!exists) {
|
|
165
|
+
writeFileSync(genPath, content);
|
|
129
166
|
console.log(
|
|
130
167
|
`[rango] Generated route types (placeholder) -> ${genPath}`,
|
|
131
168
|
);
|
|
@@ -133,12 +170,8 @@ export function writePerModuleRouteTypesForFile(filePath: string): void {
|
|
|
133
170
|
return;
|
|
134
171
|
}
|
|
135
172
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
? readFileSync(genPath, "utf-8")
|
|
139
|
-
: null;
|
|
140
|
-
if (existing !== genSource) {
|
|
141
|
-
writeFileSync(genPath, genSource);
|
|
173
|
+
if (!exists || readFileSync(genPath, "utf-8") !== content) {
|
|
174
|
+
writeFileSync(genPath, content);
|
|
142
175
|
console.log(`[rango] Generated route types -> ${genPath}`);
|
|
143
176
|
}
|
|
144
177
|
} catch (err) {
|
|
@@ -508,6 +508,15 @@ export function registerCachedFunction<T extends (...args: any[]) => any>(
|
|
|
508
508
|
if (ctx._routeName) {
|
|
509
509
|
keyArgs.push(ctx._routeName);
|
|
510
510
|
}
|
|
511
|
+
// A layout's / parallel's / their loader's ctx resolves dot names
|
|
512
|
+
// in its own module (withReverseScope), so one route's segments
|
|
513
|
+
// can reverse the same name differently.
|
|
514
|
+
const scope = ctx._reverseScope;
|
|
515
|
+
if (scope) {
|
|
516
|
+
keyArgs.push(
|
|
517
|
+
`reverse-scope:${scope.prefix ?? ""}:${scope.rootScoped}`,
|
|
518
|
+
);
|
|
519
|
+
}
|
|
511
520
|
keyArgs.push(ctx.pathname, ctx.params);
|
|
512
521
|
if (ctx._responseType) {
|
|
513
522
|
keyArgs.push(ctx._responseType);
|
package/src/cache/cache-scope.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
runInSegmentTagScope,
|
|
25
25
|
} from "./cache-tag.js";
|
|
26
26
|
import { reportCacheError } from "./cache-error.js";
|
|
27
|
+
import { isInterceptSegment } from "../browser/intercept-utils.js";
|
|
27
28
|
import {
|
|
28
29
|
predatesInvalidation,
|
|
29
30
|
type ExecutionStart,
|
|
@@ -373,7 +374,7 @@ export class CacheScope {
|
|
|
373
374
|
const next = id.charCodeAt(boundary.length);
|
|
374
375
|
return !(next >= 48 && next <= 57);
|
|
375
376
|
}
|
|
376
|
-
return
|
|
377
|
+
return isInterceptSegment({ namespace });
|
|
377
378
|
}
|
|
378
379
|
|
|
379
380
|
/**
|
|
@@ -422,6 +422,7 @@ function shellHeadToEntry(head: ShellFrameHead): ShellEntryHead {
|
|
|
422
422
|
reactVersion: head.rv,
|
|
423
423
|
buildVersion: head.bv,
|
|
424
424
|
initialTheme: head.i,
|
|
425
|
+
pathname: head.lp,
|
|
425
426
|
docKey: head.dk,
|
|
426
427
|
prunedRecords: head.pr,
|
|
427
428
|
navigationOnly: head.no,
|
|
@@ -2695,6 +2696,7 @@ export class CFCacheStore<TEnv = unknown> implements SegmentCacheStore<TEnv> {
|
|
|
2695
2696
|
t: tags,
|
|
2696
2697
|
ta: taggedAt,
|
|
2697
2698
|
i: entry.initialTheme,
|
|
2699
|
+
lp: entry.pathname,
|
|
2698
2700
|
dk: entry.docKey,
|
|
2699
2701
|
pr: entry.prunedRecords,
|
|
2700
2702
|
no: entry.navigationOnly,
|
|
@@ -47,6 +47,8 @@ export interface ShellFrameHead {
|
|
|
47
47
|
ta?: number;
|
|
48
48
|
/** ShellCacheEntry.initialTheme */
|
|
49
49
|
i?: string;
|
|
50
|
+
/** ShellCacheEntry.pathname (a visitor-keyed shell's rendered location). */
|
|
51
|
+
lp?: string;
|
|
50
52
|
/** ShellCacheEntry.docKey; navigation replay needs it after any round trip. */
|
|
51
53
|
dk?: string;
|
|
52
54
|
/** ShellCacheEntry.prunedRecords (diagnostic). */
|
|
@@ -79,6 +81,7 @@ function isShellFrameHead(value: unknown): value is ShellFrameHead {
|
|
|
79
81
|
head.t.every((tag) => typeof tag === "string"))) &&
|
|
80
82
|
(head.ta === undefined || isFiniteNumber(head.ta)) &&
|
|
81
83
|
(head.i === undefined || typeof head.i === "string") &&
|
|
84
|
+
(head.lp === undefined || typeof head.lp === "string") &&
|
|
82
85
|
(head.dk === undefined || typeof head.dk === "string") &&
|
|
83
86
|
(head.pr === undefined || typeof head.pr === "string") &&
|
|
84
87
|
(head.no === undefined || head.no === true) &&
|
package/src/cache/types.ts
CHANGED
|
@@ -468,6 +468,14 @@ export interface ShellCacheEntry {
|
|
|
468
468
|
* ThemeProvider.
|
|
469
469
|
*/
|
|
470
470
|
initialTheme?: string;
|
|
471
|
+
/**
|
|
472
|
+
* The payload pathname of a shell keyed by the visitor's URL
|
|
473
|
+
* (`rewrite(...).shell("visitor")`, visitorShellKey); absent when the
|
|
474
|
+
* capture rendered its key's own URL. The serve tail replays it as it does
|
|
475
|
+
* `initialTheme`, and the serve gate serves the entry only to a request
|
|
476
|
+
* that renders this location.
|
|
477
|
+
*/
|
|
478
|
+
pathname?: string;
|
|
471
479
|
/**
|
|
472
480
|
* The CAPTURE DATA SNAPSHOT, in stored/serialized form: the doc segment
|
|
473
481
|
* record every HIT replays the handler layer from (`docKey`) and the
|
|
@@ -271,6 +271,8 @@ interface VercelShellEnvelope {
|
|
|
271
271
|
t?: string[];
|
|
272
272
|
/** initialTheme the capture render was built with (resume theme fidelity). */
|
|
273
273
|
i?: string;
|
|
274
|
+
/** ShellCacheEntry.pathname (a visitor-keyed shell's rendered location). */
|
|
275
|
+
lp?: string;
|
|
274
276
|
/** Capture data snapshot (ShellCacheEntry.snapshot). */
|
|
275
277
|
sn: ShellSnapshotRecord[];
|
|
276
278
|
/**
|
|
@@ -1158,6 +1160,7 @@ export class VercelCacheStore<
|
|
|
1158
1160
|
reactVersion: env.rv,
|
|
1159
1161
|
buildVersion: env.bv,
|
|
1160
1162
|
initialTheme: env.i,
|
|
1163
|
+
pathname: env.lp,
|
|
1161
1164
|
snapshot: env.sn,
|
|
1162
1165
|
docKey: env.dk,
|
|
1163
1166
|
prunedRecords: env.pr,
|
|
@@ -1326,6 +1329,7 @@ export class VercelCacheStore<
|
|
|
1326
1329
|
e: Math.min(expiresAt, now + retentionTtl * 1000),
|
|
1327
1330
|
t: safeTags.length > 0 ? safeTags : undefined,
|
|
1328
1331
|
i: entry.initialTheme,
|
|
1332
|
+
lp: entry.pathname,
|
|
1329
1333
|
sn: entry.snapshot,
|
|
1330
1334
|
dk: entry.docKey,
|
|
1331
1335
|
pr: entry.prunedRecords,
|
|
@@ -1743,7 +1747,7 @@ export class VercelCacheStore<
|
|
|
1743
1747
|
|
|
1744
1748
|
private asShellEnvelope(raw: unknown): VercelShellEnvelope | null {
|
|
1745
1749
|
if (!isRecord(raw)) return null;
|
|
1746
|
-
const { p, po, rv, bv, c, s, e, t, i, sn, dk, pr, no } = raw;
|
|
1750
|
+
const { p, po, rv, bv, c, s, e, t, i, lp, sn, dk, pr, no } = raw;
|
|
1747
1751
|
if (typeof rv !== "string" || typeof bv !== "string") return null;
|
|
1748
1752
|
// Document half: required unless navigationOnly (`no`), which stores
|
|
1749
1753
|
// neither field. Tolerate a legacy navigationOnly envelope that still
|
|
@@ -1766,6 +1770,7 @@ export class VercelCacheStore<
|
|
|
1766
1770
|
e,
|
|
1767
1771
|
t: Array.isArray(t) ? (t as string[]) : undefined,
|
|
1768
1772
|
i: typeof i === "string" ? i : undefined,
|
|
1773
|
+
lp: typeof lp === "string" ? lp : undefined,
|
|
1769
1774
|
// A non-array field reads as no records.
|
|
1770
1775
|
sn: Array.isArray(sn) ? (sn as ShellSnapshotRecord[]) : [],
|
|
1771
1776
|
dk: typeof dk === "string" ? dk : undefined,
|
|
@@ -108,17 +108,21 @@ export function ClientUrlsRoot({
|
|
|
108
108
|
definition,
|
|
109
109
|
routeId,
|
|
110
110
|
namePrefix = "",
|
|
111
|
+
foreign,
|
|
111
112
|
}: {
|
|
112
113
|
definition: ClientUrlPatterns;
|
|
113
114
|
routeId: string;
|
|
114
115
|
/** include() route-name prefix, injected at materialization for canonical
|
|
115
116
|
* name composition (intercept-target coordination). */
|
|
116
117
|
namePrefix?: string;
|
|
118
|
+
/** The server's routes that compete with the group's for a URL
|
|
119
|
+
* (competingPatterns in server-projection.ts). */
|
|
120
|
+
foreign?: readonly string[];
|
|
117
121
|
}): ReactNode {
|
|
118
|
-
// The include() mount
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
+
// The include() mount pattern this group renders under ("/" at root).
|
|
123
|
+
// Navigation matches an absolute pathname against the definition's
|
|
124
|
+
// patterns joined to it (buildClientUrlsTrie in client-urls.ts), as
|
|
125
|
+
// useReverse joins it.
|
|
122
126
|
const mount = useMount();
|
|
123
127
|
const [intent, setIntent] = useState<ClientUrlNavigationIntent | null>(null);
|
|
124
128
|
|
|
@@ -155,8 +159,9 @@ export function ClientUrlsRoot({
|
|
|
155
159
|
namePrefix,
|
|
156
160
|
setIntent,
|
|
157
161
|
optimisticRoute ? undefined : routeId,
|
|
162
|
+
foreign,
|
|
158
163
|
),
|
|
159
|
-
[definition, mount, namePrefix, routeId, optimisticRoute],
|
|
164
|
+
[definition, mount, namePrefix, routeId, optimisticRoute, foreign],
|
|
160
165
|
);
|
|
161
166
|
|
|
162
167
|
// Pending entries for the destination's loaders: useLoader use()s a Promise
|