@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/browser/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// ============================================================================
|
|
2
|
-
// Browser Module - Browser entry point for
|
|
2
|
+
// Browser Module - Browser entry point for Rango
|
|
3
3
|
// ============================================================================
|
|
4
4
|
//
|
|
5
5
|
// Usage:
|
|
6
|
-
// import { initBrowserApp,
|
|
6
|
+
// import { initBrowserApp, Rango } from "rsc-router/browser";
|
|
7
7
|
//
|
|
8
8
|
// For React components (Link, useNavigation, etc.):
|
|
9
9
|
// import { Link, useNavigation, useAction, href } from "rsc-router/client";
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
// Browser app initialization
|
|
14
14
|
export {
|
|
15
15
|
initBrowserApp,
|
|
16
|
-
|
|
16
|
+
Rango,
|
|
17
17
|
type InitBrowserAppOptions,
|
|
18
18
|
} from "./rsc-router.js";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client seat of `invalidateClientCache()` (the `default` export condition).
|
|
3
|
+
*
|
|
4
|
+
* Makes the current client behave as if a server action had just completed:
|
|
5
|
+
* the history cache is marked stale (SWR), the prefetch map is flushed, the
|
|
6
|
+
* state rotates, and sibling tabs are broadcast to — the same
|
|
7
|
+
* `markCacheAsStaleAndBroadcast()` path the server-action bridge uses. This is
|
|
8
|
+
* the gentler mark-stale (not hard-clear) behavior, so Back renders the cached
|
|
9
|
+
* entry instantly and revalidates.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { getRegisteredStore } from "./navigation-store-handle.js";
|
|
13
|
+
import { clearPrefetchCache } from "./prefetch/cache.js";
|
|
14
|
+
|
|
15
|
+
export function invalidateClientCache(): void {
|
|
16
|
+
if (typeof document === "undefined") {
|
|
17
|
+
// SSR pass of a client component also resolves the default condition. A
|
|
18
|
+
// render-time call must not take down the page; no-op with a dev warning.
|
|
19
|
+
if (process.env.NODE_ENV !== "production") {
|
|
20
|
+
console.warn(
|
|
21
|
+
"[rango] invalidateClientCache() was called during a server render; " +
|
|
22
|
+
"it is a no-op outside the browser.",
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const store = getRegisteredStore();
|
|
29
|
+
if (store) {
|
|
30
|
+
store.markCacheAsStaleAndBroadcast();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Pre-boot: no store registered yet. clearPrefetchCache() (which rotates the
|
|
35
|
+
// state) is complete at this point — there is no history cache to mark and no
|
|
36
|
+
// sibling state worth broadcasting.
|
|
37
|
+
clearPrefetchCache();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Client no-op for `keepClientCache()`. It is a server action directive (the
|
|
42
|
+
* `react-server` condition sets a response header the action bridge reads);
|
|
43
|
+
* there is nothing to suppress from the client side.
|
|
44
|
+
*/
|
|
45
|
+
export function keepClientCache(): void {
|
|
46
|
+
if (process.env.NODE_ENV !== "production") {
|
|
47
|
+
console.warn(
|
|
48
|
+
"[rango] keepClientCache() has no effect on the client; it is a server " +
|
|
49
|
+
"action directive. Call it from inside a server action.",
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/browser/logging.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { INTERNAL_RANGO_DEBUG } from "../internal-debug.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Module-level debug flag for guarding call sites whose debug arguments do
|
|
5
|
+
* non-trivial work (joins, maps, spreads, object literals). Because the Vite
|
|
6
|
+
* transform folds INTERNAL_RANGO_DEBUG to a literal, an `if (IS_BROWSER_DEBUG)`
|
|
7
|
+
* guard is minifier-DCE-able — the whole block drops from the production bundle.
|
|
8
|
+
* Prefer this over isBrowserDebugEnabled() at hot call sites: a const guard folds
|
|
9
|
+
* where a function call may not.
|
|
10
|
+
*/
|
|
11
|
+
export const IS_BROWSER_DEBUG: boolean = INTERNAL_RANGO_DEBUG;
|
|
12
|
+
|
|
3
13
|
interface BrowserLogContext {
|
|
4
14
|
requestId: string;
|
|
5
15
|
txId: string;
|
|
@@ -53,3 +63,21 @@ export function debugLog(msg: string, ...args: unknown[]): void {
|
|
|
53
63
|
console.log(msg, ...args);
|
|
54
64
|
}
|
|
55
65
|
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Boot-sequence debug log: one line per initial-document step (flight decode,
|
|
69
|
+
* handle stream, bridge wiring, initial tree build, hydration commit), each
|
|
70
|
+
* stamped with performance.now() so the gap BEFORE hydrateRoot is visible.
|
|
71
|
+
* The initial document path was otherwise silent — FE debug only started
|
|
72
|
+
* talking at the first soft navigation, so a boot stall (e.g. an await that
|
|
73
|
+
* holds initBrowserApp, and with it hydrateRoot) was invisible.
|
|
74
|
+
*/
|
|
75
|
+
export function bootLog(step: string, details?: Record<string, unknown>): void {
|
|
76
|
+
if (!INTERNAL_RANGO_DEBUG) return;
|
|
77
|
+
const prefix = `[Browser][boot] ${step} @ ${Math.round(performance.now())}ms`;
|
|
78
|
+
if (details) {
|
|
79
|
+
console.log(prefix, details);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
console.log(prefix);
|
|
83
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResolvedSegment } from "./types.js";
|
|
2
|
-
import { debugLog } from "./logging.js";
|
|
2
|
+
import { debugLog, IS_BROWSER_DEBUG } from "./logging.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Merge partial loader data from server with cached loader data.
|
|
@@ -19,9 +19,11 @@ export function mergeSegmentLoaders(
|
|
|
19
19
|
const serverLoaderIds = fromServer.loaderIds || [];
|
|
20
20
|
const cachedLoaderIds = fromCache.loaderIds || [];
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
if (IS_BROWSER_DEBUG) {
|
|
23
|
+
debugLog(
|
|
24
|
+
`[Browser] Merging partial loaders: server has ${serverLoaderIds.join(", ")}, cache has ${cachedLoaderIds.join(", ")}`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
25
27
|
|
|
26
28
|
return {
|
|
27
29
|
...fromCache,
|
|
@@ -5,13 +5,15 @@ import type {
|
|
|
5
5
|
ResolvedSegment,
|
|
6
6
|
} from "./types.js";
|
|
7
7
|
import { setAppVersion } from "./app-version.js";
|
|
8
|
+
import { isActionFenceActive } from "./action-fence.js";
|
|
9
|
+
import { getRangoState } from "./rango-state.js";
|
|
8
10
|
import * as React from "react";
|
|
9
11
|
import { startTransition } from "react";
|
|
10
12
|
import {
|
|
11
13
|
createNavigationTransaction,
|
|
12
14
|
resolveNavigationState,
|
|
13
15
|
} from "./navigation-transaction.js";
|
|
14
|
-
import { buildHistoryState } from "./history-state.js";
|
|
16
|
+
import { buildHistoryState, pushHistoryWithIdx } from "./history-state.js";
|
|
15
17
|
import {
|
|
16
18
|
handleNavigationStart,
|
|
17
19
|
handleNavigationEnd,
|
|
@@ -30,6 +32,7 @@ import { isInterceptOnlyCache } from "./intercept-utils.js";
|
|
|
30
32
|
import {
|
|
31
33
|
toNetworkError,
|
|
32
34
|
emitNetworkError,
|
|
35
|
+
emitNavigationError,
|
|
33
36
|
isBackgroundSuppressible,
|
|
34
37
|
} from "./network-error-handler.js";
|
|
35
38
|
import { debugLog } from "./logging.js";
|
|
@@ -48,7 +51,7 @@ export { createNavigationTransaction };
|
|
|
48
51
|
*/
|
|
49
52
|
export interface NavigationBridgeConfigWithController extends NavigationBridgeConfig {
|
|
50
53
|
eventController: EventController;
|
|
51
|
-
/** RSC version from initial payload metadata */
|
|
54
|
+
/** RSC version from initial payload metadata. */
|
|
52
55
|
version?: string;
|
|
53
56
|
}
|
|
54
57
|
|
|
@@ -159,11 +162,7 @@ export function createNavigationBridge(
|
|
|
159
162
|
},
|
|
160
163
|
{},
|
|
161
164
|
);
|
|
162
|
-
|
|
163
|
-
window.history.replaceState(historyState, "", url);
|
|
164
|
-
} else {
|
|
165
|
-
window.history.pushState(historyState, "", url);
|
|
166
|
-
}
|
|
165
|
+
pushHistoryWithIdx(historyState, url, options?.replace ?? false);
|
|
167
166
|
|
|
168
167
|
// Ensure new history entry has a scroll restoration key
|
|
169
168
|
ensureHistoryKey();
|
|
@@ -217,17 +216,20 @@ export function createNavigationBridge(
|
|
|
217
216
|
store.setInterceptSourceUrl(null);
|
|
218
217
|
}
|
|
219
218
|
|
|
220
|
-
// Before navigating away, update the source page's cache with the latest
|
|
221
|
-
// This ensures the cache has correct handleData even if handles
|
|
219
|
+
// Before navigating away, update the source page's cache with the latest
|
|
220
|
+
// handleData. This ensures the cache has correct handleData even if handles
|
|
221
|
+
// were streaming. Use updateCacheHandleData (not cacheSegmentsForHistory):
|
|
222
|
+
// the source page's segments are unchanged, so this is a handleData refresh,
|
|
223
|
+
// not a commit. Critically it PRESERVES the entry's stale flag — when the
|
|
224
|
+
// source page has a deferred Meta still pending, its entry was marked stale
|
|
225
|
+
// (invalidate-on-pending) so a popstate return revalidates; re-committing it
|
|
226
|
+
// here would reset stale to false and serve the carried (pre-resolution)
|
|
227
|
+
// title as fresh. It also leaves the nav-instance token intact.
|
|
222
228
|
const sourceHistoryKey = store.getHistoryKey();
|
|
223
229
|
const sourceCached = store.getCachedSegments(sourceHistoryKey);
|
|
224
230
|
if (sourceCached?.segments && sourceCached.segments.length > 0) {
|
|
225
231
|
const currentHandleData = eventController.getHandleState().data;
|
|
226
|
-
store.
|
|
227
|
-
sourceHistoryKey,
|
|
228
|
-
sourceCached.segments,
|
|
229
|
-
currentHandleData,
|
|
230
|
-
);
|
|
232
|
+
store.updateCacheHandleData(sourceHistoryKey, currentHandleData);
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
// Check if we have cached segments for target URL
|
|
@@ -327,8 +329,15 @@ export function createNavigationBridge(
|
|
|
327
329
|
} as NavigateOptionsInternal);
|
|
328
330
|
}
|
|
329
331
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
+
// Aborted, or superseded by a newer navigation. A superseded nav may
|
|
333
|
+
// reject with a non-AbortError (e.g. a Flight decode that fails after its
|
|
334
|
+
// signal was aborted), so check the signal too -- otherwise we would
|
|
335
|
+
// render a boundary that clobbers the newer navigation's content.
|
|
336
|
+
if (
|
|
337
|
+
(error instanceof DOMException && error.name === "AbortError") ||
|
|
338
|
+
tx.handle.signal.aborted
|
|
339
|
+
) {
|
|
340
|
+
debugLog("[Browser] Navigation aborted or superseded");
|
|
332
341
|
return;
|
|
333
342
|
}
|
|
334
343
|
|
|
@@ -345,7 +354,13 @@ export function createNavigationBridge(
|
|
|
345
354
|
return;
|
|
346
355
|
}
|
|
347
356
|
|
|
348
|
-
|
|
357
|
+
// A response we could not process (undecodable Flight body, or an
|
|
358
|
+
// unanticipated failure building the response). Surface the route's
|
|
359
|
+
// error boundary rather than let the rejection abort the navigation
|
|
360
|
+
// silently. Prefetched responses funnel here too: a failed warm-prefetch
|
|
361
|
+
// payload rejects on consumption and propagates to this catch.
|
|
362
|
+
console.error("[Browser] Unprocessable navigation response:", error);
|
|
363
|
+
emitNavigationError(onUpdate, error, url);
|
|
349
364
|
} finally {
|
|
350
365
|
tx[Symbol.dispose]();
|
|
351
366
|
}
|
|
@@ -374,6 +389,14 @@ export function createNavigationBridge(
|
|
|
374
389
|
tx.with({ url: window.location.href, replace: true, scroll: false }),
|
|
375
390
|
);
|
|
376
391
|
} catch (error) {
|
|
392
|
+
// Aborted or superseded: bail without rendering a boundary (see navigate()).
|
|
393
|
+
if (
|
|
394
|
+
(error instanceof DOMException && error.name === "AbortError") ||
|
|
395
|
+
tx.handle.signal.aborted
|
|
396
|
+
) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
377
400
|
const networkError = toNetworkError(error, {
|
|
378
401
|
url: window.location.href,
|
|
379
402
|
operation: "revalidation",
|
|
@@ -386,7 +409,12 @@ export function createNavigationBridge(
|
|
|
386
409
|
emitNetworkError(onUpdate, networkError, window.location.href);
|
|
387
410
|
return;
|
|
388
411
|
}
|
|
389
|
-
|
|
412
|
+
|
|
413
|
+
// refresh() shares the fetchPartialUpdate chokepoint with navigate()/
|
|
414
|
+
// popstate, so an unprocessable response must surface the error boundary
|
|
415
|
+
// here too rather than become an uncaught rejection.
|
|
416
|
+
console.error("[Browser] Unprocessable refresh response:", error);
|
|
417
|
+
emitNavigationError(onUpdate, error, window.location.href);
|
|
390
418
|
} finally {
|
|
391
419
|
tx[Symbol.dispose]();
|
|
392
420
|
}
|
|
@@ -450,11 +478,22 @@ export function createNavigationBridge(
|
|
|
450
478
|
// Helper to check if streaming is in progress
|
|
451
479
|
const isStreaming = () => eventController.getState().isStreaming;
|
|
452
480
|
|
|
481
|
+
// Surface any external rotation of the rango state cookie (a server
|
|
482
|
+
// Set-Cookie, a sibling tab, a cookie clear) BEFORE reading the stale bit.
|
|
483
|
+
// The divergence observer only runs inside getRangoState() — fetch-time —
|
|
484
|
+
// so a popstate-first interaction would otherwise serve a pre-mutation
|
|
485
|
+
// page as fresh and never fetch to trigger the observer. Reading here lets
|
|
486
|
+
// the observer mark the history cache stale so getCachedSegments sees it.
|
|
487
|
+
getRangoState();
|
|
488
|
+
|
|
453
489
|
// Check if we can restore from history cache
|
|
454
490
|
const cached = store.getCachedSegments(historyKey);
|
|
455
491
|
const cachedSegments = cached?.segments;
|
|
456
492
|
const cachedHandleData = cached?.handleData;
|
|
457
|
-
|
|
493
|
+
// While an action is in flight the fence persists no stale flag, so OR it
|
|
494
|
+
// in here: a popstate during the flight serves the cached entry AND
|
|
495
|
+
// revalidates (SWR) instead of serving it as fresh.
|
|
496
|
+
const isStale = (cached?.stale ?? false) || isActionFenceActive();
|
|
458
497
|
|
|
459
498
|
if (cachedSegments && cachedSegments.length > 0) {
|
|
460
499
|
// Update store to point to this history entry
|
|
@@ -496,7 +535,14 @@ export function createNavigationBridge(
|
|
|
496
535
|
},
|
|
497
536
|
scroll: { restore: true, isStreaming },
|
|
498
537
|
};
|
|
499
|
-
|
|
538
|
+
// Intercept-driven popstate (entering OR leaving an intercept) only
|
|
539
|
+
// mutates the parallel slot; the main outlet shows the same content.
|
|
540
|
+
// Skip startViewTransition in those cases — same rationale as the
|
|
541
|
+
// intercept guard in partial-update.ts's hasTransition computation.
|
|
542
|
+
const hasTransition =
|
|
543
|
+
!isIntercept &&
|
|
544
|
+
!isLeavingIntercept &&
|
|
545
|
+
cachedSegments.some((s) => s.transition);
|
|
500
546
|
if (hasTransition) {
|
|
501
547
|
startTransition(() => {
|
|
502
548
|
if (addTransitionType) {
|
|
@@ -511,8 +557,19 @@ export function createNavigationBridge(
|
|
|
511
557
|
// SWR: If stale, trigger background revalidation
|
|
512
558
|
if (isStale) {
|
|
513
559
|
debugLog("[Browser] Cache is stale, background revalidating...");
|
|
514
|
-
// Background revalidation - don't await, just fire and forget
|
|
515
|
-
|
|
560
|
+
// Background revalidation - don't await, just fire and forget.
|
|
561
|
+
// When the entry's handles are incomplete (a deferred Meta was still
|
|
562
|
+
// pending when the user navigated away — see handlesPending), send NO
|
|
563
|
+
// segment IDs so the server returns a FULL re-render with the handle
|
|
564
|
+
// stream. A normal stale revalidation sends the cached IDs and the
|
|
565
|
+
// server returns a diff-only payload that omits unchanged segments'
|
|
566
|
+
// handles, so a deferred Meta would never re-stream and the title
|
|
567
|
+
// would stay the pre-resolution carry. handlesPending is set only for
|
|
568
|
+
// the deferred-Meta-aborted case, so action/cross-tab SWR keeps the
|
|
569
|
+
// cheap diff path.
|
|
570
|
+
const segmentIds = cached?.handlesPending
|
|
571
|
+
? []
|
|
572
|
+
: cachedSegments.map((s) => s.id);
|
|
516
573
|
|
|
517
574
|
const tx = createNavigationTransaction(
|
|
518
575
|
store,
|
|
@@ -586,8 +643,13 @@ export function createNavigationBridge(
|
|
|
586
643
|
// Restore scroll position after fetch completes
|
|
587
644
|
handleNavigationEnd({ restore: true, isStreaming });
|
|
588
645
|
} catch (error) {
|
|
589
|
-
|
|
590
|
-
|
|
646
|
+
// Aborted or superseded by a newer navigation: bail without clobbering
|
|
647
|
+
// content with a boundary (see navigate()).
|
|
648
|
+
if (
|
|
649
|
+
(error instanceof DOMException && error.name === "AbortError") ||
|
|
650
|
+
tx.handle.signal.aborted
|
|
651
|
+
) {
|
|
652
|
+
debugLog("[Browser] Popstate navigation aborted or superseded");
|
|
591
653
|
return;
|
|
592
654
|
}
|
|
593
655
|
|
|
@@ -604,7 +666,10 @@ export function createNavigationBridge(
|
|
|
604
666
|
return;
|
|
605
667
|
}
|
|
606
668
|
|
|
607
|
-
|
|
669
|
+
// Unprocessable response on a back/forward navigation: surface the
|
|
670
|
+
// error boundary instead of an uncaught rejection (see navigate()).
|
|
671
|
+
console.error("[Browser] Unprocessable popstate response:", error);
|
|
672
|
+
emitNavigationError(onUpdate, error, url);
|
|
608
673
|
} finally {
|
|
609
674
|
tx[Symbol.dispose]();
|
|
610
675
|
}
|
|
@@ -659,6 +724,10 @@ export function createNavigationBridge(
|
|
|
659
724
|
};
|
|
660
725
|
},
|
|
661
726
|
|
|
727
|
+
getVersion(): string | undefined {
|
|
728
|
+
return version;
|
|
729
|
+
},
|
|
730
|
+
|
|
662
731
|
updateVersion(newVersion: string): void {
|
|
663
732
|
version = newVersion;
|
|
664
733
|
setAppVersion(newVersion);
|