@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327
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 -4
- package/README.md +301 -797
- package/dist/bin/rango.js +603 -145
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3750 -1160
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +96 -24
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +12 -10
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +75 -19
- package/skills/layout/SKILL.md +40 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +25 -13
- package/skills/migrate-nextjs/SKILL.md +205 -20
- package/skills/migrate-react-router/SKILL.md +59 -670
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +40 -10
- package/skills/ppr/SKILL.md +616 -0
- package/skills/prerender/SKILL.md +72 -60
- package/skills/rango/SKILL.md +318 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +117 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- 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 +131 -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 +85 -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/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- package/skills/vercel/SKILL.md +128 -0
- 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 +0 -65
- 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/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- 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/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +144 -79
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +183 -144
- package/src/browser/prefetch/cache.ts +242 -77
- package/src/browser/prefetch/fetch.ts +325 -69
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +58 -20
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- 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 +17 -14
- 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 +25 -3
- 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 +145 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +203 -154
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -21
- 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 +456 -62
- 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 +128 -51
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +421 -58
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -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 +2202 -372
- 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 +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +180 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1127 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +33 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -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 +67 -37
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -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 +97 -12
- package/src/index.ts +98 -14
- 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 +32 -37
- package/src/prerender.ts +78 -10
- package/src/redirect-origin.ts +114 -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 -39
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +87 -59
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +27 -42
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +82 -59
- package/src/router/loader-resolution.ts +167 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +80 -55
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +69 -79
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +112 -67
- package/src/router/preview-match.ts +6 -2
- package/src/router/request-classification.ts +50 -69
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +115 -36
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +131 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +139 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +251 -0
- package/src/router/segment-resolution/revalidation.ts +272 -320
- 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 +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +157 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +291 -217
- 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 +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +124 -13
- package/src/rsc/redirect-guard.ts +100 -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 +421 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +282 -116
- package/src/rsc/shell-capture.ts +1158 -0
- package/src/rsc/shell-serve.ts +150 -0
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +53 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +350 -149
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +208 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +395 -176
- package/src/ssr/index.tsx +458 -178
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +199 -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 +584 -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 +56 -84
- 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 +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +19 -64
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +63 -17
- package/src/urls/path-helper.ts +22 -106
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +96 -68
- 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 +45 -1
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +4 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +210 -10
- 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 +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- 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 +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- 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 +138 -27
- package/src/vite/rango.ts +236 -138
- package/src/vite/router-discovery.ts +927 -136
- 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 +71 -43
- package/src/vite/utils/shared-utils.ts +142 -43
- 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
package/src/reverse.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ExtractParams } from "./types.js";
|
|
2
2
|
import type { SearchSchema, ResolveSearchSchema } from "./search-params.js";
|
|
3
3
|
import { serializeSearchParams } from "./search-params.js";
|
|
4
|
+
import { substitutePatternParams } from "./router/substitute-pattern-params.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Sanitize prefix string by removing leading slash
|
|
@@ -218,6 +219,67 @@ export type ExtractLocalRoutes<TPatterns> = TPatterns extends {
|
|
|
218
219
|
? TPatterns
|
|
219
220
|
: Record<string, string>;
|
|
220
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Params accepted by `useReverse(routes)`. The route's own params are
|
|
224
|
+
* required, and additional string keys are permitted so callers can
|
|
225
|
+
* override values that would otherwise be auto-filled from the matched
|
|
226
|
+
* route's `useParams()` (e.g. an enclosing `:tenantId` mount segment).
|
|
227
|
+
*/
|
|
228
|
+
export type LocalReverseParams<TPattern extends string> =
|
|
229
|
+
ExtractParams<TPattern> & {
|
|
230
|
+
readonly [extra: string]: string | undefined;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Type-safe local reverse function.
|
|
235
|
+
*
|
|
236
|
+
* Returned by `useReverse(routes)` on the client. The route map is the
|
|
237
|
+
* exposure boundary (a generated `routes` from a `urls()` module) and the
|
|
238
|
+
* scope is implicit from that import. Names may be written with or without a
|
|
239
|
+
* leading dot — `reverse("post")` and `reverse(".post")` are identical. The dot
|
|
240
|
+
* is a cosmetic readability convention (and parity with `ctx.reverse(".name")`);
|
|
241
|
+
* there is no separate global namespace here, so it carries no meaning.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* const reverse = useReverse(blogRoutes);
|
|
246
|
+
* reverse("index"); // ✓ no params (dot optional)
|
|
247
|
+
* reverse(".index"); // ✓ identical to the above
|
|
248
|
+
* reverse("post", { postId: "hello" }); // ✓ with params
|
|
249
|
+
* reverse("search", {}, { q: "hi" }); // ✓ with search schema
|
|
250
|
+
* reverse("typo"); // ✗ compile error
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
export type LocalReverseFunction<TLocalRoutes> = {
|
|
254
|
+
/**
|
|
255
|
+
* Route without params (leading dot optional)
|
|
256
|
+
*/
|
|
257
|
+
<TName extends keyof TLocalRoutes & string>(
|
|
258
|
+
name: IsEmptyObject<
|
|
259
|
+
ExtractParams<RoutePatternFor<TLocalRoutes, TName>>
|
|
260
|
+
> extends true
|
|
261
|
+
? TName | `.${TName}`
|
|
262
|
+
: never,
|
|
263
|
+
): string;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Route with params (leading dot optional)
|
|
267
|
+
*/
|
|
268
|
+
<TName extends keyof TLocalRoutes & string>(
|
|
269
|
+
name: TName | `.${TName}`,
|
|
270
|
+
params: LocalReverseParams<RoutePatternFor<TLocalRoutes, TName>>,
|
|
271
|
+
): string;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Route with params and search (leading dot optional)
|
|
275
|
+
*/
|
|
276
|
+
<TName extends keyof TLocalRoutes & string>(
|
|
277
|
+
name: TName | `.${TName}`,
|
|
278
|
+
params: LocalReverseParams<RoutePatternFor<TLocalRoutes, TName>>,
|
|
279
|
+
search: ResolveSearchSchema<ExtractSearchSchema<TLocalRoutes, TName>>,
|
|
280
|
+
): string;
|
|
281
|
+
};
|
|
282
|
+
|
|
221
283
|
/**
|
|
222
284
|
* Extract the response data type for a named route from a UrlPatterns instance.
|
|
223
285
|
* Re-exported from urls.ts for consumer convenience.
|
|
@@ -301,45 +363,9 @@ export function createReverse<TRoutes extends Record<string, string>>(
|
|
|
301
363
|
throw new Error(`Unknown route: ${name}`);
|
|
302
364
|
}
|
|
303
365
|
|
|
304
|
-
let result =
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
// Strip constraint syntax: :param(a|b) -> use "param" as key
|
|
308
|
-
// Optional params (:param?) are omitted when not provided
|
|
309
|
-
let hadOmittedOptional = false;
|
|
310
|
-
result = result.replace(
|
|
311
|
-
/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?(\?)/g,
|
|
312
|
-
(_, key, _constraint, optional) => {
|
|
313
|
-
const value = params[key];
|
|
314
|
-
// Empty string is treated as omitted — the trie matcher fills
|
|
315
|
-
// unmatched optional params with "" (not undefined), so reverse
|
|
316
|
-
// must collapse those segments instead of leaving empty slots.
|
|
317
|
-
if (value === undefined || value === "") {
|
|
318
|
-
hadOmittedOptional = true;
|
|
319
|
-
return "";
|
|
320
|
-
}
|
|
321
|
-
return encodeURIComponent(value);
|
|
322
|
-
},
|
|
323
|
-
);
|
|
324
|
-
// Second pass: required params (no trailing ?)
|
|
325
|
-
result = result.replace(
|
|
326
|
-
/:([a-zA-Z_][a-zA-Z0-9_]*)(\([^)]*\))?(?!\?)/g,
|
|
327
|
-
(_, key) => {
|
|
328
|
-
const value = params[key];
|
|
329
|
-
if (value === undefined) {
|
|
330
|
-
throw new Error(`Missing param "${key}" for route "${name}"`);
|
|
331
|
-
}
|
|
332
|
-
return encodeURIComponent(value);
|
|
333
|
-
},
|
|
334
|
-
);
|
|
335
|
-
// Clean up slashes only when an optional param was actually omitted,
|
|
336
|
-
// so intentional trailing-slash patterns like "/blog/" are preserved.
|
|
337
|
-
if (hadOmittedOptional) {
|
|
338
|
-
const hadTrailingSlash = pattern.length > 1 && pattern.endsWith("/");
|
|
339
|
-
result = result.replace(/\/\/+/g, "/").replace(/\/+$/, "") || "/";
|
|
340
|
-
if (hadTrailingSlash && !result.endsWith("/")) result += "/";
|
|
341
|
-
}
|
|
342
|
-
}
|
|
366
|
+
let result = params
|
|
367
|
+
? substitutePatternParams(pattern, params, name)
|
|
368
|
+
: pattern;
|
|
343
369
|
|
|
344
370
|
// Append search params as query string
|
|
345
371
|
if (search) {
|
|
@@ -3,26 +3,17 @@
|
|
|
3
3
|
import { Component, useState, type ReactNode } from "react";
|
|
4
4
|
import type { ClientErrorBoundaryFallbackProps } from "./types.js";
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Check if an error is a network-related error
|
|
8
|
-
*/
|
|
9
6
|
function isNetworkError(error: Error): boolean {
|
|
10
7
|
return error.name === "NetworkError";
|
|
11
8
|
}
|
|
12
9
|
|
|
13
|
-
/**
|
|
14
|
-
* Network error fallback UI with retry functionality
|
|
15
|
-
* Shows a connection-specific message and allows retrying via page refresh
|
|
16
|
-
*/
|
|
17
10
|
function NetworkErrorFallback({
|
|
18
11
|
error,
|
|
19
|
-
reset,
|
|
20
12
|
}: ClientErrorBoundaryFallbackProps): ReactNode {
|
|
21
13
|
const [isRetrying, setIsRetrying] = useState(false);
|
|
22
14
|
|
|
23
15
|
const handleRetry = (): void => {
|
|
24
16
|
setIsRetrying(true);
|
|
25
|
-
// Refresh the page to retry the request
|
|
26
17
|
window.location.reload();
|
|
27
18
|
};
|
|
28
19
|
|
|
@@ -42,7 +33,6 @@ function NetworkErrorFallback({
|
|
|
42
33
|
marginBottom: "1rem",
|
|
43
34
|
}}
|
|
44
35
|
>
|
|
45
|
-
{/* Simple cloud with x icon using CSS */}
|
|
46
36
|
<span style={{ color: "#9ca3af" }}>☁</span>
|
|
47
37
|
</div>
|
|
48
38
|
<h1
|
|
@@ -101,10 +91,6 @@ function NetworkErrorFallback({
|
|
|
101
91
|
);
|
|
102
92
|
}
|
|
103
93
|
|
|
104
|
-
/**
|
|
105
|
-
* Default fallback UI for root error boundary
|
|
106
|
-
* This is shown when an unhandled error bubbles up to the root
|
|
107
|
-
*/
|
|
108
94
|
function RootErrorFallback({
|
|
109
95
|
error,
|
|
110
96
|
reset,
|
|
@@ -230,7 +216,6 @@ export class RootErrorBoundary extends Component<
|
|
|
230
216
|
}
|
|
231
217
|
|
|
232
218
|
componentDidMount(): void {
|
|
233
|
-
// Listen for popstate (back/forward navigation) to reset error state
|
|
234
219
|
window.addEventListener("popstate", this.handlePopState);
|
|
235
220
|
}
|
|
236
221
|
|
|
@@ -247,15 +232,13 @@ export class RootErrorBoundary extends Component<
|
|
|
247
232
|
}
|
|
248
233
|
|
|
249
234
|
componentDidUpdate(prevProps: { children: ReactNode }): void {
|
|
250
|
-
// Reset error
|
|
251
|
-
// This allows the app to recover after navigation away from an errored route
|
|
235
|
+
// Reset error on children change (navigation).
|
|
252
236
|
if (this.state.hasError && prevProps.children !== this.props.children) {
|
|
253
237
|
this.setState({ hasError: false, error: null });
|
|
254
238
|
}
|
|
255
239
|
}
|
|
256
240
|
|
|
257
241
|
handlePopState = (): void => {
|
|
258
|
-
// Reset error state on back/forward navigation
|
|
259
242
|
if (this.state.hasError) {
|
|
260
243
|
this.setState({ hasError: false, error: null });
|
|
261
244
|
}
|
|
@@ -276,7 +259,6 @@ export class RootErrorBoundary extends Component<
|
|
|
276
259
|
segmentType: "route" as const,
|
|
277
260
|
};
|
|
278
261
|
|
|
279
|
-
// Use specialized fallback for network errors
|
|
280
262
|
if (isNetworkError(this.state.error)) {
|
|
281
263
|
return <NetworkErrorFallback error={errorInfo} reset={this.reset} />;
|
|
282
264
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
|
-
import { Suspense, use
|
|
4
|
-
import { invariant } from "./errors";
|
|
3
|
+
import { Suspense, use } from "react";
|
|
5
4
|
import { OutletProvider } from "./outlet-provider.js";
|
|
6
5
|
import type { ResolvedSegment } from "./types.js";
|
|
7
|
-
import {
|
|
6
|
+
import { decodeLoaderResults } from "./decode-loader-results.js";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Stable async wrapper component for route content
|
|
@@ -22,14 +21,12 @@ export function RouteContentWrapper({
|
|
|
22
21
|
fallback,
|
|
23
22
|
segmentId,
|
|
24
23
|
}: {
|
|
25
|
-
|
|
24
|
+
// Normally a pending promise (use() suspends -> fallback). forceAwait paths
|
|
25
|
+
// pass an already-resolved node so Suspender renders it without suspending.
|
|
26
|
+
content: Promise<ReactNode> | ReactNode;
|
|
26
27
|
fallback?: ReactNode;
|
|
27
28
|
segmentId?: string;
|
|
28
29
|
}): ReactNode {
|
|
29
|
-
if (!content) {
|
|
30
|
-
// Already resolved
|
|
31
|
-
return content as ReactNode;
|
|
32
|
-
}
|
|
33
30
|
return (
|
|
34
31
|
<Suspense
|
|
35
32
|
fallback={fallback ?? null}
|
|
@@ -40,57 +37,20 @@ export function RouteContentWrapper({
|
|
|
40
37
|
);
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
export function RouteContentWrapperCallback<T>({
|
|
44
|
-
resolve,
|
|
45
|
-
fallback,
|
|
46
|
-
children,
|
|
47
|
-
}: {
|
|
48
|
-
resolve: Promise<T> | T;
|
|
49
|
-
fallback?: ReactNode;
|
|
50
|
-
children: (data: T) => ReactNode;
|
|
51
|
-
}): ReactNode {
|
|
52
|
-
const id = useId();
|
|
53
|
-
invariant(children, "RouteContentWrapperCallback requires children");
|
|
54
|
-
invariant(
|
|
55
|
-
typeof children === "function",
|
|
56
|
-
"RouteContentWrapperCallback requires children to be a function",
|
|
57
|
-
);
|
|
58
|
-
invariant(
|
|
59
|
-
resolve !== undefined,
|
|
60
|
-
"RouteContentWrapperCallback requires resolve",
|
|
61
|
-
);
|
|
62
|
-
return (
|
|
63
|
-
<Suspense
|
|
64
|
-
fallback={fallback ?? null}
|
|
65
|
-
key={"route-content-suspense-callback-" + id}
|
|
66
|
-
>
|
|
67
|
-
<SuspenderCallback resolve={resolve} key={id}>
|
|
68
|
-
{children}
|
|
69
|
-
</SuspenderCallback>
|
|
70
|
-
</Suspense>
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
40
|
const Suspender = ({
|
|
75
41
|
content,
|
|
76
42
|
}: {
|
|
77
43
|
content: Promise<ReactNode> | ReactNode;
|
|
78
44
|
}): ReactNode => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
resolve: Promise<T> | T;
|
|
89
|
-
children: (data: T) => ReactNode;
|
|
90
|
-
}): ReactNode => {
|
|
91
|
-
return resolve instanceof Promise
|
|
92
|
-
? children(use(resolve))
|
|
93
|
-
: children(resolve);
|
|
45
|
+
// Normally content is a pending promise -> use() suspends and the wrapping
|
|
46
|
+
// Suspense shows the loading() fallback. forceAwait paths (popstate,
|
|
47
|
+
// stale-revalidation, fully-prefetched nav) instead pass the ALREADY-RESOLVED
|
|
48
|
+
// node so first render does not suspend for a microtask and flash the loading()
|
|
49
|
+
// fallback on a NORMAL (non-transition) commit. The wrapper tree
|
|
50
|
+
// (RouteContentWrapper > Suspense > Suspender) is identical either way, so this
|
|
51
|
+
// preserves tree structure (see docs/tree-structure.md) — only whether use()
|
|
52
|
+
// suspends differs, exactly like LoaderResolver's resolved-data branch.
|
|
53
|
+
return content instanceof Promise ? use(content) : content;
|
|
94
54
|
};
|
|
95
55
|
|
|
96
56
|
/**
|
|
@@ -159,28 +119,10 @@ function LoaderResolver({
|
|
|
159
119
|
? use(loaderDataPromise)
|
|
160
120
|
: loaderDataPromise;
|
|
161
121
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
loaderIds.forEach((id, i) => {
|
|
167
|
-
const result = resolvedData[i];
|
|
168
|
-
|
|
169
|
-
if (isLoaderDataResult(result)) {
|
|
170
|
-
if (result.ok) {
|
|
171
|
-
loaderData[id] = result.data;
|
|
172
|
-
} else {
|
|
173
|
-
if (result.fallback) {
|
|
174
|
-
loaderErrorFallback = result.fallback;
|
|
175
|
-
} else {
|
|
176
|
-
throw new Error(result.error.message);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
} else {
|
|
180
|
-
// Legacy format - direct data
|
|
181
|
-
loaderData[id] = result;
|
|
182
|
-
}
|
|
183
|
-
});
|
|
122
|
+
const { loaderData, errorFallback } = decodeLoaderResults(
|
|
123
|
+
resolvedData,
|
|
124
|
+
loaderIds,
|
|
125
|
+
);
|
|
184
126
|
|
|
185
127
|
return (
|
|
186
128
|
<OutletProvider
|
|
@@ -190,7 +132,7 @@ function LoaderResolver({
|
|
|
190
132
|
parallel={parallel}
|
|
191
133
|
loaderData={Object.keys(loaderData).length > 0 ? loaderData : undefined}
|
|
192
134
|
>
|
|
193
|
-
{
|
|
135
|
+
{errorFallback ?? children}
|
|
194
136
|
</OutletProvider>
|
|
195
137
|
);
|
|
196
138
|
}
|