@rangojs/router 0.0.0-experimental.8 → 0.0.0-experimental.8a4d0430
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/AGENTS.md +5 -0
- package/README.md +884 -4
- package/dist/bin/rango.js +1601 -0
- package/dist/vite/index.js +4474 -867
- package/package.json +60 -51
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +262 -0
- package/skills/caching/SKILL.md +50 -21
- package/skills/composability/SKILL.md +172 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +18 -16
- package/skills/fonts/SKILL.md +167 -0
- package/skills/hooks/SKILL.md +334 -72
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +131 -8
- package/skills/layout/SKILL.md +100 -3
- package/skills/links/SKILL.md +89 -30
- package/skills/loader/SKILL.md +388 -38
- package/skills/middleware/SKILL.md +171 -34
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +78 -1
- package/skills/prerender/SKILL.md +643 -0
- package/skills/rango/SKILL.md +85 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +226 -14
- package/skills/router-setup/SKILL.md +123 -30
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +318 -89
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +321 -0
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/event-controller.ts +87 -64
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +285 -553
- package/src/browser/navigation-client.ts +124 -71
- package/src/browser/navigation-store.ts +33 -50
- package/src/browser/navigation-transaction.ts +295 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +258 -308
- package/src/browser/prefetch/cache.ts +146 -0
- package/src/browser/prefetch/fetch.ts +135 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +42 -0
- package/src/browser/prefetch/queue.ts +88 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +185 -73
- package/src/browser/react/NavigationProvider.tsx +51 -11
- package/src/browser/react/context.ts +6 -0
- package/src/browser/react/filter-segment-order.ts +11 -0
- package/src/browser/react/index.ts +12 -12
- package/src/browser/react/location-state-shared.ts +95 -53
- package/src/browser/react/location-state.ts +60 -15
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +32 -79
- package/src/browser/react/use-href.tsx +2 -2
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +22 -63
- package/src/browser/react/use-params.ts +65 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-router.ts +63 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +80 -97
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +107 -26
- package/src/browser/scroll-restoration.ts +92 -16
- package/src/browser/segment-reconciler.ts +216 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +504 -599
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +109 -47
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +235 -24
- package/src/build/generate-route-types.ts +36 -0
- package/src/build/index.ts +13 -0
- package/src/build/route-trie.ts +265 -0
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +411 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +128 -0
- package/src/build/route-types/router-processing.ts +469 -0
- package/src/build/route-types/scan-filter.ts +78 -0
- package/src/build/runtime-discovery.ts +231 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +338 -0
- package/src/cache/cache-scope.ts +120 -303
- package/src/cache/cf/cf-cache-store.ts +119 -7
- package/src/cache/cf/index.ts +8 -2
- package/src/cache/document-cache.ts +101 -72
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +0 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +98 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +106 -126
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +86 -0
- package/src/debug.ts +17 -7
- package/src/errors.ts +108 -2
- package/src/handle.ts +15 -29
- package/src/handles/MetaTags.tsx +73 -20
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +30 -13
- package/src/host/cookie-handler.ts +21 -15
- package/src/host/errors.ts +8 -8
- package/src/host/index.ts +4 -7
- package/src/host/pattern-matcher.ts +27 -27
- package/src/host/router.ts +61 -39
- package/src/host/testing.ts +8 -8
- package/src/host/types.ts +15 -7
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +119 -29
- package/src/index.rsc.ts +153 -19
- package/src/index.ts +211 -30
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +26 -157
- package/src/loader.ts +27 -10
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +37 -0
- package/src/prerender/store.ts +185 -0
- package/src/prerender.ts +463 -0
- package/src/reverse.ts +330 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +934 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +430 -0
- package/src/route-definition/index.ts +52 -0
- package/src/route-definition/redirect.ts +93 -0
- package/src/route-definition.ts +1 -1428
- package/src/route-map-builder.ts +211 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +59 -8
- package/src/router/content-negotiation.ts +116 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +9 -9
- package/src/router/find-match.ts +158 -0
- package/src/router/handler-context.ts +374 -81
- package/src/router/intercept-resolution.ts +395 -0
- package/src/router/lazy-includes.ts +234 -0
- package/src/router/loader-resolution.ts +215 -122
- package/src/router/logging.ts +248 -0
- package/src/router/manifest.ts +148 -35
- package/src/router/match-api.ts +620 -0
- package/src/router/match-context.ts +5 -3
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +80 -93
- package/src/router/match-middleware/cache-lookup.ts +382 -9
- package/src/router/match-middleware/cache-store.ts +51 -22
- package/src/router/match-middleware/intercept-resolution.ts +55 -17
- package/src/router/match-middleware/segment-resolution.ts +24 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +34 -28
- package/src/router/metrics.ts +235 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +222 -0
- package/src/router/middleware.ts +324 -367
- package/src/router/pattern-matching.ts +211 -43
- package/src/router/prerender-match.ts +402 -0
- package/src/router/preview-match.ts +170 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/router-context.ts +36 -21
- package/src/router/router-interfaces.ts +452 -0
- package/src/router/router-options.ts +592 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +570 -0
- package/src/router/segment-resolution/helpers.ts +263 -0
- package/src/router/segment-resolution/loader-cache.ts +198 -0
- package/src/router/segment-resolution/revalidation.ts +1241 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -0
- package/src/router/segment-wrappers.ts +289 -0
- package/src/router/telemetry-otel.ts +299 -0
- package/src/router/telemetry.ts +300 -0
- package/src/router/timeout.ts +148 -0
- package/src/router/trie-matching.ts +239 -0
- package/src/router/types.ts +77 -3
- package/src/router.ts +692 -4257
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +764 -754
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +209 -0
- package/src/rsc/manifest-init.ts +86 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +379 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +235 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +348 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +38 -11
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +25 -13
- package/src/server/context.ts +182 -51
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +94 -15
- package/src/server/loader-registry.ts +15 -56
- package/src/server/request-context.ts +430 -70
- package/src/server.ts +35 -130
- package/src/ssr/index.tsx +100 -31
- package/src/static-handler.ts +114 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +5 -2
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +4 -30
- package/src/theme/theme-script.ts +21 -18
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +100 -0
- package/src/types/handler-context.ts +687 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +183 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +102 -0
- package/src/types/segments.ts +148 -0
- package/src/types.ts +1 -1623
- package/src/urls/include-helper.ts +197 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +339 -0
- package/src/urls/path-helper.ts +329 -0
- package/src/urls/pattern-types.ts +95 -0
- package/src/urls/response-types.ts +106 -0
- package/src/urls/type-extraction.ts +372 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -802
- package/src/use-loader.tsx +85 -77
- package/src/vite/discovery/bundle-postprocess.ts +184 -0
- package/src/vite/discovery/discover-routers.ts +344 -0
- package/src/vite/discovery/prerender-collection.ts +385 -0
- package/src/vite/discovery/route-types-writer.ts +258 -0
- package/src/vite/discovery/self-gen-tracking.ts +47 -0
- package/src/vite/discovery/state.ts +110 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +11 -1133
- package/src/vite/plugin-types.ts +131 -0
- package/src/vite/plugins/cjs-to-esm.ts +93 -0
- package/src/vite/plugins/client-ref-dedup.ts +115 -0
- package/src/vite/plugins/client-ref-hashing.ts +105 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -51
- package/src/vite/plugins/expose-id-utils.ts +287 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +569 -0
- package/src/vite/plugins/refresh-cmd.ts +65 -0
- package/src/vite/plugins/use-cache-transform.ts +323 -0
- package/src/vite/plugins/version-injector.ts +83 -0
- package/src/vite/plugins/version-plugin.ts +254 -0
- package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +23 -14
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +510 -0
- package/src/vite/router-discovery.ts +785 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +137 -0
- package/src/vite/utils/manifest-utils.ts +70 -0
- package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
- package/src/vite/utils/prerender-utils.ts +189 -0
- package/src/vite/utils/shared-utils.ts +169 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/href-context.ts +0 -33
- package/src/href.ts +0 -255
- package/src/server/route-manifest-cache.ts +0 -173
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -426
- package/src/vite/expose-location-state-id.ts +0 -177
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
package/src/browser/shallow.ts
CHANGED
|
@@ -26,7 +26,12 @@ export function shallow<T>(a: T, b: T): boolean {
|
|
|
26
26
|
|
|
27
27
|
// Check each key's value with Object.is
|
|
28
28
|
for (const key of keysA) {
|
|
29
|
-
if (
|
|
29
|
+
if (
|
|
30
|
+
!Object.is(
|
|
31
|
+
(a as Record<string, unknown>)[key],
|
|
32
|
+
(b as Record<string, unknown>)[key],
|
|
33
|
+
)
|
|
34
|
+
) {
|
|
30
35
|
return false;
|
|
31
36
|
}
|
|
32
37
|
}
|
package/src/browser/types.ts
CHANGED
|
@@ -8,10 +8,10 @@ import type { RenderSegmentsOptions } from "../segment-system.js";
|
|
|
8
8
|
// ============================================================================
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* RSC payload received from server
|
|
11
|
+
* RSC payload received from server.
|
|
12
|
+
* The tree is reconstructed from metadata.segments by the browser bridges.
|
|
12
13
|
*/
|
|
13
14
|
export interface RscPayload<TMetadata = RscMetadata> {
|
|
14
|
-
root: ReactNode | Promise<ReactNode> | null;
|
|
15
15
|
metadata?: TMetadata;
|
|
16
16
|
returnValue?: ActionResult;
|
|
17
17
|
formState?: unknown;
|
|
@@ -36,6 +36,8 @@ export interface RscMetadata {
|
|
|
36
36
|
isError?: boolean;
|
|
37
37
|
matched?: string[];
|
|
38
38
|
diff?: string[];
|
|
39
|
+
/** Merged route params from the matched route */
|
|
40
|
+
params?: Record<string, string>;
|
|
39
41
|
/**
|
|
40
42
|
* State of named slots for this route match
|
|
41
43
|
* Key is slot name (e.g., "@modal"), value is slot state
|
|
@@ -53,6 +55,11 @@ export interface RscMetadata {
|
|
|
53
55
|
* Used to detect version mismatches after HMR/deployment.
|
|
54
56
|
*/
|
|
55
57
|
version?: string;
|
|
58
|
+
/**
|
|
59
|
+
* TTL in milliseconds for the client-side in-memory prefetch cache.
|
|
60
|
+
* Sent on initial render so the browser can configure its cache duration.
|
|
61
|
+
*/
|
|
62
|
+
prefetchCacheTTL?: number;
|
|
56
63
|
/**
|
|
57
64
|
* Theme configuration from router.
|
|
58
65
|
* Included when theme is enabled in router config.
|
|
@@ -65,6 +72,10 @@ export interface RscMetadata {
|
|
|
65
72
|
initialTheme?: Theme;
|
|
66
73
|
/** Whether connection warmup is enabled */
|
|
67
74
|
warmupEnabled?: boolean;
|
|
75
|
+
/** Server-side redirect with optional state (for partial requests) */
|
|
76
|
+
redirect?: { url: string };
|
|
77
|
+
/** Server-set location state to include in history.pushState */
|
|
78
|
+
locationState?: Record<string, unknown>;
|
|
68
79
|
}
|
|
69
80
|
|
|
70
81
|
/**
|
|
@@ -115,7 +126,7 @@ export interface NavigationState {
|
|
|
115
126
|
/** Whether RSC data is currently streaming (initial load or navigation) */
|
|
116
127
|
isStreaming: boolean;
|
|
117
128
|
|
|
118
|
-
/** Current location
|
|
129
|
+
/** Current location */
|
|
119
130
|
location: NavigationLocation;
|
|
120
131
|
|
|
121
132
|
/** URL being navigated to (null when idle) */
|
|
@@ -172,7 +183,7 @@ export type ActionStateListener = (state: TrackedActionState) => void;
|
|
|
172
183
|
|
|
173
184
|
/**
|
|
174
185
|
* Cache interface for storing segments
|
|
175
|
-
* Compatible with
|
|
186
|
+
* Compatible with Map
|
|
176
187
|
*
|
|
177
188
|
* @internal This type is an implementation detail and may change without notice.
|
|
178
189
|
*/
|
|
@@ -209,9 +220,11 @@ export interface NavigationUpdate {
|
|
|
209
220
|
/**
|
|
210
221
|
* State value for navigate/Link
|
|
211
222
|
* - LocationStateEntry[]: Type-safe state entries (recommended)
|
|
212
|
-
* - unknown:
|
|
223
|
+
* - unknown: Plain state format (object or getter function)
|
|
213
224
|
*/
|
|
214
|
-
export type HistoryState =
|
|
225
|
+
export type HistoryState =
|
|
226
|
+
| import("./react/location-state-shared.js").LocationStateEntry[]
|
|
227
|
+
| unknown;
|
|
215
228
|
|
|
216
229
|
/**
|
|
217
230
|
* Options for navigation operations
|
|
@@ -219,6 +232,25 @@ export type HistoryState = import("./react/location-state-shared.js").LocationSt
|
|
|
219
232
|
export interface NavigateOptions {
|
|
220
233
|
replace?: boolean;
|
|
221
234
|
scroll?: boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Whether to revalidate server data on navigation.
|
|
237
|
+
* Set to `false` to skip the RSC server fetch and only update the URL.
|
|
238
|
+
*
|
|
239
|
+
* Only takes effect when the pathname stays the same (search param / hash changes).
|
|
240
|
+
* If the pathname changes, this option is ignored and a full navigation occurs.
|
|
241
|
+
*
|
|
242
|
+
* All location-aware hooks (`useSearchParams`, `useNavigation`, etc.) still update.
|
|
243
|
+
* Server components do not re-render.
|
|
244
|
+
*
|
|
245
|
+
* @default true
|
|
246
|
+
*
|
|
247
|
+
* @example
|
|
248
|
+
* ```tsx
|
|
249
|
+
* router.push("/products?color=blue", { revalidate: false });
|
|
250
|
+
* router.replace("/products?page=3", { revalidate: false });
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
revalidate?: boolean;
|
|
222
254
|
/**
|
|
223
255
|
* State to pass to history.pushState/replaceState
|
|
224
256
|
* Accessible via useLocationState() hook.
|
|
@@ -226,19 +258,67 @@ export interface NavigateOptions {
|
|
|
226
258
|
* @example
|
|
227
259
|
* ```tsx
|
|
228
260
|
* // Type-safe state (recommended)
|
|
229
|
-
* const ProductState = createLocationState<{ name: string }>(
|
|
261
|
+
* const ProductState = createLocationState<{ name: string }>();
|
|
230
262
|
* navigate("/product/123", { state: [ProductState({ name: "Widget" })] });
|
|
231
263
|
*
|
|
264
|
+
* // Type-safe just-in-time state (getter called at navigation time)
|
|
265
|
+
* navigate("/product/123", {
|
|
266
|
+
* state: [ProductState(() => ({ name: computeName() }))],
|
|
267
|
+
* });
|
|
268
|
+
*
|
|
232
269
|
* // Multiple states
|
|
233
270
|
* navigate("/checkout", { state: [ProductState(p), CartState(c)] });
|
|
234
271
|
*
|
|
235
|
-
* //
|
|
272
|
+
* // Plain static state
|
|
236
273
|
* navigate("/product", { state: { from: "list" } });
|
|
274
|
+
*
|
|
275
|
+
* // Plain just-in-time state
|
|
276
|
+
* navigate("/product", { state: () => ({ from: window.location.pathname }) });
|
|
237
277
|
* ```
|
|
238
278
|
*/
|
|
239
279
|
state?: HistoryState;
|
|
240
280
|
}
|
|
241
281
|
|
|
282
|
+
/** @internal Extended options used only within the navigation bridge */
|
|
283
|
+
export interface NavigateOptionsInternal extends NavigateOptions {
|
|
284
|
+
/** Skip segment cache (used by redirect-with-state to force re-render) */
|
|
285
|
+
_skipCache?: boolean;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Options for useRouter push/replace methods.
|
|
290
|
+
* Same as NavigateOptions but without `replace` (implicit in push vs replace).
|
|
291
|
+
*/
|
|
292
|
+
export type RouterNavigateOptions = Omit<NavigateOptions, "replace">;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Router instance returned by useRouter hook.
|
|
296
|
+
* Provides stable action methods that never cause re-renders.
|
|
297
|
+
*/
|
|
298
|
+
export interface RouterInstance {
|
|
299
|
+
/** Navigate to a URL, pushing a new entry to the history stack */
|
|
300
|
+
push(url: string, options?: RouterNavigateOptions): Promise<void>;
|
|
301
|
+
/** Navigate to a URL, replacing the current history entry */
|
|
302
|
+
replace(url: string, options?: RouterNavigateOptions): Promise<void>;
|
|
303
|
+
/** Refresh the current route (re-fetch server data, preserve client state) */
|
|
304
|
+
refresh(): Promise<void>;
|
|
305
|
+
/** Prefetch a URL for faster client-side transition */
|
|
306
|
+
prefetch(url: string): void;
|
|
307
|
+
/** Go back in browser history */
|
|
308
|
+
back(): void;
|
|
309
|
+
/** Go forward in browser history */
|
|
310
|
+
forward(): void;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* URLSearchParams without mutation methods.
|
|
315
|
+
* Matches Next.js convention for useSearchParams return type.
|
|
316
|
+
*/
|
|
317
|
+
export type ReadonlyURLSearchParams = Omit<
|
|
318
|
+
URLSearchParams,
|
|
319
|
+
"append" | "delete" | "set" | "sort"
|
|
320
|
+
>;
|
|
321
|
+
|
|
242
322
|
// ============================================================================
|
|
243
323
|
// RSC Browser Dependencies
|
|
244
324
|
// ============================================================================
|
|
@@ -252,15 +332,15 @@ export interface NavigateOptions {
|
|
|
252
332
|
export interface RscBrowserDependencies {
|
|
253
333
|
createFromFetch: <T>(
|
|
254
334
|
response: Promise<Response>,
|
|
255
|
-
options?: { temporaryReferences?: any }
|
|
335
|
+
options?: { temporaryReferences?: any },
|
|
256
336
|
) => Promise<T>;
|
|
257
337
|
createFromReadableStream: <T>(stream: ReadableStream) => Promise<T>;
|
|
258
338
|
encodeReply: (
|
|
259
339
|
args: any[],
|
|
260
|
-
options?: { temporaryReferences?: any }
|
|
340
|
+
options?: { temporaryReferences?: any },
|
|
261
341
|
) => Promise<FormData | string>;
|
|
262
342
|
setServerCallback: (
|
|
263
|
-
callback: (id: string, args: any[]) => Promise<any
|
|
343
|
+
callback: (id: string, args: any[]) => Promise<any>,
|
|
264
344
|
) => void;
|
|
265
345
|
createTemporaryReferenceSet: () => any;
|
|
266
346
|
}
|
|
@@ -312,11 +392,13 @@ export interface NavigationStore {
|
|
|
312
392
|
cacheSegmentsForHistory(
|
|
313
393
|
historyKey: string,
|
|
314
394
|
segments: ResolvedSegment[],
|
|
315
|
-
handleData?: HandleData
|
|
395
|
+
handleData?: HandleData,
|
|
316
396
|
): void;
|
|
317
397
|
getCachedSegments(
|
|
318
|
-
historyKey: string
|
|
319
|
-
):
|
|
398
|
+
historyKey: string,
|
|
399
|
+
):
|
|
400
|
+
| { segments: ResolvedSegment[]; stale: boolean; handleData?: HandleData }
|
|
401
|
+
| undefined;
|
|
320
402
|
hasHistoryCache(historyKey: string): boolean;
|
|
321
403
|
updateCacheHandleData(historyKey: string, handleData: HandleData): void;
|
|
322
404
|
markCacheAsStale(): void;
|
|
@@ -340,39 +422,10 @@ export interface NavigationStore {
|
|
|
340
422
|
setActionState(actionId: string, state: Partial<TrackedActionState>): void;
|
|
341
423
|
subscribeToAction(
|
|
342
424
|
actionId: string,
|
|
343
|
-
listener: ActionStateListener
|
|
425
|
+
listener: ActionStateListener,
|
|
344
426
|
): () => void;
|
|
345
427
|
}
|
|
346
428
|
|
|
347
|
-
// ============================================================================
|
|
348
|
-
// Request Controller Types
|
|
349
|
-
// ============================================================================
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Disposable abort controller with automatic cleanup
|
|
353
|
-
*/
|
|
354
|
-
export interface DisposableAbortController extends Disposable {
|
|
355
|
-
controller: AbortController;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Request controller for managing concurrent requests
|
|
360
|
-
*
|
|
361
|
-
* Separates navigation requests (aborted on new navigation) from
|
|
362
|
-
* action requests (complete independently of navigation).
|
|
363
|
-
*/
|
|
364
|
-
export interface RequestController {
|
|
365
|
-
create(): AbortController;
|
|
366
|
-
createDisposable(): DisposableAbortController;
|
|
367
|
-
/** Create a disposable controller for actions (not aborted by navigation) */
|
|
368
|
-
createActionDisposable(): DisposableAbortController;
|
|
369
|
-
/** Abort all navigation requests (not actions) */
|
|
370
|
-
abortAll(): void;
|
|
371
|
-
/** Abort all action requests (used for error handling) */
|
|
372
|
-
abortAllActions(): void;
|
|
373
|
-
remove(controller: AbortController): void;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
429
|
// ============================================================================
|
|
377
430
|
// Navigation Client Types
|
|
378
431
|
// ============================================================================
|
|
@@ -390,6 +443,8 @@ export interface FetchPartialOptions {
|
|
|
390
443
|
interceptSourceUrl?: string;
|
|
391
444
|
/** RSC version for cache invalidation detection */
|
|
392
445
|
version?: string;
|
|
446
|
+
/** If true, this is an HMR refetch - server should invalidate manifest cache */
|
|
447
|
+
hmr?: boolean;
|
|
393
448
|
}
|
|
394
449
|
|
|
395
450
|
/**
|
|
@@ -428,7 +483,6 @@ export interface LinkInterceptorOptions {
|
|
|
428
483
|
*/
|
|
429
484
|
export interface ServerActionBridge {
|
|
430
485
|
register(): void;
|
|
431
|
-
unregister(): void;
|
|
432
486
|
}
|
|
433
487
|
|
|
434
488
|
/**
|
|
@@ -441,7 +495,7 @@ export interface ServerActionBridgeConfig {
|
|
|
441
495
|
onUpdate: UpdateSubscriber;
|
|
442
496
|
renderSegments: (
|
|
443
497
|
segments: ResolvedSegment[],
|
|
444
|
-
options?: RenderSegmentsOptions
|
|
498
|
+
options?: RenderSegmentsOptions,
|
|
445
499
|
) => Promise<ReactNode> | ReactNode;
|
|
446
500
|
}
|
|
447
501
|
|
|
@@ -468,9 +522,17 @@ export interface NavigationBridgeConfig {
|
|
|
468
522
|
onUpdate: UpdateSubscriber;
|
|
469
523
|
renderSegments: (
|
|
470
524
|
segments: ResolvedSegment[],
|
|
471
|
-
options?: RenderSegmentsOptions
|
|
525
|
+
options?: RenderSegmentsOptions,
|
|
472
526
|
) => Promise<ReactNode> | ReactNode;
|
|
473
527
|
}
|
|
474
528
|
|
|
475
529
|
// Re-export ResolvedSegment for convenience
|
|
476
530
|
export type { ResolvedSegment };
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Token for tracking an active stream.
|
|
534
|
+
* Call end() when the stream completes.
|
|
535
|
+
*/
|
|
536
|
+
export interface StreamingToken {
|
|
537
|
+
end(): void;
|
|
538
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate that a client-consumed redirect URL (from headers or Flight payload)
|
|
3
|
+
* targets the same origin as the current page. Prevents open-redirect attacks
|
|
4
|
+
* via crafted responses.
|
|
5
|
+
*
|
|
6
|
+
* @returns The canonical (normalized) URL string on success, or null if blocked.
|
|
7
|
+
*/
|
|
8
|
+
export function validateRedirectOrigin(
|
|
9
|
+
url: string,
|
|
10
|
+
currentOrigin: string,
|
|
11
|
+
): string | null {
|
|
12
|
+
try {
|
|
13
|
+
const target = new URL(url, currentOrigin);
|
|
14
|
+
if (target.origin !== currentOrigin) {
|
|
15
|
+
console.error(
|
|
16
|
+
`[rango] Redirect blocked: origin mismatch (${target.origin})`,
|
|
17
|
+
);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
// Return pathname+search+hash for relative inputs, full href for absolute.
|
|
21
|
+
// This normalizes protocol-relative and other ambiguous forms.
|
|
22
|
+
return target.href.startsWith(currentOrigin)
|
|
23
|
+
? target.href
|
|
24
|
+
: target.pathname + target.search + target.hash;
|
|
25
|
+
} catch {
|
|
26
|
+
console.error(`[rango] Redirect blocked: invalid URL "${url}"`);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|