@rangojs/router 0.0.0-experimental.3 → 0.0.0-experimental.31
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 +883 -4
- package/dist/bin/rango.js +1601 -0
- package/dist/vite/index.js +4655 -747
- package/package.json +78 -50
- package/skills/breadcrumbs/SKILL.md +206 -0
- package/skills/cache-guide/SKILL.md +262 -0
- package/skills/caching/SKILL.md +54 -25
- package/skills/composability/SKILL.md +172 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +23 -21
- package/skills/fonts/SKILL.md +167 -0
- package/skills/hooks/SKILL.md +389 -64
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +133 -10
- package/skills/layout/SKILL.md +102 -5
- package/skills/links/SKILL.md +239 -0
- package/skills/loader/SKILL.md +366 -29
- package/skills/middleware/SKILL.md +173 -36
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +80 -3
- package/skills/prerender/SKILL.md +643 -0
- package/skills/rango/SKILL.md +86 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +227 -15
- package/skills/router-setup/SKILL.md +225 -32
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +12 -11
- package/skills/typesafety/SKILL.md +415 -87
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +10 -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 +20 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +201 -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 +267 -317
- 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 +173 -73
- package/src/browser/react/NavigationProvider.tsx +138 -27
- 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 +37 -0
- 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 +49 -65
- package/src/browser/react/use-href.tsx +20 -188
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-mount.ts +31 -0
- package/src/browser/react/use-navigation.ts +27 -78
- 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 +111 -26
- package/src/browser/scroll-restoration.ts +92 -16
- package/src/browser/segment-reconciler.ts +216 -0
- package/src/browser/segment-structure-assert.ts +83 -0
- package/src/browser/server-action-bridge.ts +504 -584
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +92 -57
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +438 -0
- package/src/build/generate-route-types.ts +36 -0
- package/src/build/index.ts +35 -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 +12 -15
- package/src/client.tsx +115 -135
- 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 +34 -19
- 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 +165 -0
- package/src/host/errors.ts +97 -0
- package/src/host/index.ts +53 -0
- package/src/host/pattern-matcher.ts +214 -0
- package/src/host/router.ts +352 -0
- package/src/host/testing.ts +79 -0
- package/src/host/types.ts +146 -0
- package/src/host/utils.ts +25 -0
- package/src/href-client.ts +135 -49
- package/src/index.rsc.ts +183 -17
- package/src/index.ts +241 -24
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +27 -142
- 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 +9 -11
- 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 -1388
- package/src/route-map-builder.ts +241 -112
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +70 -9
- 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 +371 -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 +155 -32
- 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 -29
- 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 +321 -30
- package/src/router/prerender-match.ts +400 -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 +688 -3656
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +786 -760
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +5 -25
- 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 +40 -14
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +57 -61
- package/src/server/context.ts +202 -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 +422 -70
- package/src/server.ts +36 -120
- package/src/ssr/index.tsx +157 -26
- 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 -1577
- 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 -726
- 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 -782
- 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} +29 -15
- 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 -3
- 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/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -357
- 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.
|
|
@@ -63,16 +70,12 @@ export interface RscMetadata {
|
|
|
63
70
|
* Included when theme is enabled in router config.
|
|
64
71
|
*/
|
|
65
72
|
initialTheme?: Theme;
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
* Current matched route name (for local name resolution in useHref).
|
|
73
|
-
* When using include() with name prefix, this contains the full prefixed name.
|
|
74
|
-
*/
|
|
75
|
-
routeName?: string;
|
|
73
|
+
/** Whether connection warmup is enabled */
|
|
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>;
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
/**
|
|
@@ -123,7 +126,7 @@ export interface NavigationState {
|
|
|
123
126
|
/** Whether RSC data is currently streaming (initial load or navigation) */
|
|
124
127
|
isStreaming: boolean;
|
|
125
128
|
|
|
126
|
-
/** Current location
|
|
129
|
+
/** Current location */
|
|
127
130
|
location: NavigationLocation;
|
|
128
131
|
|
|
129
132
|
/** URL being navigated to (null when idle) */
|
|
@@ -180,7 +183,7 @@ export type ActionStateListener = (state: TrackedActionState) => void;
|
|
|
180
183
|
|
|
181
184
|
/**
|
|
182
185
|
* Cache interface for storing segments
|
|
183
|
-
* Compatible with
|
|
186
|
+
* Compatible with Map
|
|
184
187
|
*
|
|
185
188
|
* @internal This type is an implementation detail and may change without notice.
|
|
186
189
|
*/
|
|
@@ -217,9 +220,11 @@ export interface NavigationUpdate {
|
|
|
217
220
|
/**
|
|
218
221
|
* State value for navigate/Link
|
|
219
222
|
* - LocationStateEntry[]: Type-safe state entries (recommended)
|
|
220
|
-
* - unknown:
|
|
223
|
+
* - unknown: Plain state format (object or getter function)
|
|
221
224
|
*/
|
|
222
|
-
export type HistoryState =
|
|
225
|
+
export type HistoryState =
|
|
226
|
+
| import("./react/location-state-shared.js").LocationStateEntry[]
|
|
227
|
+
| unknown;
|
|
223
228
|
|
|
224
229
|
/**
|
|
225
230
|
* Options for navigation operations
|
|
@@ -234,19 +239,67 @@ export interface NavigateOptions {
|
|
|
234
239
|
* @example
|
|
235
240
|
* ```tsx
|
|
236
241
|
* // Type-safe state (recommended)
|
|
237
|
-
* const ProductState = createLocationState<{ name: string }>(
|
|
242
|
+
* const ProductState = createLocationState<{ name: string }>();
|
|
238
243
|
* navigate("/product/123", { state: [ProductState({ name: "Widget" })] });
|
|
239
244
|
*
|
|
245
|
+
* // Type-safe just-in-time state (getter called at navigation time)
|
|
246
|
+
* navigate("/product/123", {
|
|
247
|
+
* state: [ProductState(() => ({ name: computeName() }))],
|
|
248
|
+
* });
|
|
249
|
+
*
|
|
240
250
|
* // Multiple states
|
|
241
251
|
* navigate("/checkout", { state: [ProductState(p), CartState(c)] });
|
|
242
252
|
*
|
|
243
|
-
* //
|
|
253
|
+
* // Plain static state
|
|
244
254
|
* navigate("/product", { state: { from: "list" } });
|
|
255
|
+
*
|
|
256
|
+
* // Plain just-in-time state
|
|
257
|
+
* navigate("/product", { state: () => ({ from: window.location.pathname }) });
|
|
245
258
|
* ```
|
|
246
259
|
*/
|
|
247
260
|
state?: HistoryState;
|
|
248
261
|
}
|
|
249
262
|
|
|
263
|
+
/** @internal Extended options used only within the navigation bridge */
|
|
264
|
+
export interface NavigateOptionsInternal extends NavigateOptions {
|
|
265
|
+
/** Skip segment cache (used by redirect-with-state to force re-render) */
|
|
266
|
+
_skipCache?: boolean;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Options for useRouter push/replace methods.
|
|
271
|
+
* Same as NavigateOptions but without `replace` (implicit in push vs replace).
|
|
272
|
+
*/
|
|
273
|
+
export type RouterNavigateOptions = Omit<NavigateOptions, "replace">;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Router instance returned by useRouter hook.
|
|
277
|
+
* Provides stable action methods that never cause re-renders.
|
|
278
|
+
*/
|
|
279
|
+
export interface RouterInstance {
|
|
280
|
+
/** Navigate to a URL, pushing a new entry to the history stack */
|
|
281
|
+
push(url: string, options?: RouterNavigateOptions): Promise<void>;
|
|
282
|
+
/** Navigate to a URL, replacing the current history entry */
|
|
283
|
+
replace(url: string, options?: RouterNavigateOptions): Promise<void>;
|
|
284
|
+
/** Refresh the current route (re-fetch server data, preserve client state) */
|
|
285
|
+
refresh(): Promise<void>;
|
|
286
|
+
/** Prefetch a URL for faster client-side transition */
|
|
287
|
+
prefetch(url: string): void;
|
|
288
|
+
/** Go back in browser history */
|
|
289
|
+
back(): void;
|
|
290
|
+
/** Go forward in browser history */
|
|
291
|
+
forward(): void;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* URLSearchParams without mutation methods.
|
|
296
|
+
* Matches Next.js convention for useSearchParams return type.
|
|
297
|
+
*/
|
|
298
|
+
export type ReadonlyURLSearchParams = Omit<
|
|
299
|
+
URLSearchParams,
|
|
300
|
+
"append" | "delete" | "set" | "sort"
|
|
301
|
+
>;
|
|
302
|
+
|
|
250
303
|
// ============================================================================
|
|
251
304
|
// RSC Browser Dependencies
|
|
252
305
|
// ============================================================================
|
|
@@ -260,15 +313,15 @@ export interface NavigateOptions {
|
|
|
260
313
|
export interface RscBrowserDependencies {
|
|
261
314
|
createFromFetch: <T>(
|
|
262
315
|
response: Promise<Response>,
|
|
263
|
-
options?: { temporaryReferences?: any }
|
|
316
|
+
options?: { temporaryReferences?: any },
|
|
264
317
|
) => Promise<T>;
|
|
265
318
|
createFromReadableStream: <T>(stream: ReadableStream) => Promise<T>;
|
|
266
319
|
encodeReply: (
|
|
267
320
|
args: any[],
|
|
268
|
-
options?: { temporaryReferences?: any }
|
|
321
|
+
options?: { temporaryReferences?: any },
|
|
269
322
|
) => Promise<FormData | string>;
|
|
270
323
|
setServerCallback: (
|
|
271
|
-
callback: (id: string, args: any[]) => Promise<any
|
|
324
|
+
callback: (id: string, args: any[]) => Promise<any>,
|
|
272
325
|
) => void;
|
|
273
326
|
createTemporaryReferenceSet: () => any;
|
|
274
327
|
}
|
|
@@ -320,11 +373,13 @@ export interface NavigationStore {
|
|
|
320
373
|
cacheSegmentsForHistory(
|
|
321
374
|
historyKey: string,
|
|
322
375
|
segments: ResolvedSegment[],
|
|
323
|
-
handleData?: HandleData
|
|
376
|
+
handleData?: HandleData,
|
|
324
377
|
): void;
|
|
325
378
|
getCachedSegments(
|
|
326
|
-
historyKey: string
|
|
327
|
-
):
|
|
379
|
+
historyKey: string,
|
|
380
|
+
):
|
|
381
|
+
| { segments: ResolvedSegment[]; stale: boolean; handleData?: HandleData }
|
|
382
|
+
| undefined;
|
|
328
383
|
hasHistoryCache(historyKey: string): boolean;
|
|
329
384
|
updateCacheHandleData(historyKey: string, handleData: HandleData): void;
|
|
330
385
|
markCacheAsStale(): void;
|
|
@@ -348,39 +403,10 @@ export interface NavigationStore {
|
|
|
348
403
|
setActionState(actionId: string, state: Partial<TrackedActionState>): void;
|
|
349
404
|
subscribeToAction(
|
|
350
405
|
actionId: string,
|
|
351
|
-
listener: ActionStateListener
|
|
406
|
+
listener: ActionStateListener,
|
|
352
407
|
): () => void;
|
|
353
408
|
}
|
|
354
409
|
|
|
355
|
-
// ============================================================================
|
|
356
|
-
// Request Controller Types
|
|
357
|
-
// ============================================================================
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Disposable abort controller with automatic cleanup
|
|
361
|
-
*/
|
|
362
|
-
export interface DisposableAbortController extends Disposable {
|
|
363
|
-
controller: AbortController;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Request controller for managing concurrent requests
|
|
368
|
-
*
|
|
369
|
-
* Separates navigation requests (aborted on new navigation) from
|
|
370
|
-
* action requests (complete independently of navigation).
|
|
371
|
-
*/
|
|
372
|
-
export interface RequestController {
|
|
373
|
-
create(): AbortController;
|
|
374
|
-
createDisposable(): DisposableAbortController;
|
|
375
|
-
/** Create a disposable controller for actions (not aborted by navigation) */
|
|
376
|
-
createActionDisposable(): DisposableAbortController;
|
|
377
|
-
/** Abort all navigation requests (not actions) */
|
|
378
|
-
abortAll(): void;
|
|
379
|
-
/** Abort all action requests (used for error handling) */
|
|
380
|
-
abortAllActions(): void;
|
|
381
|
-
remove(controller: AbortController): void;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
410
|
// ============================================================================
|
|
385
411
|
// Navigation Client Types
|
|
386
412
|
// ============================================================================
|
|
@@ -398,6 +424,8 @@ export interface FetchPartialOptions {
|
|
|
398
424
|
interceptSourceUrl?: string;
|
|
399
425
|
/** RSC version for cache invalidation detection */
|
|
400
426
|
version?: string;
|
|
427
|
+
/** If true, this is an HMR refetch - server should invalidate manifest cache */
|
|
428
|
+
hmr?: boolean;
|
|
401
429
|
}
|
|
402
430
|
|
|
403
431
|
/**
|
|
@@ -436,7 +464,6 @@ export interface LinkInterceptorOptions {
|
|
|
436
464
|
*/
|
|
437
465
|
export interface ServerActionBridge {
|
|
438
466
|
register(): void;
|
|
439
|
-
unregister(): void;
|
|
440
467
|
}
|
|
441
468
|
|
|
442
469
|
/**
|
|
@@ -449,7 +476,7 @@ export interface ServerActionBridgeConfig {
|
|
|
449
476
|
onUpdate: UpdateSubscriber;
|
|
450
477
|
renderSegments: (
|
|
451
478
|
segments: ResolvedSegment[],
|
|
452
|
-
options?: RenderSegmentsOptions
|
|
479
|
+
options?: RenderSegmentsOptions,
|
|
453
480
|
) => Promise<ReactNode> | ReactNode;
|
|
454
481
|
}
|
|
455
482
|
|
|
@@ -476,9 +503,17 @@ export interface NavigationBridgeConfig {
|
|
|
476
503
|
onUpdate: UpdateSubscriber;
|
|
477
504
|
renderSegments: (
|
|
478
505
|
segments: ResolvedSegment[],
|
|
479
|
-
options?: RenderSegmentsOptions
|
|
506
|
+
options?: RenderSegmentsOptions,
|
|
480
507
|
) => Promise<ReactNode> | ReactNode;
|
|
481
508
|
}
|
|
482
509
|
|
|
483
510
|
// Re-export ResolvedSegment for convenience
|
|
484
511
|
export type { ResolvedSegment };
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Token for tracking an active stream.
|
|
515
|
+
* Call end() when the stream completes.
|
|
516
|
+
*/
|
|
517
|
+
export interface StreamingToken {
|
|
518
|
+
end(): void;
|
|
519
|
+
}
|
|
@@ -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
|
+
}
|