@rangojs/router 0.0.0-experimental.a769fbe7 → 0.0.0-experimental.ac99d918
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 +211 -43
- package/dist/bin/rango.js +279 -102
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3313 -1160
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +62 -11
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +63 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +222 -30
- package/skills/caching/SKILL.md +263 -8
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +250 -30
- package/skills/host-router/SKILL.md +124 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +223 -9
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +77 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +66 -5
- package/skills/router-setup/SKILL.md +38 -3
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +120 -0
- package/skills/typesafety/SKILL.md +319 -27
- package/skills/use-cache/SKILL.md +36 -5
- package/skills/vercel/SKILL.md +107 -0
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +1 -66
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +81 -147
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/navigation-bridge.ts +66 -14
- package/src/browser/navigation-client.ts +172 -109
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/partial-update.ts +79 -93
- package/src/browser/prefetch/cache.ts +180 -62
- package/src/browser/prefetch/fetch.ts +252 -39
- package/src/browser/prefetch/queue.ts +42 -8
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +72 -10
- package/src/browser/react/NavigationProvider.tsx +83 -31
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +46 -11
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +52 -1
- package/src/browser/rsc-router.tsx +111 -24
- package/src/browser/scroll-restoration.ts +29 -19
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -62
- package/src/browser/types.ts +60 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +6 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +333 -94
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +134 -32
- package/src/cache/cache-scope.ts +100 -74
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2256 -241
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +61 -20
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +22 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +17 -5
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/browser.ts +0 -1
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +69 -10
- package/src/index.ts +112 -14
- package/src/internal-debug.ts +2 -4
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +413 -275
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +107 -32
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +50 -8
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +0 -16
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +44 -23
- package/src/router/handler-context.ts +46 -30
- package/src/router/intercept-resolution.ts +23 -23
- package/src/router/lazy-includes.ts +15 -52
- package/src/router/loader-resolution.ts +207 -30
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +40 -42
- package/src/router/match-api.ts +120 -204
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +0 -7
- package/src/router/match-middleware/cache-lookup.ts +161 -262
- package/src/router/match-middleware/cache-store.ts +3 -33
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +45 -14
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +87 -39
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -140
- package/src/router/middleware.ts +169 -140
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +190 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +0 -27
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +119 -65
- package/src/router/segment-resolution/helpers.ts +34 -0
- package/src/router/segment-resolution/loader-cache.ts +40 -37
- package/src/router/segment-resolution/revalidation.ts +329 -305
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +4 -1
- package/src/router/segment-wrappers.ts +0 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +128 -42
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -409
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +18 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +28 -4
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +53 -56
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -69
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +22 -9
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +208 -201
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +211 -52
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +289 -124
- package/src/ssr/index.tsx +22 -15
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +124 -70
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +40 -11
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +12 -7
- package/src/types/segments.ts +36 -15
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +192 -99
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +51 -4
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +236 -6
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -317
- package/src/vite/plugins/performance-tracks.ts +65 -207
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +32 -23
- package/src/vite/plugins/virtual-entries.ts +46 -17
- package/src/vite/rango.ts +207 -125
- package/src/vite/router-discovery.ts +931 -133
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +27 -29
- package/src/vite/utils/shared-utils.ts +97 -44
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/debug-channel.ts +0 -93
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route Snapshot
|
|
3
|
+
*
|
|
4
|
+
* Pure data type representing the fully-resolved state of a single route match.
|
|
5
|
+
* Consolidates the duplicated findMatch + loadManifest + collectRouteMiddleware +
|
|
6
|
+
* cacheScope derivation that previously lived separately in preview-match.ts
|
|
7
|
+
* and match-api.ts.
|
|
8
|
+
*
|
|
9
|
+
* resolveRoute() is the factory: given a pathname and dependencies, it returns
|
|
10
|
+
* a RouteSnapshot (or redirect/null). Consumers (createMatchContextForFull,
|
|
11
|
+
* createMatchContextForPartial, previewMatch) read snapshot fields instead of
|
|
12
|
+
* re-deriving them.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { CacheScope } from "../cache/cache-scope.js";
|
|
16
|
+
import { createCacheScope } from "../cache/cache-scope.js";
|
|
17
|
+
import type { EntryData, MetricsStore } from "../server/context.js";
|
|
18
|
+
import { loadManifest } from "./manifest.js";
|
|
19
|
+
import { collectRouteMiddleware } from "./middleware.js";
|
|
20
|
+
import type { CollectedMiddleware } from "./middleware-types.js";
|
|
21
|
+
import { traverseBack } from "./pattern-matching.js";
|
|
22
|
+
import type { RouteMatchResult } from "./pattern-matching.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Immutable snapshot of a resolved route match.
|
|
26
|
+
*
|
|
27
|
+
* Contains everything derivable from (pathname, findMatch, loadManifest)
|
|
28
|
+
* without request context, navigation state, or intercept logic.
|
|
29
|
+
*/
|
|
30
|
+
export interface RouteSnapshot<TEnv = any> {
|
|
31
|
+
/** Raw match result from the trie/pattern matcher */
|
|
32
|
+
matched: RouteMatchResult<TEnv>;
|
|
33
|
+
/** Resolved manifest entry (with loaded handler, loader, etc.) */
|
|
34
|
+
manifestEntry: EntryData;
|
|
35
|
+
/** All entries in the route chain (from traverseBack) */
|
|
36
|
+
entries: EntryData[];
|
|
37
|
+
/** Canonical route key (e.g. "blog.detail") */
|
|
38
|
+
routeKey: string;
|
|
39
|
+
/** Last segment of a dotted route key (e.g. "detail" from "blog.detail") */
|
|
40
|
+
localRouteName: string;
|
|
41
|
+
/** Extracted route params */
|
|
42
|
+
params: Record<string, string>;
|
|
43
|
+
/** Collected route-level middleware from the entry tree */
|
|
44
|
+
routeMiddleware: CollectedMiddleware[];
|
|
45
|
+
/** Merged cache scope from the entry chain */
|
|
46
|
+
cacheScope: CacheScope | null;
|
|
47
|
+
/** Whether the matched route is a passthrough route */
|
|
48
|
+
isPassthrough: boolean;
|
|
49
|
+
/** Response type for non-RSC routes (e.g. "application/json") */
|
|
50
|
+
responseType?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type ResolveRouteResult<TEnv = any> =
|
|
54
|
+
| { type: "match"; snapshot: RouteSnapshot<TEnv> }
|
|
55
|
+
| { type: "redirect"; redirectTo: string }
|
|
56
|
+
| null;
|
|
57
|
+
|
|
58
|
+
export interface ResolveRouteDeps<TEnv = any> {
|
|
59
|
+
findMatch: (pathname: string) => RouteMatchResult<TEnv> | null;
|
|
60
|
+
metricsStore?: MetricsStore;
|
|
61
|
+
isSSR?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* When true, skip entries array and cacheScope chain construction.
|
|
64
|
+
* Used by previewMatch which only needs matched, manifestEntry,
|
|
65
|
+
* routeMiddleware, and responseType — avoids an extra traverseBack
|
|
66
|
+
* allocation and cacheScope composition on the hot classification path.
|
|
67
|
+
*/
|
|
68
|
+
lite?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* When true, skip pushing the "route-matching" metric internally.
|
|
71
|
+
* Used by createMatchContextForPartial on the fresh path (no snapshot
|
|
72
|
+
* reuse) so it can measure current + prev + intercept-source findMatch
|
|
73
|
+
* calls under one combined "route-matching" metric. On the reuse path,
|
|
74
|
+
* the partial path emits "route-matching:nav" for the prev +
|
|
75
|
+
* intercept-source lookups only (current-route resolution was done
|
|
76
|
+
* during classification without metrics).
|
|
77
|
+
*/
|
|
78
|
+
skipRouteMatchMetric?: boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Resolve a pathname into a RouteSnapshot.
|
|
83
|
+
*
|
|
84
|
+
* This is the single source of truth for route derivation. It performs:
|
|
85
|
+
* 1. findMatch(pathname)
|
|
86
|
+
* 2. Redirect check
|
|
87
|
+
* 3. loadManifest
|
|
88
|
+
* 4. Passthrough detection
|
|
89
|
+
* 5. collectRouteMiddleware
|
|
90
|
+
* 6. Cache scope chain
|
|
91
|
+
* 7. responseType + localRouteName extraction
|
|
92
|
+
*
|
|
93
|
+
* Metrics timing is preserved identically to the previous inline code.
|
|
94
|
+
*/
|
|
95
|
+
export async function resolveRoute<TEnv = any>(
|
|
96
|
+
pathname: string,
|
|
97
|
+
deps: ResolveRouteDeps<TEnv>,
|
|
98
|
+
): Promise<ResolveRouteResult<TEnv>> {
|
|
99
|
+
const {
|
|
100
|
+
metricsStore,
|
|
101
|
+
isSSR = false,
|
|
102
|
+
lite = false,
|
|
103
|
+
skipRouteMatchMetric = false,
|
|
104
|
+
} = deps;
|
|
105
|
+
|
|
106
|
+
const routeMatchStart =
|
|
107
|
+
metricsStore && !skipRouteMatchMetric ? performance.now() : 0;
|
|
108
|
+
const matched = deps.findMatch(pathname);
|
|
109
|
+
if (metricsStore && !skipRouteMatchMetric) {
|
|
110
|
+
metricsStore.metrics.push({
|
|
111
|
+
label: "route-matching",
|
|
112
|
+
duration: performance.now() - routeMatchStart,
|
|
113
|
+
startTime: routeMatchStart - metricsStore.requestStart,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!matched) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (matched.redirectTo) {
|
|
122
|
+
return { type: "redirect", redirectTo: matched.redirectTo };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const manifestStart = metricsStore ? performance.now() : 0;
|
|
126
|
+
const manifestEntry = await loadManifest(
|
|
127
|
+
matched.entry,
|
|
128
|
+
matched.routeKey,
|
|
129
|
+
pathname,
|
|
130
|
+
metricsStore,
|
|
131
|
+
isSSR,
|
|
132
|
+
);
|
|
133
|
+
if (metricsStore) {
|
|
134
|
+
metricsStore.metrics.push({
|
|
135
|
+
label: "manifest-loading",
|
|
136
|
+
duration: performance.now() - manifestStart,
|
|
137
|
+
startTime: manifestStart - metricsStore.requestStart,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const isPassthrough =
|
|
142
|
+
manifestEntry.type === "route" && manifestEntry.isPassthrough === true;
|
|
143
|
+
|
|
144
|
+
let entries: EntryData[];
|
|
145
|
+
let cacheScope: CacheScope | null = null;
|
|
146
|
+
if (lite) {
|
|
147
|
+
entries = [];
|
|
148
|
+
} else {
|
|
149
|
+
({ entries, cacheScope } = buildEntriesAndCacheScope(manifestEntry));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const routeMiddleware = collectRouteMiddleware(
|
|
153
|
+
lite ? traverseBack(manifestEntry) : entries,
|
|
154
|
+
matched.params,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const responseType =
|
|
158
|
+
matched.responseType ||
|
|
159
|
+
(manifestEntry.type === "route" ? manifestEntry.responseType : undefined);
|
|
160
|
+
|
|
161
|
+
const localRouteName = matched.routeKey.includes(".")
|
|
162
|
+
? matched.routeKey.split(".").pop()!
|
|
163
|
+
: matched.routeKey;
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
type: "match",
|
|
167
|
+
snapshot: {
|
|
168
|
+
matched,
|
|
169
|
+
manifestEntry,
|
|
170
|
+
entries,
|
|
171
|
+
routeKey: matched.routeKey,
|
|
172
|
+
localRouteName,
|
|
173
|
+
params: matched.params,
|
|
174
|
+
routeMiddleware,
|
|
175
|
+
cacheScope,
|
|
176
|
+
isPassthrough,
|
|
177
|
+
responseType,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Fill in the entries and cacheScope fields on a lite snapshot.
|
|
184
|
+
*
|
|
185
|
+
* When classifyRequest produces a lite snapshot (entries=[], cacheScope=null),
|
|
186
|
+
* this function computes the missing fields from manifestEntry without
|
|
187
|
+
* re-running findMatch, loadManifest, or collectRouteMiddleware.
|
|
188
|
+
*
|
|
189
|
+
* If the snapshot already has entries, returns it as-is.
|
|
190
|
+
*/
|
|
191
|
+
export function ensureFullRouteSnapshot<TEnv = any>(
|
|
192
|
+
snapshot: RouteSnapshot<TEnv>,
|
|
193
|
+
): RouteSnapshot<TEnv> {
|
|
194
|
+
if (snapshot.entries.length > 0) {
|
|
195
|
+
return snapshot;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const { entries, cacheScope } = buildEntriesAndCacheScope(
|
|
199
|
+
snapshot.manifestEntry,
|
|
200
|
+
);
|
|
201
|
+
return { ...snapshot, entries, cacheScope };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Materialize the entry chain and derive the merged cache scope.
|
|
206
|
+
* Shared by resolveRoute (non-lite) and ensureFullRouteSnapshot.
|
|
207
|
+
*/
|
|
208
|
+
function buildEntriesAndCacheScope(manifestEntry: EntryData): {
|
|
209
|
+
entries: EntryData[];
|
|
210
|
+
cacheScope: CacheScope | null;
|
|
211
|
+
} {
|
|
212
|
+
const entries = [...traverseBack(manifestEntry)];
|
|
213
|
+
let cacheScope: CacheScope | null = null;
|
|
214
|
+
for (const entry of entries) {
|
|
215
|
+
if (entry.cache) {
|
|
216
|
+
cacheScope = createCacheScope(entry.cache, cacheScope);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return { entries, cacheScope };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Test helper: create a RouteSnapshot with sensible defaults and overrides.
|
|
224
|
+
*/
|
|
225
|
+
export function createRouteSnapshot<TEnv = any>(
|
|
226
|
+
overrides?: Partial<RouteSnapshot<TEnv>>,
|
|
227
|
+
): RouteSnapshot<TEnv> {
|
|
228
|
+
return {
|
|
229
|
+
matched: {
|
|
230
|
+
entry: {} as any,
|
|
231
|
+
routeKey: "test",
|
|
232
|
+
params: {},
|
|
233
|
+
} as RouteMatchResult<TEnv>,
|
|
234
|
+
manifestEntry: { type: "route", shortCode: "R0", parent: null } as any,
|
|
235
|
+
entries: [],
|
|
236
|
+
routeKey: "test",
|
|
237
|
+
localRouteName: "test",
|
|
238
|
+
params: {},
|
|
239
|
+
routeMiddleware: [],
|
|
240
|
+
cacheScope: null,
|
|
241
|
+
isPassthrough: false,
|
|
242
|
+
...overrides,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
@@ -54,10 +54,8 @@ export interface InterceptResult {
|
|
|
54
54
|
* Instead of passing 20+ parameters, middleware calls getRouterContext() to access them.
|
|
55
55
|
*/
|
|
56
56
|
export interface RouterContext<TEnv = any> {
|
|
57
|
-
// Route matching
|
|
58
57
|
findMatch: (pathname: string) => RouteMatchResult | null;
|
|
59
58
|
|
|
60
|
-
// Manifest loading
|
|
61
59
|
loadManifest: (
|
|
62
60
|
entry: any,
|
|
63
61
|
routeKey: string,
|
|
@@ -66,10 +64,8 @@ export interface RouterContext<TEnv = any> {
|
|
|
66
64
|
isSSR?: boolean,
|
|
67
65
|
) => Promise<EntryData>;
|
|
68
66
|
|
|
69
|
-
// Entry traversal
|
|
70
67
|
traverseBack: (entry: EntryData) => Generator<EntryData>;
|
|
71
68
|
|
|
72
|
-
// Handler context creation
|
|
73
69
|
createHandlerContext: (
|
|
74
70
|
params: Record<string, string>,
|
|
75
71
|
request: Request,
|
|
@@ -83,7 +79,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
83
79
|
isPassthroughRoute?: boolean,
|
|
84
80
|
) => HandlerContext<any, TEnv>;
|
|
85
81
|
|
|
86
|
-
// Loader setup
|
|
87
82
|
setupLoaderAccess: (
|
|
88
83
|
ctx: HandlerContext<any, TEnv>,
|
|
89
84
|
loaderPromises: Map<string, Promise<any>>,
|
|
@@ -94,7 +89,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
94
89
|
loaderPromises: Map<string, Promise<any>>,
|
|
95
90
|
) => void;
|
|
96
91
|
|
|
97
|
-
// Context access
|
|
98
92
|
getContext: () => {
|
|
99
93
|
getOrCreateStore: (key: string) => any;
|
|
100
94
|
runWithStore: <T>(
|
|
@@ -105,16 +99,13 @@ export interface RouterContext<TEnv = any> {
|
|
|
105
99
|
) => T;
|
|
106
100
|
};
|
|
107
101
|
|
|
108
|
-
// Metrics
|
|
109
102
|
getMetricsStore: () => MetricsStore | undefined;
|
|
110
103
|
|
|
111
|
-
// Cache
|
|
112
104
|
createCacheScope: (
|
|
113
105
|
cacheConfig: any,
|
|
114
106
|
parent: CacheScope | null,
|
|
115
107
|
) => CacheScope | null;
|
|
116
108
|
|
|
117
|
-
// Intercept detection
|
|
118
109
|
findInterceptForRoute: (
|
|
119
110
|
routeKey: string,
|
|
120
111
|
parentEntry: EntryData | null,
|
|
@@ -122,7 +113,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
122
113
|
isAction: boolean,
|
|
123
114
|
) => InterceptResult | null;
|
|
124
115
|
|
|
125
|
-
// Segment resolution (with revalidation)
|
|
126
116
|
resolveAllSegmentsWithRevalidation: (
|
|
127
117
|
entries: EntryData[],
|
|
128
118
|
routeKey: string,
|
|
@@ -133,7 +123,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
133
123
|
request: Request,
|
|
134
124
|
prevUrl: URL,
|
|
135
125
|
nextUrl: URL,
|
|
136
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
137
126
|
actionContext: any | undefined,
|
|
138
127
|
interceptResult: InterceptResult | null,
|
|
139
128
|
localRouteName: string,
|
|
@@ -166,12 +155,10 @@ export interface RouterContext<TEnv = any> {
|
|
|
166
155
|
revalidationContext?: RevalidationContext,
|
|
167
156
|
) => Promise<ResolvedSegment[]>;
|
|
168
157
|
|
|
169
|
-
// Collect with markers
|
|
170
158
|
collectWithMarkers?: <T>(
|
|
171
159
|
gen: AsyncGenerator<T | { __type: "id"; id: string }>,
|
|
172
160
|
) => Promise<{ items: T[]; matchedIds: string[] }>;
|
|
173
161
|
|
|
174
|
-
// Revalidation evaluation
|
|
175
162
|
evaluateRevalidation: (params: {
|
|
176
163
|
segment: ResolvedSegment;
|
|
177
164
|
prevParams: Record<string, string>;
|
|
@@ -195,7 +182,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
195
182
|
| "intercept-loader";
|
|
196
183
|
}) => Promise<boolean>;
|
|
197
184
|
|
|
198
|
-
// Request context
|
|
199
185
|
getRequestContext: () =>
|
|
200
186
|
| {
|
|
201
187
|
waitUntil: (fn: () => Promise<void>) => void;
|
|
@@ -203,7 +189,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
203
189
|
}
|
|
204
190
|
| undefined;
|
|
205
191
|
|
|
206
|
-
// Simple segment resolution (without revalidation - for full match)
|
|
207
192
|
resolveAllSegments: (
|
|
208
193
|
entries: EntryData[],
|
|
209
194
|
routeKey: string,
|
|
@@ -213,7 +198,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
213
198
|
options?: { skipLoaders?: boolean },
|
|
214
199
|
) => Promise<ResolvedSegment[]>;
|
|
215
200
|
|
|
216
|
-
// Generator-based simple resolution
|
|
217
201
|
resolveAllSegmentsGenerator?: (
|
|
218
202
|
entries: EntryData[],
|
|
219
203
|
routeKey: string,
|
|
@@ -222,21 +206,17 @@ export interface RouterContext<TEnv = any> {
|
|
|
222
206
|
loaderPromises: Map<string, Promise<any>>,
|
|
223
207
|
) => AsyncGenerator<ResolvedSegment | { __type: "id"; id: string }>;
|
|
224
208
|
|
|
225
|
-
// Collect segments from generator
|
|
226
209
|
collectSegmentsFromGenerator?: <T>(
|
|
227
210
|
gen: AsyncGenerator<T | { __type: "id"; id: string }>,
|
|
228
211
|
) => Promise<T[]>;
|
|
229
212
|
|
|
230
|
-
// Handle store
|
|
231
213
|
createHandleStore: () => any;
|
|
232
214
|
|
|
233
|
-
// Loaders-only resolution (for full match cache hit - no revalidation)
|
|
234
215
|
resolveLoadersOnly?: (
|
|
235
216
|
entries: EntryData[],
|
|
236
217
|
handlerContext: HandlerContext<any, TEnv>,
|
|
237
218
|
) => Promise<ResolvedSegment[]>;
|
|
238
219
|
|
|
239
|
-
// Loaders-only resolution (for cache hit scenarios)
|
|
240
220
|
resolveLoadersOnlyWithRevalidation?: (
|
|
241
221
|
entries: EntryData[],
|
|
242
222
|
handlerContext: HandlerContext<any, TEnv>,
|
|
@@ -258,10 +238,8 @@ export interface RouterContext<TEnv = any> {
|
|
|
258
238
|
// Telemetry sink (optional, no-op when undefined)
|
|
259
239
|
telemetry?: TelemetrySink;
|
|
260
240
|
|
|
261
|
-
// Request ID for telemetry span correlation (set per-request in match handlers)
|
|
262
241
|
requestId?: string;
|
|
263
242
|
|
|
264
|
-
// Intercept loaders only (for cache hit + intercept scenarios)
|
|
265
243
|
resolveInterceptLoadersOnly?: (
|
|
266
244
|
intercept: InterceptEntry,
|
|
267
245
|
entry: EntryData,
|
|
@@ -284,7 +262,6 @@ export interface RouterContext<TEnv = any> {
|
|
|
284
262
|
} | null>;
|
|
285
263
|
}
|
|
286
264
|
|
|
287
|
-
// AsyncLocalStorage instance for router context
|
|
288
265
|
const routerContext = new AsyncLocalStorage<RouterContext<any>>();
|
|
289
266
|
|
|
290
267
|
/**
|
|
@@ -308,10 +285,6 @@ export function getRouterContext<TEnv = any>(): RouterContext<TEnv> {
|
|
|
308
285
|
*
|
|
309
286
|
* All async code within fn() can call getRouterContext() to access router closures.
|
|
310
287
|
* This works across async boundaries thanks to AsyncLocalStorage.
|
|
311
|
-
*
|
|
312
|
-
* @param deps Router dependencies to make available
|
|
313
|
-
* @param fn Function to run with dependencies available
|
|
314
|
-
* @returns Result of fn()
|
|
315
288
|
*/
|
|
316
289
|
export function runWithRouterContext<T, TEnv = any>(
|
|
317
290
|
deps: RouterContext<TEnv>,
|
|
@@ -2,17 +2,16 @@ import type { ComponentType, ReactNode } from "react";
|
|
|
2
2
|
import type { SerializedManifest } from "../debug.js";
|
|
3
3
|
import type { ReverseFunction } from "../reverse.js";
|
|
4
4
|
import type { UrlPatterns } from "../urls.js";
|
|
5
|
+
import type { UrlBuilder, EnvCompatible } from "../urls/pattern-types.js";
|
|
5
6
|
import type { EntryData } from "../server/context";
|
|
6
7
|
import type { ErrorInfo, MatchResult } from "../types";
|
|
7
8
|
import type { NonceProvider } from "../rsc/types.js";
|
|
8
9
|
import type { ExecutionContext } from "../server/request-context.js";
|
|
9
|
-
import type {
|
|
10
|
-
SerializedSegmentData,
|
|
11
|
-
SegmentHandleData,
|
|
12
|
-
} from "../cache/types.js";
|
|
10
|
+
import type { SerializedSegmentData } from "../cache/types.js";
|
|
13
11
|
import type { MiddlewareEntry, MiddlewareFn } from "./middleware.js";
|
|
12
|
+
import type { ExtractParams } from "../types/route-config.js";
|
|
14
13
|
import { RSC_ROUTER_BRAND } from "./router-registry.js";
|
|
15
|
-
import type {
|
|
14
|
+
import type { RangoOptions, RootLayoutProps } from "./router-options.js";
|
|
16
15
|
import type { DefaultVars } from "../types/global-namespace.js";
|
|
17
16
|
import type { ResolvedTimeouts, OnTimeoutCallback } from "./timeout.js";
|
|
18
17
|
|
|
@@ -48,16 +47,16 @@ type MergeRoutesWithResponses<
|
|
|
48
47
|
};
|
|
49
48
|
|
|
50
49
|
/**
|
|
51
|
-
* Public
|
|
50
|
+
* Public Rango router interface — the user-facing API surface.
|
|
52
51
|
*
|
|
53
52
|
* Users interact with this type when building and using routers.
|
|
54
|
-
* Internal framework code uses
|
|
53
|
+
* Internal framework code uses RangoInternal (via toInternal()) to access
|
|
55
54
|
* matching, build-time, and configuration members that are not part of the
|
|
56
55
|
* public contract.
|
|
57
56
|
*
|
|
58
57
|
* TRoutes accumulates all registered route types through the builder chain.
|
|
59
58
|
*/
|
|
60
|
-
export interface
|
|
59
|
+
export interface Rango<
|
|
61
60
|
TEnv = any,
|
|
62
61
|
TRoutes extends Record<string, unknown> = Record<string, string>,
|
|
63
62
|
> {
|
|
@@ -68,23 +67,36 @@ export interface RSCRouter<
|
|
|
68
67
|
readonly id: string;
|
|
69
68
|
|
|
70
69
|
/**
|
|
71
|
-
*
|
|
70
|
+
* URL prefix applied to all routes. Undefined when no basename is configured.
|
|
71
|
+
*/
|
|
72
|
+
readonly basename: string | undefined;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Register routes using URL patterns from urls() or a builder function
|
|
72
76
|
*
|
|
73
77
|
* @example
|
|
74
78
|
* ```typescript
|
|
75
|
-
*
|
|
76
|
-
*
|
|
79
|
+
* // With urls()
|
|
80
|
+
* createRouter({}).routes(urlpatterns)
|
|
81
|
+
*
|
|
82
|
+
* // With builder function (urls() is implicit)
|
|
83
|
+
* createRouter({}).routes(({ path, layout }) => [
|
|
84
|
+
* layout(RootLayout, () => [
|
|
85
|
+
* path("/", HomePage),
|
|
86
|
+
* ]),
|
|
87
|
+
* ])
|
|
77
88
|
* ```
|
|
78
89
|
*/
|
|
79
|
-
routes<T extends UrlPatterns<
|
|
80
|
-
patterns: T,
|
|
81
|
-
):
|
|
90
|
+
routes<T extends UrlPatterns<any, any, any>>(
|
|
91
|
+
patterns: T & EnvCompatible<T, TEnv>,
|
|
92
|
+
): Rango<
|
|
82
93
|
TEnv,
|
|
83
94
|
TRoutes &
|
|
84
95
|
(NonNullable<T["_routes"]> extends Record<string, unknown>
|
|
85
96
|
? MergeRoutesWithResponses<NonNullable<T["_routes"]>, T["_responses"]>
|
|
86
97
|
: Record<string, string>)
|
|
87
98
|
>;
|
|
99
|
+
routes(builder: UrlBuilder<TEnv>): Rango<TEnv, TRoutes>;
|
|
88
100
|
|
|
89
101
|
/**
|
|
90
102
|
* Add global middleware that runs on all routes
|
|
@@ -94,13 +106,18 @@ export interface RSCRouter<
|
|
|
94
106
|
* createRouter({ document: RootLayout })
|
|
95
107
|
* .use(loggerMiddleware) // All routes
|
|
96
108
|
* .use("/api/*", rateLimiter) // Pattern match
|
|
109
|
+
* .use("/users/:id", (ctx) => {}) // ctx.params.id is typed
|
|
97
110
|
* .routes(urlpatterns)
|
|
98
111
|
* ```
|
|
99
112
|
*/
|
|
113
|
+
use<Pattern extends string>(
|
|
114
|
+
pattern: Pattern,
|
|
115
|
+
middleware: MiddlewareFn<TEnv, ExtractParams<Pattern>>,
|
|
116
|
+
): Rango<TEnv, TRoutes>;
|
|
100
117
|
use(
|
|
101
118
|
patternOrMiddleware: string | MiddlewareFn<TEnv>,
|
|
102
119
|
middleware?: MiddlewareFn<TEnv>,
|
|
103
|
-
):
|
|
120
|
+
): Rango<TEnv, TRoutes>;
|
|
104
121
|
|
|
105
122
|
/**
|
|
106
123
|
* Type-safe URL builder for registered routes
|
|
@@ -127,7 +144,7 @@ export interface RSCRouter<
|
|
|
127
144
|
* type AppRoutes = typeof _router.routeMap;
|
|
128
145
|
*
|
|
129
146
|
* declare global {
|
|
130
|
-
* namespace
|
|
147
|
+
* namespace Rango {
|
|
131
148
|
* interface RegisteredRoutes extends AppRoutes {}
|
|
132
149
|
* }
|
|
133
150
|
* }
|
|
@@ -163,16 +180,16 @@ export interface RSCRouter<
|
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
/**
|
|
166
|
-
* Internal
|
|
183
|
+
* Internal Rango router interface — the full framework-facing API.
|
|
167
184
|
*
|
|
168
185
|
* This type includes all members used by the Vite plugin, RSC handler,
|
|
169
186
|
* pre-rendering pipeline, and other framework internals. It is NOT exported
|
|
170
187
|
* from the public package API.
|
|
171
188
|
*
|
|
172
|
-
* Use toInternal(router) to assert a public
|
|
189
|
+
* Use toInternal(router) to assert a public Rango into this type
|
|
173
190
|
* at the boundary where framework code receives a user-provided router.
|
|
174
191
|
*/
|
|
175
|
-
export interface
|
|
192
|
+
export interface RangoInternal<
|
|
176
193
|
TEnv = any,
|
|
177
194
|
TRoutes extends Record<string, unknown> = Record<string, string>,
|
|
178
195
|
> {
|
|
@@ -188,26 +205,40 @@ export interface RSCRouterInternal<
|
|
|
188
205
|
*/
|
|
189
206
|
readonly id: string;
|
|
190
207
|
|
|
208
|
+
/** URL prefix applied to all routes. */
|
|
209
|
+
readonly basename: string | undefined;
|
|
210
|
+
|
|
191
211
|
/**
|
|
192
|
-
* Register routes using URL patterns from urls()
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
212
|
+
* Register routes using URL patterns from urls() or a builder function.
|
|
213
|
+
*
|
|
214
|
+
* Env compatibility is checked by EnvCompatible: an env-agnostic urls() block
|
|
215
|
+
* (its env is `unknown` — e.g. a shared module, or an app that does not augment
|
|
216
|
+
* `Rango.Env`) attaches to any router, while a urls<TEnv>() block carrying a
|
|
217
|
+
* concrete env is accepted only when this router's `TEnv` satisfies it. So a
|
|
218
|
+
* `urls<{ DB }>()` cannot be mounted on a `createRouter<{}>()`.
|
|
219
|
+
*/
|
|
220
|
+
routes<T extends UrlPatterns<any, any, any>>(
|
|
221
|
+
patterns: T & EnvCompatible<T, TEnv>,
|
|
222
|
+
): Rango<
|
|
197
223
|
TEnv,
|
|
198
224
|
TRoutes &
|
|
199
225
|
(NonNullable<T["_routes"]> extends Record<string, unknown>
|
|
200
226
|
? MergeRoutesWithResponses<NonNullable<T["_routes"]>, T["_responses"]>
|
|
201
227
|
: Record<string, string>)
|
|
202
228
|
>;
|
|
229
|
+
routes(builder: UrlBuilder<TEnv>): Rango<TEnv, TRoutes>;
|
|
203
230
|
|
|
204
231
|
/**
|
|
205
232
|
* Add global middleware that runs on all routes
|
|
206
233
|
*/
|
|
234
|
+
use<Pattern extends string>(
|
|
235
|
+
pattern: Pattern,
|
|
236
|
+
middleware: MiddlewareFn<TEnv, ExtractParams<Pattern>>,
|
|
237
|
+
): Rango<TEnv, TRoutes>;
|
|
207
238
|
use(
|
|
208
239
|
patternOrMiddleware: string | MiddlewareFn<TEnv>,
|
|
209
240
|
middleware?: MiddlewareFn<TEnv>,
|
|
210
|
-
):
|
|
241
|
+
): Rango<TEnv, TRoutes>;
|
|
211
242
|
|
|
212
243
|
/**
|
|
213
244
|
* Type-safe URL builder for registered routes
|
|
@@ -229,17 +260,17 @@ export interface RSCRouterInternal<
|
|
|
229
260
|
* Error callback for monitoring/alerting
|
|
230
261
|
* Called when errors occur in loaders, actions, or routes
|
|
231
262
|
*/
|
|
232
|
-
readonly onError?:
|
|
263
|
+
readonly onError?: RangoOptions<TEnv>["onError"];
|
|
233
264
|
|
|
234
265
|
/**
|
|
235
266
|
* Cache configuration
|
|
236
267
|
*/
|
|
237
|
-
readonly cache?:
|
|
268
|
+
readonly cache?: RangoOptions<TEnv>["cache"];
|
|
238
269
|
|
|
239
270
|
/**
|
|
240
271
|
* Not found component to render when no route matches
|
|
241
272
|
*/
|
|
242
|
-
readonly notFound?:
|
|
273
|
+
readonly notFound?: RangoOptions<TEnv>["notFound"];
|
|
243
274
|
|
|
244
275
|
/**
|
|
245
276
|
* Resolved theme configuration (null if theme not enabled)
|
|
@@ -269,6 +300,13 @@ export interface RSCRouterInternal<
|
|
|
269
300
|
*/
|
|
270
301
|
readonly prefetchCacheTTL: number;
|
|
271
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Resolved rango state cookie name (`{prefix}_{routerId}`), composed once at
|
|
305
|
+
* router init and shipped to the client in payload metadata. The server-side
|
|
306
|
+
* cookie writer reads it from here; the client reads it from metadata.
|
|
307
|
+
*/
|
|
308
|
+
readonly resolvedStateCookieName: string;
|
|
309
|
+
|
|
272
310
|
/**
|
|
273
311
|
* Whether connection warmup is enabled.
|
|
274
312
|
* When true, the client sends HEAD /?_rsc_warmup after idle periods
|
|
@@ -338,6 +376,20 @@ export interface RSCRouterInternal<
|
|
|
338
376
|
*/
|
|
339
377
|
readonly __sourceFile?: string;
|
|
340
378
|
|
|
379
|
+
/** @internal basename for runtime manifest generation */
|
|
380
|
+
readonly __basename?: string;
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* @internal Router-level error/notFound fallbacks (`createRouter` options),
|
|
384
|
+
* exposed for the build-time clientChunks discovery so a `"use client"`
|
|
385
|
+
* default boundary is routed into the dedicated `app-fallback` chunk. Unlike
|
|
386
|
+
* the route-tree `errorBoundary()`/`notFoundBoundary()` helpers these never
|
|
387
|
+
* land in `EntryData`, so they are read directly off the router instance.
|
|
388
|
+
*/
|
|
389
|
+
readonly __defaultErrorBoundary?: RangoOptions<TEnv>["defaultErrorBoundary"];
|
|
390
|
+
readonly __defaultNotFoundBoundary?: RangoOptions<TEnv>["defaultNotFoundBoundary"];
|
|
391
|
+
readonly __notFound?: RangoOptions<TEnv>["notFound"];
|
|
392
|
+
|
|
341
393
|
match(
|
|
342
394
|
request: Request,
|
|
343
395
|
input?: RouterRequestInput<TEnv>,
|
|
@@ -353,13 +405,17 @@ export interface RSCRouterInternal<
|
|
|
353
405
|
params: Record<string, string>,
|
|
354
406
|
buildVars?: Record<string, any>,
|
|
355
407
|
isPassthroughRoute?: boolean,
|
|
408
|
+
buildEnv?: any,
|
|
409
|
+
devMode?: boolean,
|
|
356
410
|
): Promise<{
|
|
357
411
|
segments: SerializedSegmentData[];
|
|
358
|
-
|
|
412
|
+
/** RSC-encoded handle map ("" when none) — see handle-snapshot.ts. */
|
|
413
|
+
handles: string;
|
|
359
414
|
routeName: string;
|
|
360
415
|
params: Record<string, string>;
|
|
361
416
|
interceptSegments?: SerializedSegmentData[];
|
|
362
|
-
|
|
417
|
+
/** RSC-encoded MERGED (main + intercept) handle map for the intercept artifact. */
|
|
418
|
+
interceptHandles?: string;
|
|
363
419
|
passthrough?: true;
|
|
364
420
|
} | null>;
|
|
365
421
|
|
|
@@ -371,7 +427,9 @@ export interface RSCRouterInternal<
|
|
|
371
427
|
handler: Function,
|
|
372
428
|
handlerId: string,
|
|
373
429
|
routeName?: string,
|
|
374
|
-
|
|
430
|
+
buildEnv?: any,
|
|
431
|
+
devMode?: boolean,
|
|
432
|
+
): Promise<{ encoded: string; handles: string } | null>;
|
|
375
433
|
|
|
376
434
|
/**
|
|
377
435
|
* Preview match - returns route middleware without segment resolution.
|
|
@@ -424,6 +482,13 @@ export interface RSCRouterInternal<
|
|
|
424
482
|
segmentType?: ErrorInfo["segmentType"],
|
|
425
483
|
): Promise<MatchResult | null>;
|
|
426
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Low-level route matching function.
|
|
487
|
+
* Used by classifyRequest() for request classification without
|
|
488
|
+
* entering the full match pipeline.
|
|
489
|
+
*/
|
|
490
|
+
findMatch(pathname: string, metricsStore?: any): any;
|
|
491
|
+
|
|
427
492
|
/**
|
|
428
493
|
* Debug utility to serialize the manifest for inspection
|
|
429
494
|
* Returns a JSON-friendly representation of all routes and layouts
|
|
@@ -437,16 +502,16 @@ export interface RSCRouterInternal<
|
|
|
437
502
|
}
|
|
438
503
|
|
|
439
504
|
/**
|
|
440
|
-
* Assert a public
|
|
505
|
+
* Assert a public Rango into the internal type.
|
|
441
506
|
*
|
|
442
507
|
* Use this at the boundary where framework code receives a user-provided
|
|
443
508
|
* router and needs access to internal members (match, config, build-time).
|
|
444
509
|
* The cast is safe because createRouter() always produces an object that
|
|
445
|
-
* satisfies
|
|
510
|
+
* satisfies RangoInternal; the public type is just a narrower view.
|
|
446
511
|
*/
|
|
447
512
|
export function toInternal<
|
|
448
513
|
TEnv = any,
|
|
449
514
|
TRoutes extends Record<string, unknown> = Record<string, string>,
|
|
450
|
-
>(router:
|
|
451
|
-
return router as
|
|
515
|
+
>(router: Rango<TEnv, TRoutes>): RangoInternal<TEnv, TRoutes> {
|
|
516
|
+
return router as RangoInternal<TEnv, TRoutes>;
|
|
452
517
|
}
|