@rangojs/router 0.0.0-experimental.19 → 0.0.0-experimental.1c0bdfad
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 +17 -0
- package/README.md +291 -61
- package/dist/bin/rango.js +544 -143
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3744 -1329
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +67 -13
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +312 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +247 -23
- package/skills/caching/SKILL.md +322 -19
- package/skills/composability/SKILL.md +27 -2
- 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 +282 -60
- package/skills/host-router/SKILL.md +278 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +50 -6
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +297 -31
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +771 -0
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +155 -111
- package/skills/rango/SKILL.md +251 -23
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +123 -48
- package/skills/route/SKILL.md +104 -9
- package/skills/router-setup/SKILL.md +124 -11
- 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 +125 -222
- 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 +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/typesafety/SKILL.md +357 -52
- package/skills/use-cache/SKILL.md +46 -14
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +67 -40
- package/src/bin/rango.ts +18 -0
- 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 +197 -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/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +200 -30
- package/src/browser/navigation-client.ts +217 -58
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +187 -112
- package/src/browser/prefetch/cache.ts +312 -30
- package/src/browser/prefetch/fetch.ts +344 -47
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +126 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +125 -18
- package/src/browser/react/NavigationProvider.tsx +135 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- 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 +80 -5
- package/src/browser/rsc-router.tsx +226 -75
- package/src/browser/scroll-restoration.ts +54 -42
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +619 -442
- package/src/browser/types.ts +115 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +7 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +182 -37
- 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 +392 -106
- 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 +214 -48
- package/src/cache/cache-scope.ts +236 -89
- 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 +2224 -171
- 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 +11 -17
- package/src/cache/document-cache.ts +89 -27
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +11 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +31 -31
- package/src/cache/read-through-swr.ts +41 -11
- 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 +45 -21
- package/src/client.tsx +120 -336
- 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/debug.ts +2 -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 +56 -19
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +95 -0
- 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 -5
- 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 +79 -29
- package/src/index.ts +149 -65
- 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 +63 -26
- 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 +7 -72
- package/src/route-definition/dsl-helpers.ts +469 -276
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +113 -37
- package/src/route-definition/index.ts +3 -3
- package/src/route-definition/redirect.ts +53 -12
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -17
- package/src/route-types.ts +37 -41
- 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 +45 -22
- package/src/router/handler-context.ts +110 -39
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +50 -24
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +274 -56
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +121 -205
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +33 -6
- package/src/router/match-middleware/cache-lookup.ts +214 -263
- package/src/router/match-middleware/cache-store.ts +73 -33
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +104 -49
- package/src/router/metrics.ts +217 -26
- package/src/router/middleware-types.ts +24 -110
- package/src/router/middleware.ts +384 -197
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +148 -91
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prerender-match.ts +199 -56
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +144 -74
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +8 -28
- package/src/router/router-interfaces.ts +129 -36
- package/src/router/router-options.ts +185 -23
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +281 -76
- package/src/router/segment-resolution/helpers.ts +116 -31
- package/src/router/segment-resolution/loader-cache.ts +63 -37
- package/src/router/segment-resolution/revalidation.ts +493 -391
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +8 -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 +180 -58
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +182 -54
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +702 -460
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -25
- 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 +98 -19
- 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 +126 -106
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +269 -114
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/types.ts +34 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +49 -41
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +281 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +317 -63
- 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 +26 -46
- package/src/server/request-context.ts +425 -177
- package/src/server.ts +6 -0
- package/src/ssr/index.tsx +25 -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 +99 -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 +343 -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/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 +3 -19
- 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 +236 -88
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +10 -45
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +37 -19
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +64 -91
- package/src/vite/discovery/discover-routers.ts +147 -88
- 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 +247 -145
- 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 +61 -13
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +10 -3
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +155 -65
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- 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 +49 -98
- 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 +127 -0
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +46 -37
- package/src/vite/plugins/virtual-entries.ts +13 -18
- package/src/vite/rango.ts +241 -287
- package/src/vite/router-discovery.ts +956 -149
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +4 -4
- 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 +141 -34
- package/src/vite/utils/shared-utils.ts +92 -42
- package/CLAUDE.md +0 -5
- 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 -6
- package/src/network-error-thrower.tsx +0 -23
- package/src/route-definition/route-function.ts +0 -119
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -7,14 +7,12 @@ import type {
|
|
|
7
7
|
import { generateHistoryKey } from "./navigation-store.js";
|
|
8
8
|
import {
|
|
9
9
|
handleNavigationStart,
|
|
10
|
-
handleNavigationEnd,
|
|
11
10
|
ensureHistoryKey,
|
|
12
11
|
} from "./scroll-restoration.js";
|
|
13
12
|
import type { EventController, NavigationHandle } from "./event-controller.js";
|
|
14
13
|
import { debugLog } from "./logging.js";
|
|
15
|
-
import { buildHistoryState } from "./history-state.js";
|
|
14
|
+
import { buildHistoryState, pushHistoryWithIdx } from "./history-state.js";
|
|
16
15
|
|
|
17
|
-
// Re-export for consumers that import from navigation-transaction
|
|
18
16
|
export { resolveNavigationState } from "./history-state.js";
|
|
19
17
|
|
|
20
18
|
/** Check if a history state object contains location state keys. */
|
|
@@ -26,7 +24,6 @@ function hasLocationState(state: unknown): boolean {
|
|
|
26
24
|
);
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
// Polyfill Symbol.dispose for Safari and older browsers
|
|
30
27
|
if (typeof Symbol.dispose === "undefined") {
|
|
31
28
|
(Symbol as any).dispose = Symbol("Symbol.dispose");
|
|
32
29
|
}
|
|
@@ -81,11 +78,12 @@ export interface BoundTransaction {
|
|
|
81
78
|
readonly currentUrl: string;
|
|
82
79
|
/** Start streaming and get a token to end it when the stream completes */
|
|
83
80
|
startStreaming(): StreamingToken;
|
|
81
|
+
/** Commit the navigation. Returns the effective scroll option for the caller to handle. */
|
|
84
82
|
commit(
|
|
85
83
|
segmentIds: string[],
|
|
86
84
|
segments: ResolvedSegment[],
|
|
87
85
|
overrides?: BoundCommitOverrides,
|
|
88
|
-
):
|
|
86
|
+
): { scroll?: boolean };
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
/**
|
|
@@ -93,7 +91,7 @@ export interface BoundTransaction {
|
|
|
93
91
|
* Uses the event controller handle for lifecycle management
|
|
94
92
|
*/
|
|
95
93
|
interface NavigationTransaction extends Disposable {
|
|
96
|
-
commit(options: CommitOptions):
|
|
94
|
+
commit(options: CommitOptions): { scroll?: boolean };
|
|
97
95
|
with(
|
|
98
96
|
options: Omit<CommitOptions, "segmentIds" | "segments">,
|
|
99
97
|
): BoundTransaction;
|
|
@@ -114,13 +112,12 @@ export function createNavigationTransaction(
|
|
|
114
112
|
let committed = false;
|
|
115
113
|
const currentUrl = window.location.href;
|
|
116
114
|
|
|
117
|
-
// Start navigation in event controller (this sets loading state)
|
|
118
115
|
const handle = eventController.startNavigation(url, options);
|
|
119
116
|
|
|
120
117
|
/**
|
|
121
118
|
* Commit the navigation - updates store and URL atomically
|
|
122
119
|
*/
|
|
123
|
-
function commit(opts: CommitOptions):
|
|
120
|
+
function commit(opts: CommitOptions): { scroll?: boolean } {
|
|
124
121
|
committed = true;
|
|
125
122
|
|
|
126
123
|
const {
|
|
@@ -138,91 +135,63 @@ export function createNavigationTransaction(
|
|
|
138
135
|
|
|
139
136
|
const parsedUrl = new URL(url, window.location.origin);
|
|
140
137
|
|
|
141
|
-
// Generate history key from URL (with intercept suffix for separate caching)
|
|
142
138
|
const historyKey = generateHistoryKey(url, { intercept });
|
|
143
139
|
|
|
144
|
-
// For cache-only commits (stale revalidation), only update cache and return
|
|
145
|
-
// Don't touch store state or history - user may have navigated elsewhere
|
|
146
140
|
if (cacheOnly) {
|
|
147
141
|
const currentHandleData = eventController.getHandleState().data;
|
|
148
142
|
store.cacheSegmentsForHistory(historyKey, segments, currentHandleData);
|
|
149
|
-
// Complete the navigation handle so currentNavigation is cleared.
|
|
150
|
-
// Without this, the entry lingers and weakens state-machine invariants.
|
|
151
143
|
handle.complete(parsedUrl);
|
|
152
144
|
debugLog("[Browser] Cache-only commit, historyKey:", historyKey);
|
|
153
|
-
return;
|
|
145
|
+
return { scroll: false };
|
|
154
146
|
}
|
|
155
147
|
|
|
156
|
-
// Save current scroll position before navigating
|
|
157
148
|
handleNavigationStart();
|
|
158
149
|
|
|
159
|
-
// Update segment state atomically
|
|
160
150
|
store.setSegmentIds(segmentIds);
|
|
161
151
|
store.setCurrentUrl(url);
|
|
162
152
|
store.setPath(parsedUrl.pathname);
|
|
163
153
|
|
|
164
154
|
store.setHistoryKey(historyKey);
|
|
165
155
|
|
|
166
|
-
// Cache segments with current handleData for this history entry
|
|
167
156
|
const currentHandleData = eventController.getHandleState().data;
|
|
168
157
|
store.cacheSegmentsForHistory(historyKey, segments, currentHandleData);
|
|
169
158
|
|
|
170
|
-
// For server actions, skip URL/history updates but still complete navigation
|
|
171
159
|
if (storeOnly) {
|
|
172
160
|
debugLog("[Browser] Store updated (action)");
|
|
173
|
-
// Complete navigation to clear loading state
|
|
174
161
|
handle.complete(parsedUrl);
|
|
175
|
-
return;
|
|
162
|
+
return { scroll: false };
|
|
176
163
|
}
|
|
177
164
|
|
|
178
|
-
// Build history state - include user state, intercept info, and server-set state
|
|
179
165
|
const historyState = buildHistoryState(
|
|
180
166
|
opts.state,
|
|
181
167
|
{ intercept, sourceUrl: interceptSourceUrl },
|
|
182
168
|
serverState,
|
|
183
169
|
);
|
|
184
170
|
|
|
185
|
-
// Snapshot old state before pushState/replaceState overwrites it.
|
|
186
|
-
// Used to detect when location state is being cleared.
|
|
187
171
|
const oldState = window.history.state;
|
|
188
172
|
|
|
189
|
-
|
|
190
|
-
if (replace) {
|
|
191
|
-
window.history.replaceState(historyState, "", url);
|
|
192
|
-
} else {
|
|
193
|
-
window.history.pushState(historyState, "", url);
|
|
194
|
-
}
|
|
195
|
-
// Ensure new history entry has a scroll restoration key
|
|
173
|
+
pushHistoryWithIdx(historyState, url, replace ?? false);
|
|
196
174
|
ensureHistoryKey();
|
|
197
175
|
|
|
198
|
-
// Notify location state hooks when either old or new state carries
|
|
199
|
-
// location state. This covers both "set new state" and "clear old state"
|
|
200
|
-
// for same-page navigations where components don't remount.
|
|
201
176
|
if (hasLocationState(oldState) || hasLocationState(historyState)) {
|
|
202
177
|
window.dispatchEvent(new Event("__rsc_locationstate"));
|
|
203
178
|
}
|
|
204
179
|
|
|
205
|
-
// Complete the navigation in event controller (sets idle state, updates location)
|
|
206
180
|
handle.complete(parsedUrl);
|
|
207
181
|
|
|
208
|
-
// Handle scroll after navigation
|
|
209
|
-
handleNavigationEnd({ scroll });
|
|
210
|
-
|
|
211
182
|
debugLog(
|
|
212
183
|
"[Browser] Navigation committed, historyKey:",
|
|
213
184
|
historyKey,
|
|
214
185
|
intercept ? "(intercept)" : "",
|
|
215
186
|
);
|
|
187
|
+
|
|
188
|
+
return { scroll };
|
|
216
189
|
}
|
|
217
190
|
|
|
218
191
|
return {
|
|
219
192
|
handle,
|
|
220
193
|
commit,
|
|
221
194
|
|
|
222
|
-
/**
|
|
223
|
-
* Create a bound transaction with pre-configured URL options
|
|
224
|
-
* segmentIds and segments provided at commit time (after they're resolved)
|
|
225
|
-
*/
|
|
226
195
|
with(
|
|
227
196
|
opts: Omit<CommitOptions, "segmentIds" | "segments">,
|
|
228
197
|
): BoundTransaction {
|
|
@@ -238,32 +207,18 @@ export function createNavigationTransaction(
|
|
|
238
207
|
segments: ResolvedSegment[],
|
|
239
208
|
overrides?: BoundCommitOverrides,
|
|
240
209
|
) => {
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
// Allow overrides to force replace (e.g., for intercepts)
|
|
245
|
-
const finalReplace =
|
|
246
|
-
overrides?.replace !== undefined ? overrides.replace : opts.replace;
|
|
247
|
-
// Intercept info: overrides take precedence, fallback to opts
|
|
248
|
-
const intercept =
|
|
249
|
-
overrides?.intercept !== undefined
|
|
250
|
-
? overrides.intercept
|
|
251
|
-
: opts.intercept;
|
|
210
|
+
const finalScroll = overrides?.scroll ?? opts.scroll;
|
|
211
|
+
const finalReplace = overrides?.replace ?? opts.replace;
|
|
212
|
+
const intercept = overrides?.intercept ?? opts.intercept;
|
|
252
213
|
const interceptSourceUrl =
|
|
253
|
-
overrides?.interceptSourceUrl
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
//
|
|
257
|
-
const cacheOnly =
|
|
258
|
-
overrides?.cacheOnly !== undefined
|
|
259
|
-
? overrides.cacheOnly
|
|
260
|
-
: opts.cacheOnly;
|
|
261
|
-
// User state: overrides take precedence, fallback to opts
|
|
214
|
+
overrides?.interceptSourceUrl ?? opts.interceptSourceUrl;
|
|
215
|
+
const cacheOnly = overrides?.cacheOnly ?? opts.cacheOnly;
|
|
216
|
+
// state is `unknown` (null is meaningful) so `??` would wrongly drop a
|
|
217
|
+
// null override; serverState always comes from overrides, never opts.
|
|
262
218
|
const state =
|
|
263
219
|
overrides?.state !== undefined ? overrides.state : opts.state;
|
|
264
|
-
// Server-set location state: only from overrides (set by partial-update)
|
|
265
220
|
const serverState = overrides?.serverState;
|
|
266
|
-
commit({
|
|
221
|
+
return commit({
|
|
267
222
|
...opts,
|
|
268
223
|
segmentIds,
|
|
269
224
|
segments,
|
|
@@ -280,13 +235,10 @@ export function createNavigationTransaction(
|
|
|
280
235
|
},
|
|
281
236
|
|
|
282
237
|
[Symbol.dispose]() {
|
|
283
|
-
// Superseded: another navigation took over.
|
|
284
238
|
if (handle.signal.aborted) {
|
|
285
239
|
return;
|
|
286
240
|
}
|
|
287
241
|
|
|
288
|
-
// Failed (not committed): keep the target URL -- the error UI owns it.
|
|
289
|
-
// Just reset the event controller to idle.
|
|
290
242
|
if (!committed) {
|
|
291
243
|
handle[Symbol.dispose]();
|
|
292
244
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NetworkError, isNetworkError } from "../errors.js";
|
|
2
|
-
import {
|
|
2
|
+
import { RenderErrorThrower } from "../render-error-thrower.js";
|
|
3
3
|
import type { UpdateSubscriber } from "./types.js";
|
|
4
4
|
import { createElement, startTransition } from "react";
|
|
5
5
|
|
|
@@ -24,18 +24,18 @@ export function toNetworkError(
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* Render an error into the segment tree via the onUpdate subscriber so the
|
|
28
|
+
* nearest error boundary catches it. Wrapped in startTransition; RenderErrorThrower
|
|
29
|
+
* throws during render (async rejections do not reach boundaries on their own).
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
function emitErrorToBoundary(
|
|
32
32
|
onUpdate: UpdateSubscriber,
|
|
33
|
-
error:
|
|
33
|
+
error: unknown,
|
|
34
34
|
pathname: string,
|
|
35
35
|
): void {
|
|
36
36
|
startTransition(() => {
|
|
37
37
|
onUpdate({
|
|
38
|
-
root: createElement(
|
|
38
|
+
root: createElement(RenderErrorThrower, { error }),
|
|
39
39
|
metadata: {
|
|
40
40
|
pathname,
|
|
41
41
|
segments: [],
|
|
@@ -45,6 +45,33 @@ export function emitNetworkError(
|
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Emit a NetworkError to the nearest error boundary (offline, failed fetch).
|
|
50
|
+
*/
|
|
51
|
+
export function emitNetworkError(
|
|
52
|
+
onUpdate: UpdateSubscriber,
|
|
53
|
+
error: NetworkError,
|
|
54
|
+
pathname: string,
|
|
55
|
+
): void {
|
|
56
|
+
emitErrorToBoundary(onUpdate, error, pathname);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Emit a navigation processing error to the nearest error boundary. Used when a
|
|
61
|
+
* navigation response cannot be processed (an undecodable Flight body, or any
|
|
62
|
+
* unanticipated failure while building the response) -- for both fresh and
|
|
63
|
+
* prefetched responses, since both funnel through the navigation catch. Without
|
|
64
|
+
* this, such a failure becomes an uncaught rejection that silently aborts the
|
|
65
|
+
* navigation instead of surfacing the route's error boundary.
|
|
66
|
+
*/
|
|
67
|
+
export function emitNavigationError(
|
|
68
|
+
onUpdate: UpdateSubscriber,
|
|
69
|
+
error: unknown,
|
|
70
|
+
pathname: string,
|
|
71
|
+
): void {
|
|
72
|
+
emitErrorToBoundary(onUpdate, error, pathname);
|
|
73
|
+
}
|
|
74
|
+
|
|
48
75
|
/**
|
|
49
76
|
* Check if an error is safe to suppress in background operations.
|
|
50
77
|
*
|