@rangojs/router 0.0.0-experimental.135c6902 → 0.0.0-experimental.136
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 +8 -0
- package/README.md +245 -49
- package/dist/bin/rango.js +440 -133
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3386 -1111
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +78 -25
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +64 -2
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +247 -23
- package/skills/caching/SKILL.md +281 -11
- package/skills/composability/SKILL.md +27 -3
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +4 -2
- 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 +83 -23
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +87 -18
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +289 -53
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +914 -0
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +144 -7
- package/skills/prerender/SKILL.md +172 -125
- package/skills/rango/SKILL.md +251 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +123 -48
- package/skills/route/SKILL.md +101 -5
- package/skills/router-setup/SKILL.md +117 -10
- package/skills/scripts/SKILL.md +179 -0
- 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 +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -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 +122 -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 +123 -0
- package/skills/typesafety/SKILL.md +332 -29
- package/skills/use-cache/SKILL.md +57 -14
- package/skills/view-transitions/SKILL.md +337 -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/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +192 -150
- 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 +131 -30
- package/src/browser/navigation-client.ts +199 -86
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +157 -74
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +174 -109
- package/src/browser/prefetch/cache.ts +222 -69
- package/src/browser/prefetch/fetch.ts +347 -39
- package/src/browser/prefetch/queue.ts +113 -32
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +102 -15
- package/src/browser/react/NavigationProvider.tsx +300 -122
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/deferred-handle-resolution.ts +75 -0
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -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-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- 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 +99 -8
- package/src/browser/rsc-router.tsx +125 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +222 -61
- package/src/browser/types.ts +115 -12
- 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 +5 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +165 -36
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +125 -24
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +260 -94
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +29 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +239 -52
- package/src/cache/cache-scope.ts +234 -87
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +1989 -378
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +89 -21
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +10 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +9 -17
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +37 -100
- package/src/client.rsc.tsx +44 -21
- package/src/client.tsx +119 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +84 -2
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +62 -19
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +37 -8
- package/src/handles/is-thenable.ts +19 -0
- package/src/handles/meta.ts +51 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +23 -52
- 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 +99 -13
- package/src/index.ts +139 -19
- package/src/internal-debug.ts +11 -10
- 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/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +461 -304
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +149 -74
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +51 -10
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +0 -16
- package/src/route-types.ts +37 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +44 -23
- package/src/router/handler-context.ts +83 -39
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +48 -24
- package/src/router/lazy-includes.ts +15 -52
- package/src/router/loader-resolution.ts +274 -56
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +40 -42
- package/src/router/match-api.ts +124 -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 +54 -25
- package/src/router/match-middleware/cache-lookup.ts +205 -271
- package/src/router/match-middleware/cache-store.ts +81 -50
- 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 +93 -39
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +268 -171
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +132 -90
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +195 -56
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +3 -27
- package/src/router/router-interfaces.ts +129 -35
- package/src/router/router-options.ts +202 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +197 -92
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +76 -39
- package/src/router/segment-resolution/revalidation.ts +392 -338
- 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 +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +161 -199
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +163 -59
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +174 -54
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +660 -518
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +127 -31
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +133 -13
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +115 -73
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +287 -113
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +36 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +269 -202
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +235 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +38 -46
- package/src/server/request-context.ts +442 -173
- package/src/ssr/index.tsx +24 -16
- 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 +701 -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 +257 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -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 +357 -0
- package/src/testing/render-route.tsx +581 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -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 +20 -58
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- 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 +234 -82
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +12 -7
- package/src/types/segments.ts +136 -15
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +68 -18
- 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 -19
- 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 +214 -132
- 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 +57 -4
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +6 -0
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +178 -5
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- 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 +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +553 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +39 -25
- package/src/vite/rango.ts +119 -111
- package/src/vite/router-discovery.ts +941 -142
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- 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/directive-prologue.ts +40 -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 +81 -34
- package/src/vite/utils/shared-utils.ts +92 -42
- package/src/browser/action-response-classifier.ts +0 -99
- 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/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL param encode/decode at the route boundary.
|
|
3
|
+
*
|
|
4
|
+
* Extraction (decode): regex/trie matchers keep param values URL-encoded;
|
|
5
|
+
* `safeDecodeURIComponent` turns them back into raw strings so `ctx.params`
|
|
6
|
+
* matches the contract apps expect (Express/React Router/Fastify/Koa) and
|
|
7
|
+
* round-trips through reverse stay stable. Malformed %-encoding is
|
|
8
|
+
* preserved as-is so a broken URL doesn't crash matching.
|
|
9
|
+
*
|
|
10
|
+
* Reversal (encode): `encodePathSegment` escapes only what RFC 3986
|
|
11
|
+
* requires for a path segment — `/`, `?`, `#`, space, control chars,
|
|
12
|
+
* non-ASCII — and leaves pchar sub-delims (`@ : $ & + , ; =` and friends)
|
|
13
|
+
* readable. `encodeURIComponent` over-encodes for path segments, which
|
|
14
|
+
* makes generated URLs harder for humans to read in the address bar
|
|
15
|
+
* (e.g. mailbox IDs like `ivo@example.com` would become
|
|
16
|
+
* `ivo%40example.com` even though `@` is path-legal).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export function safeDecodeURIComponent(raw: string): string {
|
|
20
|
+
if (raw === "" || raw.indexOf("%") === -1) return raw;
|
|
21
|
+
try {
|
|
22
|
+
return decodeURIComponent(raw);
|
|
23
|
+
} catch {
|
|
24
|
+
return raw;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const PATH_SAFE_ESCAPES: Record<string, string> = {
|
|
29
|
+
"%3A": ":",
|
|
30
|
+
"%40": "@",
|
|
31
|
+
"%24": "$",
|
|
32
|
+
"%26": "&",
|
|
33
|
+
"%2B": "+",
|
|
34
|
+
"%2C": ",",
|
|
35
|
+
"%3B": ";",
|
|
36
|
+
"%3D": "=",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function encodePathSegment(value: string): string {
|
|
40
|
+
return encodeURIComponent(value).replace(
|
|
41
|
+
/%(?:3A|40|24|26|2B|2C|3B|3D)/gi,
|
|
42
|
+
(match) => PATH_SAFE_ESCAPES[match.toUpperCase()] ?? match,
|
|
43
|
+
);
|
|
44
|
+
}
|
package/src/router.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { createCacheScope } from "./cache/cache-scope.js";
|
|
3
|
-
import {
|
|
4
|
-
setCacheProfiles,
|
|
5
|
-
resolveCacheProfiles,
|
|
6
|
-
} from "./cache/profile-registry.js";
|
|
3
|
+
import { resolveCacheProfiles } from "./cache/profile-registry.js";
|
|
7
4
|
import { isCachedFunction } from "./cache/taint.js";
|
|
8
5
|
import { assertClientComponent } from "./component-utils.js";
|
|
9
6
|
import { DefaultDocument } from "./components/DefaultDocument.js";
|
|
@@ -19,11 +16,13 @@ import {
|
|
|
19
16
|
import MapRootLayout from "./server/root-layout.js";
|
|
20
17
|
import type { AllUseItems } from "./route-types.js";
|
|
21
18
|
import type { UrlPatterns } from "./urls.js";
|
|
19
|
+
import type { UrlBuilder } from "./urls/pattern-types.js";
|
|
20
|
+
import { urls } from "./urls.js";
|
|
21
|
+
import { buildPrecomputedByPrefix } from "./build/prefix-tree-utils.js";
|
|
22
22
|
import {
|
|
23
|
-
EntryData,
|
|
24
|
-
InterceptSelectorContext,
|
|
23
|
+
type EntryData,
|
|
25
24
|
getContext,
|
|
26
|
-
|
|
25
|
+
RangoContext,
|
|
27
26
|
type MetricsStore,
|
|
28
27
|
} from "./server/context";
|
|
29
28
|
import { createHandleStore, type HandleStore } from "./server/handle-store.js";
|
|
@@ -55,6 +54,7 @@ import { buildDebugManifest } from "./router/debug-manifest.js";
|
|
|
55
54
|
|
|
56
55
|
import type { SegmentResolutionDeps, MatchApiDeps } from "./router/types.js";
|
|
57
56
|
import { createHandlerContext } from "./router/handler-context.js";
|
|
57
|
+
import { normalizeBasename } from "./router/basename.js";
|
|
58
58
|
import {
|
|
59
59
|
setupLoaderAccess,
|
|
60
60
|
setupLoaderAccessSilent,
|
|
@@ -63,15 +63,17 @@ import {
|
|
|
63
63
|
import { loadManifest } from "./router/manifest.js";
|
|
64
64
|
import { createMetricsStore } from "./router/metrics.js";
|
|
65
65
|
import {
|
|
66
|
-
|
|
66
|
+
compileMiddlewarePattern,
|
|
67
67
|
type MiddlewareEntry,
|
|
68
68
|
type MiddlewareFn,
|
|
69
69
|
} from "./router/middleware.js";
|
|
70
70
|
import {
|
|
71
71
|
extractStaticPrefix,
|
|
72
|
+
joinPrefix,
|
|
72
73
|
traverseBack,
|
|
73
74
|
} from "./router/pattern-matching.js";
|
|
74
75
|
import { resolveSink, safeEmit, getRequestId } from "./router/telemetry.js";
|
|
76
|
+
import { resolveTracing } from "./router/tracing.js";
|
|
75
77
|
import { evaluateRevalidation } from "./router/revalidation.js";
|
|
76
78
|
import {
|
|
77
79
|
type RouterContext,
|
|
@@ -89,13 +91,10 @@ import {
|
|
|
89
91
|
RouterRegistry,
|
|
90
92
|
nextRouterAutoId,
|
|
91
93
|
} from "./router/router-registry.js";
|
|
94
|
+
import type { RangoOptions, RootLayoutProps } from "./router/router-options.js";
|
|
92
95
|
import type {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
} from "./router/router-options.js";
|
|
96
|
-
import type {
|
|
97
|
-
RSCRouter,
|
|
98
|
-
RSCRouterInternal,
|
|
96
|
+
Rango,
|
|
97
|
+
RangoInternal,
|
|
99
98
|
RouterRequestInput,
|
|
100
99
|
} from "./router/router-interfaces.js";
|
|
101
100
|
|
|
@@ -110,29 +109,36 @@ import {
|
|
|
110
109
|
matchForPrerender as _matchForPrerender,
|
|
111
110
|
renderStaticSegment as _renderStaticSegment,
|
|
112
111
|
} from "./router/prerender-match.js";
|
|
112
|
+
import { resolveStateCookieName } from "./router/state-cookie-name.js";
|
|
113
|
+
import { resolvePrefetchCacheTTL } from "./router/prefetch-cache-ttl.js";
|
|
114
|
+
import {
|
|
115
|
+
resolvePrefetchCacheSize,
|
|
116
|
+
resolvePrefetchConcurrency,
|
|
117
|
+
} from "./router/prefetch-limits.js";
|
|
113
118
|
|
|
114
119
|
// Re-export public types and values from extracted modules
|
|
115
120
|
export { RSC_ROUTER_BRAND, RouterRegistry } from "./router/router-registry.js";
|
|
116
121
|
export type {
|
|
117
|
-
|
|
122
|
+
RangoOptions,
|
|
118
123
|
RootLayoutProps,
|
|
119
124
|
SSRStreamMode,
|
|
120
125
|
SSROptions,
|
|
121
126
|
ResolveStreamingContext,
|
|
122
127
|
} from "./router/router-options.js";
|
|
123
128
|
export type {
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
Rango,
|
|
130
|
+
RangoInternal,
|
|
126
131
|
RouterRequestInput,
|
|
127
132
|
} from "./router/router-interfaces.js";
|
|
128
133
|
export { toInternal } from "./router/router-interfaces.js";
|
|
129
134
|
|
|
130
135
|
export function createRouter<TEnv = any>(
|
|
131
|
-
options:
|
|
132
|
-
):
|
|
136
|
+
options: RangoOptions<TEnv> = {},
|
|
137
|
+
): Rango<TEnv, {}> {
|
|
133
138
|
const {
|
|
134
139
|
id: userProvidedId,
|
|
135
140
|
$$id: injectedId,
|
|
141
|
+
basename: basenameOption,
|
|
136
142
|
debugPerformance = false,
|
|
137
143
|
document: documentOption,
|
|
138
144
|
defaultErrorBoundary,
|
|
@@ -148,24 +154,48 @@ export function createRouter<TEnv = any>(
|
|
|
148
154
|
nonce,
|
|
149
155
|
version,
|
|
150
156
|
prefetchCacheTTL: prefetchCacheTTLOption,
|
|
157
|
+
prefetchCacheSize: prefetchCacheSizeOption,
|
|
158
|
+
prefetchConcurrency: prefetchConcurrencyOption,
|
|
159
|
+
stateCookiePrefix: stateCookiePrefixOption,
|
|
151
160
|
warmup: warmupOption,
|
|
152
161
|
allowDebugManifest: allowDebugManifestOption = false,
|
|
153
162
|
telemetry: telemetrySink,
|
|
163
|
+
tracing: tracingOption,
|
|
154
164
|
ssr: ssrOption,
|
|
155
165
|
timeout: timeoutShorthand,
|
|
156
166
|
timeouts: timeoutsOption,
|
|
157
167
|
onTimeout,
|
|
158
168
|
originCheck: originCheckOption,
|
|
169
|
+
viewTransition: viewTransitionOption = "auto",
|
|
170
|
+
debugCacheSignal: debugCacheSignalOption = false,
|
|
171
|
+
strictMode: strictModeOption = true,
|
|
159
172
|
} = options;
|
|
160
173
|
|
|
174
|
+
// Debug cache signal gate (DEVELOPMENT/TEST ONLY). Enabled by the
|
|
175
|
+
// debugCacheSignal option OR the RANGO_TEST_SIGNALS=1 env flag. When off,
|
|
176
|
+
// no X-Rango-Cache header is emitted and output is byte-identical.
|
|
177
|
+
const cacheSignalEnabled =
|
|
178
|
+
debugCacheSignalOption ||
|
|
179
|
+
(typeof process !== "undefined" &&
|
|
180
|
+
(process as { env?: Record<string, string | undefined> }).env
|
|
181
|
+
?.RANGO_TEST_SIGNALS === "1");
|
|
182
|
+
|
|
183
|
+
// Normalize basename: ensure leading slash, strip trailing slash.
|
|
184
|
+
// A bare "/" is equivalent to no basename. Shared with the testing
|
|
185
|
+
// primitives via normalizeBasename so they can never drift.
|
|
186
|
+
const basename = normalizeBasename(basenameOption);
|
|
187
|
+
|
|
161
188
|
// Resolve telemetry sink (no-op when not configured)
|
|
162
189
|
const telemetry = resolveSink(telemetrySink);
|
|
163
190
|
|
|
164
|
-
// Resolve
|
|
165
|
-
//
|
|
166
|
-
|
|
191
|
+
// Resolve span tracing (undefined when not configured; every traceSpan() call
|
|
192
|
+
// is then a direct pass-through with zero behavior change).
|
|
193
|
+
const resolvedTracing = resolveTracing(tracingOption);
|
|
194
|
+
|
|
195
|
+
// Resolve cache profiles: merge user config with the guaranteed default
|
|
196
|
+
// profile. This resolved map is threaded onto each request context; the
|
|
197
|
+
// "use cache: <profile>" runtime path reads it request-scoped.
|
|
167
198
|
const resolvedCacheProfiles = resolveCacheProfiles(cacheProfilesOption);
|
|
168
|
-
setCacheProfiles(resolvedCacheProfiles);
|
|
169
199
|
|
|
170
200
|
// Source file: prefer Vite-injected path (zero cost), fall back to
|
|
171
201
|
// stack trace parsing for non-Vite environments (e.g. tests).
|
|
@@ -200,21 +230,40 @@ export function createRouter<TEnv = any>(
|
|
|
200
230
|
const routerId =
|
|
201
231
|
userProvidedId ?? injectedId ?? `router_${nextRouterAutoId()}`;
|
|
202
232
|
|
|
203
|
-
// Resolve
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
233
|
+
// Resolve the rango state cookie name once, here, so the two cookie writers
|
|
234
|
+
// (the client document.cookie writer and the server Set-Cookie writer)
|
|
235
|
+
// consume one pre-composed name and cannot drift.
|
|
236
|
+
const resolvedStateCookieName = resolveStateCookieName(
|
|
237
|
+
stateCookiePrefixOption,
|
|
238
|
+
routerId,
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// Resolve prefetch cache TTL (default: 300 seconds / 5 minutes). Clamps to a
|
|
242
|
+
// non-negative integer and guards non-finite (NaN/Infinity) inputs so a
|
|
243
|
+
// malformed `Cache-Control: max-age=NaN` can never reach the wire.
|
|
244
|
+
const resolvedPrefetchCacheTTL = resolvePrefetchCacheTTL(
|
|
245
|
+
prefetchCacheTTLOption,
|
|
246
|
+
);
|
|
247
|
+
const prefetchCacheTTL = resolvedPrefetchCacheTTL.ms;
|
|
210
248
|
const prefetchCacheControl: string | false =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
249
|
+
resolvedPrefetchCacheTTL.cacheControl;
|
|
250
|
+
|
|
251
|
+
// Resolve client-side prefetch limits (in-memory cache size and queue
|
|
252
|
+
// concurrency). Both are positive-integer counts; sub-1/non-finite inputs
|
|
253
|
+
// fall back to the defaults. Shipped to the client in payload metadata.
|
|
254
|
+
const prefetchCacheSize = resolvePrefetchCacheSize(prefetchCacheSizeOption);
|
|
255
|
+
const prefetchConcurrency = resolvePrefetchConcurrency(
|
|
256
|
+
prefetchConcurrencyOption,
|
|
257
|
+
);
|
|
214
258
|
|
|
215
259
|
// Resolve warmup enabled flag (default: true)
|
|
216
260
|
const warmupEnabled = warmupOption !== false;
|
|
217
261
|
|
|
262
|
+
// Resolve StrictMode flag (default: true). Shipped to the client in payload
|
|
263
|
+
// metadata; the browser entry reads it once to decide whether to wrap the
|
|
264
|
+
// hydrated tree in React.StrictMode.
|
|
265
|
+
const strictMode = strictModeOption !== false;
|
|
266
|
+
|
|
218
267
|
// Resolve theme config (null if theme not enabled)
|
|
219
268
|
const resolvedThemeConfig = themeOption
|
|
220
269
|
? resolveThemeConfig(themeOption)
|
|
@@ -246,9 +295,14 @@ export function createRouter<TEnv = any>(
|
|
|
246
295
|
invokeOnError(onError, error, phase, context, "Router");
|
|
247
296
|
}
|
|
248
297
|
|
|
249
|
-
// Validate document is a client component
|
|
298
|
+
// Validate document is a client component. Under a test runner the "use
|
|
299
|
+
// client" transform has not run, so a real exported document has no marker;
|
|
300
|
+
// allowServerInTest lets the router construct in a bare unit test (for
|
|
301
|
+
// dispatch / assertGeneratedRoutesMatch) while a real build still throws.
|
|
250
302
|
if (documentOption !== undefined) {
|
|
251
|
-
assertClientComponent(documentOption, "document"
|
|
303
|
+
assertClientComponent(documentOption, "document", {
|
|
304
|
+
allowServerInTest: true,
|
|
305
|
+
});
|
|
252
306
|
}
|
|
253
307
|
|
|
254
308
|
// Use default document if none provided (keeps internal name as rootLayout)
|
|
@@ -312,7 +366,7 @@ export function createRouter<TEnv = any>(
|
|
|
312
366
|
let regex: RegExp | null = null;
|
|
313
367
|
let paramNames: string[] = [];
|
|
314
368
|
if (fullPattern) {
|
|
315
|
-
const parsed =
|
|
369
|
+
const parsed = compileMiddlewarePattern(fullPattern);
|
|
316
370
|
regex = parsed.regex;
|
|
317
371
|
paramNames = parsed.paramNames;
|
|
318
372
|
}
|
|
@@ -322,7 +376,6 @@ export function createRouter<TEnv = any>(
|
|
|
322
376
|
regex,
|
|
323
377
|
paramNames,
|
|
324
378
|
handler,
|
|
325
|
-
mountPrefix,
|
|
326
379
|
});
|
|
327
380
|
}
|
|
328
381
|
|
|
@@ -356,9 +409,11 @@ export function createRouter<TEnv = any>(
|
|
|
356
409
|
getRouterPrecomputedEntries(routerId) ?? getPrecomputedEntries();
|
|
357
410
|
if (current !== precomputedSource) {
|
|
358
411
|
precomputedSource = current;
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
412
|
+
// buildPrecomputedByPrefix drops any staticPrefix owned by more than one
|
|
413
|
+
// leaf include instead of collapsing it last-wins (which would mis-assign
|
|
414
|
+
// one include's routes to another's entry and 500 a valid sibling route).
|
|
415
|
+
// Such shared-prefix includes resolve via the handler path instead.
|
|
416
|
+
precomputedByPrefix = current ? buildPrecomputedByPrefix(current) : null;
|
|
362
417
|
}
|
|
363
418
|
return precomputedByPrefix;
|
|
364
419
|
}
|
|
@@ -526,7 +581,9 @@ export function createRouter<TEnv = any>(
|
|
|
526
581
|
trackHandler,
|
|
527
582
|
findNearestErrorBoundary,
|
|
528
583
|
findNearestNotFoundBoundary,
|
|
584
|
+
notFoundComponent: notFound,
|
|
529
585
|
callOnError,
|
|
586
|
+
viewTransitionDefault: viewTransitionOption,
|
|
530
587
|
};
|
|
531
588
|
|
|
532
589
|
// Match API dependencies
|
|
@@ -614,6 +671,8 @@ export function createRouter<TEnv = any>(
|
|
|
614
671
|
params: Record<string, string>,
|
|
615
672
|
buildVars?: Record<string, any>,
|
|
616
673
|
isPassthroughRoute?: boolean,
|
|
674
|
+
buildEnv?: TEnv,
|
|
675
|
+
devMode?: boolean,
|
|
617
676
|
) {
|
|
618
677
|
return _matchForPrerender(
|
|
619
678
|
pathname,
|
|
@@ -621,6 +680,8 @@ export function createRouter<TEnv = any>(
|
|
|
621
680
|
prerenderDeps,
|
|
622
681
|
buildVars,
|
|
623
682
|
isPassthroughRoute,
|
|
683
|
+
buildEnv,
|
|
684
|
+
devMode,
|
|
624
685
|
);
|
|
625
686
|
}
|
|
626
687
|
|
|
@@ -628,12 +689,16 @@ export function createRouter<TEnv = any>(
|
|
|
628
689
|
handler: Function,
|
|
629
690
|
handlerId: string,
|
|
630
691
|
routeName?: string,
|
|
692
|
+
buildEnv?: TEnv,
|
|
693
|
+
devMode?: boolean,
|
|
631
694
|
) {
|
|
632
695
|
return _renderStaticSegment<TEnv>(
|
|
633
696
|
handler,
|
|
634
697
|
handlerId,
|
|
635
698
|
mergedRouteMap,
|
|
636
699
|
routeName,
|
|
700
|
+
buildEnv,
|
|
701
|
+
devMode,
|
|
637
702
|
);
|
|
638
703
|
}
|
|
639
704
|
|
|
@@ -646,6 +711,7 @@ export function createRouter<TEnv = any>(
|
|
|
646
711
|
findMatch,
|
|
647
712
|
findInterceptForRoute,
|
|
648
713
|
telemetry: telemetrySink,
|
|
714
|
+
cacheSignalEnabled,
|
|
649
715
|
});
|
|
650
716
|
|
|
651
717
|
const { match, matchPartial, matchError, previewMatch } = matchHandlers;
|
|
@@ -655,11 +721,18 @@ export function createRouter<TEnv = any>(
|
|
|
655
721
|
* The type system tracks accumulated routes through the builder chain
|
|
656
722
|
* Initial TRoutes is {} (empty) to avoid poisoning accumulated types with Record<string, string>
|
|
657
723
|
*/
|
|
658
|
-
const router:
|
|
724
|
+
const router: RangoInternal<TEnv, {}> = {
|
|
659
725
|
__brand: RSC_ROUTER_BRAND,
|
|
660
726
|
id: routerId,
|
|
727
|
+
basename,
|
|
728
|
+
|
|
729
|
+
routes(patternsOrBuilder: UrlPatterns<TEnv> | UrlBuilder<TEnv>): any {
|
|
730
|
+
// Wrap builder functions in urls() automatically
|
|
731
|
+
const urlPatterns: UrlPatterns<TEnv> =
|
|
732
|
+
typeof patternsOrBuilder === "function"
|
|
733
|
+
? (urls(patternsOrBuilder) as UrlPatterns<TEnv>)
|
|
734
|
+
: patternsOrBuilder;
|
|
661
735
|
|
|
662
|
-
routes(urlPatterns: UrlPatterns<TEnv>): any {
|
|
663
736
|
// Store reference for runtime manifest generation
|
|
664
737
|
storedUrlPatterns = urlPatterns;
|
|
665
738
|
const currentMountIndex = mountIndex++;
|
|
@@ -696,7 +769,7 @@ export function createRouter<TEnv = any>(
|
|
|
696
769
|
};
|
|
697
770
|
|
|
698
771
|
let handlerResult: AllUseItems[] = [];
|
|
699
|
-
|
|
772
|
+
RangoContext.run(
|
|
700
773
|
{
|
|
701
774
|
manifest,
|
|
702
775
|
patterns: routePatterns,
|
|
@@ -707,6 +780,10 @@ export function createRouter<TEnv = any>(
|
|
|
707
780
|
counters: {},
|
|
708
781
|
mountIndex: currentMountIndex,
|
|
709
782
|
cacheProfiles: resolvedCacheProfiles,
|
|
783
|
+
// basename sets the initial URL prefix so all path() patterns
|
|
784
|
+
// are registered with the prefix (e.g. "/admin" + "/users" = "/admin/users").
|
|
785
|
+
// No namePrefix — route names stay unprefixed.
|
|
786
|
+
...(basename ? { urlPrefix: basename } : {}),
|
|
710
787
|
},
|
|
711
788
|
() => {
|
|
712
789
|
handlerResult = urlPatterns.handler() as AllUseItems[];
|
|
@@ -726,7 +803,7 @@ export function createRouter<TEnv = any>(
|
|
|
726
803
|
if (entry.type === "route" && entry.isPrerender) {
|
|
727
804
|
if (!prerenderRouteKeys) prerenderRouteKeys = new Set();
|
|
728
805
|
prerenderRouteKeys.add(name);
|
|
729
|
-
if (entry.
|
|
806
|
+
if (entry.isPassthrough === true) {
|
|
730
807
|
if (!passthroughRouteKeys) passthroughRouteKeys = new Set();
|
|
731
808
|
passthroughRouteKeys.add(name);
|
|
732
809
|
}
|
|
@@ -804,10 +881,13 @@ export function createRouter<TEnv = any>(
|
|
|
804
881
|
|
|
805
882
|
// Create placeholder RouteEntry for each lazy include
|
|
806
883
|
for (const lazyInclude of lazyIncludes) {
|
|
807
|
-
// Compute the full URL prefix (combining parent prefix if any)
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
884
|
+
// Compute the full URL prefix (combining parent prefix if any). Use the
|
|
885
|
+
// slash-collapsing join so a trailing-slash parent prefix does not
|
|
886
|
+
// produce a double-slash staticPrefix the trie's sp can never match.
|
|
887
|
+
const fullPrefix = joinPrefix(
|
|
888
|
+
lazyInclude.context.urlPrefix,
|
|
889
|
+
lazyInclude.prefix,
|
|
890
|
+
);
|
|
811
891
|
|
|
812
892
|
const lazyEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
|
|
813
893
|
prefix: "",
|
|
@@ -855,8 +935,18 @@ export function createRouter<TEnv = any>(
|
|
|
855
935
|
patternOrMiddleware: string | MiddlewareFn<TEnv>,
|
|
856
936
|
middleware?: MiddlewareFn<TEnv>,
|
|
857
937
|
): any {
|
|
858
|
-
//
|
|
859
|
-
|
|
938
|
+
// Auto-prefix pattern with basename so router-level middleware
|
|
939
|
+
// patterns are router-relative (e.g. "/users/*" matches "/app/users/*").
|
|
940
|
+
if (basename && typeof patternOrMiddleware === "string") {
|
|
941
|
+
const pattern = patternOrMiddleware;
|
|
942
|
+
const prefixed =
|
|
943
|
+
pattern === "/*" || pattern === "*"
|
|
944
|
+
? `${basename}/*`
|
|
945
|
+
: `${basename}${pattern}`;
|
|
946
|
+
addMiddleware(prefixed, middleware, null);
|
|
947
|
+
} else {
|
|
948
|
+
addMiddleware(patternOrMiddleware, middleware, null);
|
|
949
|
+
}
|
|
860
950
|
return router;
|
|
861
951
|
},
|
|
862
952
|
|
|
@@ -892,13 +982,25 @@ export function createRouter<TEnv = any>(
|
|
|
892
982
|
// Expose prefetch cache settings
|
|
893
983
|
prefetchCacheControl,
|
|
894
984
|
prefetchCacheTTL,
|
|
985
|
+
prefetchCacheSize,
|
|
986
|
+
prefetchConcurrency,
|
|
987
|
+
|
|
988
|
+
// Expose the resolved rango state cookie name for the server-side writer
|
|
989
|
+
// (invalidateClientCache) and for shipping to the client in metadata.
|
|
990
|
+
resolvedStateCookieName,
|
|
895
991
|
|
|
896
992
|
// Expose warmup enabled flag for handler and client
|
|
897
993
|
warmupEnabled,
|
|
898
994
|
|
|
995
|
+
// Expose StrictMode flag for the initial-render payload metadata
|
|
996
|
+
strictMode,
|
|
997
|
+
|
|
899
998
|
// Expose router-wide performance debugging for request-level metrics setup
|
|
900
999
|
debugPerformance,
|
|
901
1000
|
|
|
1001
|
+
// Expose resolved span tracing for the handler (Cloudflare custom spans)
|
|
1002
|
+
tracing: resolvedTracing,
|
|
1003
|
+
|
|
902
1004
|
// Expose debug manifest flag for handler
|
|
903
1005
|
allowDebugManifest: allowDebugManifestOption,
|
|
904
1006
|
|
|
@@ -957,6 +1059,16 @@ export function createRouter<TEnv = any>(
|
|
|
957
1059
|
// Expose source file for per-router type generation
|
|
958
1060
|
__sourceFile,
|
|
959
1061
|
|
|
1062
|
+
// Expose basename for runtime manifest generation
|
|
1063
|
+
__basename: basename,
|
|
1064
|
+
|
|
1065
|
+
// Expose router-level boundary defaults for build-time clientChunks
|
|
1066
|
+
// discovery (so a "use client" default boundary lands in app-fallback).
|
|
1067
|
+
// These are createRouter options, never pushed onto EntryData.
|
|
1068
|
+
__defaultErrorBoundary: defaultErrorBoundary,
|
|
1069
|
+
__defaultNotFoundBoundary: defaultNotFoundBoundary,
|
|
1070
|
+
__notFound: notFound,
|
|
1071
|
+
|
|
960
1072
|
// RSC request handler (lazily created on first call)
|
|
961
1073
|
fetch: (() => {
|
|
962
1074
|
// Handler is created on first call and reused
|
|
@@ -974,8 +1086,10 @@ export function createRouter<TEnv = any>(
|
|
|
974
1086
|
if (!handler) {
|
|
975
1087
|
// Lazy import deferred to first request to avoid dev mode issues
|
|
976
1088
|
const { createRSCHandler } = await import("./rsc/handler.js");
|
|
977
|
-
// Cast:
|
|
978
|
-
//
|
|
1089
|
+
// Cast: createRSCHandler receives `router as any`, which erases TEnv
|
|
1090
|
+
// and infers its handler as RouterRequestInput<unknown>. Re-narrow the
|
|
1091
|
+
// returned handler to RouterRequestInput<TEnv> so the call below stays
|
|
1092
|
+
// typed. (The handler already accepts (request, RouterRequestInput).)
|
|
979
1093
|
handler = createRSCHandler({
|
|
980
1094
|
router: router as any,
|
|
981
1095
|
cache,
|
|
@@ -990,6 +1104,10 @@ export function createRouter<TEnv = any>(
|
|
|
990
1104
|
};
|
|
991
1105
|
})(),
|
|
992
1106
|
|
|
1107
|
+
// Low-level route matching for request classification
|
|
1108
|
+
findMatch: (pathname: string, metricsStore?: any) =>
|
|
1109
|
+
findMatch(pathname, metricsStore),
|
|
1110
|
+
|
|
993
1111
|
// Debug utility for manifest inspection
|
|
994
1112
|
debugManifest: () => buildDebugManifest<TEnv>(routesEntries),
|
|
995
1113
|
};
|
|
@@ -998,8 +1116,10 @@ export function createRouter<TEnv = any>(
|
|
|
998
1116
|
RouterRegistry.set(routerId, router);
|
|
999
1117
|
|
|
1000
1118
|
// If urls option was provided, auto-register them
|
|
1001
|
-
if (urlsOption) {
|
|
1002
|
-
return router.routes(urlsOption) as
|
|
1119
|
+
if (typeof urlsOption === "function") {
|
|
1120
|
+
return router.routes(urlsOption) as Rango<TEnv, {}>;
|
|
1121
|
+
} else if (urlsOption) {
|
|
1122
|
+
return router.routes(urlsOption) as Rango<TEnv, {}>;
|
|
1003
1123
|
}
|
|
1004
1124
|
|
|
1005
1125
|
return router;
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
* RSC rendering) so they can be standalone modules without closure coupling.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { RangoInternal } from "../router/router-interfaces.js";
|
|
10
10
|
import type { ErrorPhase } from "../types.js";
|
|
11
11
|
import type { InvokeOnErrorContext } from "../router/error-handling.js";
|
|
12
12
|
import type { RSCDependencies, LoadSSRModule } from "./types.js";
|
|
13
13
|
import type { SSRStreamMode } from "../router/router-options.js";
|
|
14
14
|
|
|
15
15
|
export interface HandlerContext<TEnv = unknown> {
|
|
16
|
-
router:
|
|
16
|
+
router: RangoInternal<TEnv, any>;
|
|
17
17
|
version: string;
|
|
18
18
|
renderToReadableStream: RSCDependencies["renderToReadableStream"];
|
|
19
19
|
decodeReply: RSCDependencies["decodeReply"];
|
|
@@ -31,6 +31,7 @@ export interface HandlerContext<TEnv = unknown> {
|
|
|
31
31
|
createRedirectFlightResponse: (
|
|
32
32
|
redirectUrl: string,
|
|
33
33
|
locationState?: Record<string, unknown>,
|
|
34
|
+
external?: boolean,
|
|
34
35
|
) => Response;
|
|
35
36
|
|
|
36
37
|
/**
|