@rangojs/router 0.0.0-experimental.11 → 0.0.0-experimental.110
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 +9 -0
- package/README.md +1037 -4
- package/dist/__internal.d.ts +83 -0
- package/dist/__internal.d.ts.map +1 -0
- package/dist/__internal.js +19 -0
- package/dist/__internal.js.map +1 -0
- package/dist/__mocks__/version.d.ts +7 -0
- package/dist/__mocks__/version.d.ts.map +1 -0
- package/dist/__mocks__/version.js +7 -0
- package/dist/__mocks__/version.js.map +1 -0
- package/dist/__tests__/client-href.test.d.ts +2 -0
- package/dist/__tests__/client-href.test.d.ts.map +1 -0
- package/dist/__tests__/client-href.test.js +74 -0
- package/dist/__tests__/client-href.test.js.map +1 -0
- package/dist/__tests__/component-utils.test.d.ts +2 -0
- package/dist/__tests__/component-utils.test.d.ts.map +1 -0
- package/dist/__tests__/component-utils.test.js +51 -0
- package/dist/__tests__/component-utils.test.js.map +1 -0
- package/dist/__tests__/event-controller.test.d.ts +2 -0
- package/dist/__tests__/event-controller.test.d.ts.map +1 -0
- package/dist/__tests__/event-controller.test.js +538 -0
- package/dist/__tests__/event-controller.test.js.map +1 -0
- package/dist/__tests__/helpers/route-tree.d.ts +118 -0
- package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
- package/dist/__tests__/helpers/route-tree.js +374 -0
- package/dist/__tests__/helpers/route-tree.js.map +1 -0
- package/dist/__tests__/match-result.test.d.ts +2 -0
- package/dist/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/__tests__/match-result.test.js +154 -0
- package/dist/__tests__/match-result.test.js.map +1 -0
- package/dist/__tests__/navigation-store.test.d.ts +2 -0
- package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
- package/dist/__tests__/navigation-store.test.js +440 -0
- package/dist/__tests__/navigation-store.test.js.map +1 -0
- package/dist/__tests__/partial-update.test.d.ts +2 -0
- package/dist/__tests__/partial-update.test.d.ts.map +1 -0
- package/dist/__tests__/partial-update.test.js +1009 -0
- package/dist/__tests__/partial-update.test.js.map +1 -0
- package/dist/__tests__/reverse-types.test.d.ts +8 -0
- package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-types.test.js +656 -0
- package/dist/__tests__/reverse-types.test.js.map +1 -0
- package/dist/__tests__/route-definition.test.d.ts +2 -0
- package/dist/__tests__/route-definition.test.d.ts.map +1 -0
- package/dist/__tests__/route-definition.test.js +55 -0
- package/dist/__tests__/route-definition.test.js.map +1 -0
- package/dist/__tests__/router-helpers.test.d.ts +2 -0
- package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/router-helpers.test.js +377 -0
- package/dist/__tests__/router-helpers.test.js.map +1 -0
- package/dist/__tests__/router-integration-2.test.d.ts +2 -0
- package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration-2.test.js +426 -0
- package/dist/__tests__/router-integration-2.test.js.map +1 -0
- package/dist/__tests__/router-integration.test.d.ts +2 -0
- package/dist/__tests__/router-integration.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration.test.js +1051 -0
- package/dist/__tests__/router-integration.test.js.map +1 -0
- package/dist/__tests__/search-params.test.d.ts +5 -0
- package/dist/__tests__/search-params.test.d.ts.map +1 -0
- package/dist/__tests__/search-params.test.js +306 -0
- package/dist/__tests__/search-params.test.js.map +1 -0
- package/dist/__tests__/segment-system.test.d.ts +2 -0
- package/dist/__tests__/segment-system.test.d.ts.map +1 -0
- package/dist/__tests__/segment-system.test.js +627 -0
- package/dist/__tests__/segment-system.test.js.map +1 -0
- package/dist/__tests__/static-handler-types.test.d.ts +8 -0
- package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
- package/dist/__tests__/static-handler-types.test.js +63 -0
- package/dist/__tests__/static-handler-types.test.js.map +1 -0
- package/dist/__tests__/urls.test.d.ts +2 -0
- package/dist/__tests__/urls.test.d.ts.map +1 -0
- package/dist/__tests__/urls.test.js +421 -0
- package/dist/__tests__/urls.test.js.map +1 -0
- package/dist/__tests__/use-mount.test.d.ts +2 -0
- package/dist/__tests__/use-mount.test.d.ts.map +1 -0
- package/dist/__tests__/use-mount.test.js +35 -0
- package/dist/__tests__/use-mount.test.js.map +1 -0
- package/dist/bin/rango.d.ts +2 -0
- package/dist/bin/rango.d.ts.map +1 -0
- package/dist/bin/rango.js +1635 -158
- package/dist/bin/rango.js.map +1 -0
- package/dist/browser/event-controller.d.ts +191 -0
- package/dist/browser/event-controller.d.ts.map +1 -0
- package/dist/browser/event-controller.js +559 -0
- package/dist/browser/event-controller.js.map +1 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/link-interceptor.d.ts +38 -0
- package/dist/browser/link-interceptor.d.ts.map +1 -0
- package/dist/browser/link-interceptor.js +99 -0
- package/dist/browser/link-interceptor.js.map +1 -0
- package/dist/browser/logging.d.ts +10 -0
- package/dist/browser/logging.d.ts.map +1 -0
- package/dist/browser/logging.js +29 -0
- package/dist/browser/logging.js.map +1 -0
- package/dist/browser/lru-cache.d.ts +17 -0
- package/dist/browser/lru-cache.d.ts.map +1 -0
- package/dist/browser/lru-cache.js +50 -0
- package/dist/browser/lru-cache.js.map +1 -0
- package/dist/browser/merge-segment-loaders.d.ts +39 -0
- package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
- package/dist/browser/merge-segment-loaders.js +102 -0
- package/dist/browser/merge-segment-loaders.js.map +1 -0
- package/dist/browser/navigation-bridge.d.ts +102 -0
- package/dist/browser/navigation-bridge.d.ts.map +1 -0
- package/dist/browser/navigation-bridge.js +708 -0
- package/dist/browser/navigation-bridge.js.map +1 -0
- package/dist/browser/navigation-client.d.ts +25 -0
- package/dist/browser/navigation-client.d.ts.map +1 -0
- package/dist/browser/navigation-client.js +157 -0
- package/dist/browser/navigation-client.js.map +1 -0
- package/dist/browser/navigation-store.d.ts +101 -0
- package/dist/browser/navigation-store.d.ts.map +1 -0
- package/dist/browser/navigation-store.js +625 -0
- package/dist/browser/navigation-store.js.map +1 -0
- package/dist/browser/partial-update.d.ts +75 -0
- package/dist/browser/partial-update.d.ts.map +1 -0
- package/dist/browser/partial-update.js +426 -0
- package/dist/browser/partial-update.js.map +1 -0
- package/dist/browser/react/Link.d.ts +86 -0
- package/dist/browser/react/Link.d.ts.map +1 -0
- package/dist/browser/react/Link.js +128 -0
- package/dist/browser/react/Link.js.map +1 -0
- package/dist/browser/react/NavigationProvider.d.ts +63 -0
- package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
- package/dist/browser/react/NavigationProvider.js +216 -0
- package/dist/browser/react/NavigationProvider.js.map +1 -0
- package/dist/browser/react/ScrollRestoration.d.ts +75 -0
- package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
- package/dist/browser/react/ScrollRestoration.js +57 -0
- package/dist/browser/react/ScrollRestoration.js.map +1 -0
- package/dist/browser/react/context.d.ts +46 -0
- package/dist/browser/react/context.d.ts.map +1 -0
- package/dist/browser/react/context.js +10 -0
- package/dist/browser/react/context.js.map +1 -0
- package/dist/browser/react/index.d.ts +11 -0
- package/dist/browser/react/index.d.ts.map +1 -0
- package/dist/browser/react/index.js +22 -0
- package/dist/browser/react/index.js.map +1 -0
- package/dist/browser/react/location-state-shared.d.ts +63 -0
- package/dist/browser/react/location-state-shared.d.ts.map +1 -0
- package/dist/browser/react/location-state-shared.js +81 -0
- package/dist/browser/react/location-state-shared.js.map +1 -0
- package/dist/browser/react/location-state.d.ts +23 -0
- package/dist/browser/react/location-state.d.ts.map +1 -0
- package/dist/browser/react/location-state.js +29 -0
- package/dist/browser/react/location-state.js.map +1 -0
- package/dist/browser/react/mount-context.d.ts +24 -0
- package/dist/browser/react/mount-context.d.ts.map +1 -0
- package/dist/browser/react/mount-context.js +24 -0
- package/dist/browser/react/mount-context.js.map +1 -0
- package/dist/browser/react/use-action.d.ts +64 -0
- package/dist/browser/react/use-action.d.ts.map +1 -0
- package/dist/browser/react/use-action.js +134 -0
- package/dist/browser/react/use-action.js.map +1 -0
- package/dist/browser/react/use-client-cache.d.ts +41 -0
- package/dist/browser/react/use-client-cache.d.ts.map +1 -0
- package/dist/browser/react/use-client-cache.js +39 -0
- package/dist/browser/react/use-client-cache.js.map +1 -0
- package/dist/browser/react/use-handle.d.ts +31 -0
- package/dist/browser/react/use-handle.d.ts.map +1 -0
- package/dist/browser/react/use-handle.js +144 -0
- package/dist/browser/react/use-handle.js.map +1 -0
- package/dist/browser/react/use-href.d.ts +33 -0
- package/dist/browser/react/use-href.d.ts.map +1 -0
- package/dist/browser/react/use-href.js +39 -0
- package/dist/browser/react/use-href.js.map +1 -0
- package/dist/browser/react/use-link-status.d.ts +37 -0
- package/dist/browser/react/use-link-status.d.ts.map +1 -0
- package/dist/browser/react/use-link-status.js +99 -0
- package/dist/browser/react/use-link-status.js.map +1 -0
- package/dist/browser/react/use-mount.d.ts +25 -0
- package/dist/browser/react/use-mount.d.ts.map +1 -0
- package/dist/browser/react/use-mount.js +30 -0
- package/dist/browser/react/use-mount.js.map +1 -0
- package/dist/browser/react/use-navigation.d.ts +27 -0
- package/dist/browser/react/use-navigation.d.ts.map +1 -0
- package/dist/browser/react/use-navigation.js +87 -0
- package/dist/browser/react/use-navigation.js.map +1 -0
- package/dist/browser/react/use-segments.d.ts +38 -0
- package/dist/browser/react/use-segments.d.ts.map +1 -0
- package/dist/browser/react/use-segments.js +130 -0
- package/dist/browser/react/use-segments.js.map +1 -0
- package/dist/browser/request-controller.d.ts +26 -0
- package/dist/browser/request-controller.d.ts.map +1 -0
- package/dist/browser/request-controller.js +147 -0
- package/dist/browser/request-controller.js.map +1 -0
- package/dist/browser/rsc-router.d.ts +129 -0
- package/dist/browser/rsc-router.d.ts.map +1 -0
- package/dist/browser/rsc-router.js +195 -0
- package/dist/browser/rsc-router.js.map +1 -0
- package/dist/browser/scroll-restoration.d.ts +93 -0
- package/dist/browser/scroll-restoration.d.ts.map +1 -0
- package/dist/browser/scroll-restoration.js +321 -0
- package/dist/browser/scroll-restoration.js.map +1 -0
- package/dist/browser/segment-structure-assert.d.ts +17 -0
- package/dist/browser/segment-structure-assert.d.ts.map +1 -0
- package/dist/browser/segment-structure-assert.js +59 -0
- package/dist/browser/segment-structure-assert.js.map +1 -0
- package/dist/browser/server-action-bridge.d.ts +26 -0
- package/dist/browser/server-action-bridge.d.ts.map +1 -0
- package/dist/browser/server-action-bridge.js +668 -0
- package/dist/browser/server-action-bridge.js.map +1 -0
- package/dist/browser/shallow.d.ts +12 -0
- package/dist/browser/shallow.d.ts.map +1 -0
- package/dist/browser/shallow.js +34 -0
- package/dist/browser/shallow.js.map +1 -0
- package/dist/browser/types.d.ts +369 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
- package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-cli.test.js +237 -0
- package/dist/build/__tests__/generate-cli.test.js.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.js +119 -0
- package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.js +620 -0
- package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.js +308 -0
- package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +81 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +276 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/build/generate-route-types.d.ts +115 -0
- package/dist/build/generate-route-types.d.ts.map +1 -0
- package/dist/build/generate-route-types.js +740 -0
- package/dist/build/generate-route-types.js.map +1 -0
- package/dist/build/index.d.ts +21 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +21 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/route-trie.d.ts +71 -0
- package/dist/build/route-trie.d.ts.map +1 -0
- package/dist/build/route-trie.js +175 -0
- package/dist/build/route-trie.js.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.js +208 -0
- package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
- package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
- package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
- package/dist/cache/__tests__/document-cache.test.js +345 -0
- package/dist/cache/__tests__/document-cache.test.js.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
- package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
- package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-store.test.js +367 -0
- package/dist/cache/__tests__/memory-store.test.js.map +1 -0
- package/dist/cache/cache-scope.d.ts +102 -0
- package/dist/cache/cache-scope.d.ts.map +1 -0
- package/dist/cache/cache-scope.js +440 -0
- package/dist/cache/cache-scope.js.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
- package/dist/cache/cf/cf-cache-store.d.ts +165 -0
- package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
- package/dist/cache/cf/cf-cache-store.js +242 -0
- package/dist/cache/cf/cf-cache-store.js.map +1 -0
- package/dist/cache/cf/index.d.ts +14 -0
- package/dist/cache/cf/index.d.ts.map +1 -0
- package/dist/cache/cf/index.js +17 -0
- package/dist/cache/cf/index.js.map +1 -0
- package/dist/cache/document-cache.d.ts +64 -0
- package/dist/cache/document-cache.d.ts.map +1 -0
- package/dist/cache/document-cache.js +228 -0
- package/dist/cache/document-cache.js.map +1 -0
- package/dist/cache/index.d.ts +19 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +21 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory-segment-store.d.ts +110 -0
- package/dist/cache/memory-segment-store.d.ts.map +1 -0
- package/dist/cache/memory-segment-store.js +117 -0
- package/dist/cache/memory-segment-store.js.map +1 -0
- package/dist/cache/memory-store.d.ts +41 -0
- package/dist/cache/memory-store.d.ts.map +1 -0
- package/dist/cache/memory-store.js +191 -0
- package/dist/cache/memory-store.js.map +1 -0
- package/dist/cache/types.d.ts +317 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +12 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/client.d.ts +248 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/client.rsc.d.ts +26 -0
- package/dist/client.rsc.d.ts.map +1 -0
- package/dist/client.rsc.js +46 -0
- package/dist/client.rsc.js.map +1 -0
- package/dist/component-utils.d.ts +36 -0
- package/dist/component-utils.d.ts.map +1 -0
- package/dist/component-utils.js +61 -0
- package/dist/component-utils.js.map +1 -0
- package/dist/components/DefaultDocument.d.ts +13 -0
- package/dist/components/DefaultDocument.d.ts.map +1 -0
- package/dist/components/DefaultDocument.js +15 -0
- package/dist/components/DefaultDocument.js.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +157 -0
- package/dist/debug.js.map +1 -0
- package/dist/default-error-boundary.d.ts +11 -0
- package/dist/default-error-boundary.d.ts.map +1 -0
- package/dist/default-error-boundary.js +45 -0
- package/dist/default-error-boundary.js.map +1 -0
- package/dist/deps/browser.d.ts +2 -0
- package/dist/deps/browser.d.ts.map +1 -0
- package/dist/deps/browser.js +3 -0
- package/dist/deps/browser.js.map +1 -0
- package/dist/deps/html-stream-client.d.ts +2 -0
- package/dist/deps/html-stream-client.d.ts.map +1 -0
- package/dist/deps/html-stream-client.js +3 -0
- package/dist/deps/html-stream-client.js.map +1 -0
- package/dist/deps/html-stream-server.d.ts +2 -0
- package/dist/deps/html-stream-server.d.ts.map +1 -0
- package/dist/deps/html-stream-server.js +3 -0
- package/dist/deps/html-stream-server.js.map +1 -0
- package/dist/deps/rsc.d.ts +2 -0
- package/dist/deps/rsc.d.ts.map +1 -0
- package/dist/deps/rsc.js +4 -0
- package/dist/deps/rsc.js.map +1 -0
- package/dist/deps/ssr.d.ts +2 -0
- package/dist/deps/ssr.d.ts.map +1 -0
- package/dist/deps/ssr.js +3 -0
- package/dist/deps/ssr.js.map +1 -0
- package/dist/errors.d.ts +174 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/handle.d.ts +78 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +82 -0
- package/dist/handle.js.map +1 -0
- package/dist/handles/MetaTags.d.ts +14 -0
- package/dist/handles/MetaTags.d.ts.map +1 -0
- package/dist/handles/MetaTags.js +136 -0
- package/dist/handles/MetaTags.js.map +1 -0
- package/dist/handles/index.d.ts +6 -0
- package/dist/handles/index.d.ts.map +1 -0
- package/dist/handles/index.js +6 -0
- package/dist/handles/index.js.map +1 -0
- package/dist/handles/meta.d.ts +39 -0
- package/dist/handles/meta.d.ts.map +1 -0
- package/dist/handles/meta.js +202 -0
- package/dist/handles/meta.js.map +1 -0
- package/dist/host/__tests__/errors.test.d.ts +2 -0
- package/dist/host/__tests__/errors.test.d.ts.map +1 -0
- package/dist/host/__tests__/errors.test.js +76 -0
- package/dist/host/__tests__/errors.test.js.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.js +251 -0
- package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/host/__tests__/router.test.d.ts +2 -0
- package/dist/host/__tests__/router.test.d.ts.map +1 -0
- package/dist/host/__tests__/router.test.js +241 -0
- package/dist/host/__tests__/router.test.js.map +1 -0
- package/dist/host/__tests__/testing.test.d.ts +2 -0
- package/dist/host/__tests__/testing.test.d.ts.map +1 -0
- package/dist/host/__tests__/testing.test.js +64 -0
- package/dist/host/__tests__/testing.test.js.map +1 -0
- package/dist/host/__tests__/utils.test.d.ts +2 -0
- package/dist/host/__tests__/utils.test.d.ts.map +1 -0
- package/dist/host/__tests__/utils.test.js +29 -0
- package/dist/host/__tests__/utils.test.js.map +1 -0
- package/dist/host/cookie-handler.d.ts +34 -0
- package/dist/host/cookie-handler.d.ts.map +1 -0
- package/dist/host/cookie-handler.js +124 -0
- package/dist/host/cookie-handler.js.map +1 -0
- package/dist/host/errors.d.ts +56 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +79 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +32 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pattern-matcher.d.ts +36 -0
- package/dist/host/pattern-matcher.d.ts.map +1 -0
- package/dist/host/pattern-matcher.js +172 -0
- package/dist/host/pattern-matcher.js.map +1 -0
- package/dist/host/router.d.ts +26 -0
- package/dist/host/router.d.ts.map +1 -0
- package/dist/host/router.js +218 -0
- package/dist/host/router.js.map +1 -0
- package/dist/host/testing.d.ts +36 -0
- package/dist/host/testing.d.ts.map +1 -0
- package/dist/host/testing.js +55 -0
- package/dist/host/testing.js.map +1 -0
- package/dist/host/types.d.ts +115 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/host/utils.d.ts +21 -0
- package/dist/host/utils.d.ts.map +1 -0
- package/dist/host/utils.js +23 -0
- package/dist/host/utils.js.map +1 -0
- package/dist/href-client.d.ts +131 -0
- package/dist/href-client.d.ts.map +1 -0
- package/dist/href-client.js +64 -0
- package/dist/href-client.js.map +1 -0
- package/{src/href-context.ts → dist/href-context.d.ts} +7 -11
- package/dist/href-context.d.ts.map +1 -0
- package/dist/href-context.js +21 -0
- package/dist/href-context.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/index.rsc.d.ts +32 -0
- package/dist/index.rsc.d.ts.map +1 -0
- package/dist/index.rsc.js +40 -0
- package/dist/index.rsc.js.map +1 -0
- package/dist/internal-debug.d.ts +2 -0
- package/dist/internal-debug.d.ts.map +1 -0
- package/dist/internal-debug.js +5 -0
- package/dist/internal-debug.js.map +1 -0
- package/dist/loader.d.ts +14 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +20 -0
- package/dist/loader.js.map +1 -0
- package/dist/loader.rsc.d.ts +19 -0
- package/dist/loader.rsc.d.ts.map +1 -0
- package/dist/loader.rsc.js +99 -0
- package/dist/loader.rsc.js.map +1 -0
- package/dist/network-error-thrower.d.ts +17 -0
- package/dist/network-error-thrower.d.ts.map +1 -0
- package/dist/network-error-thrower.js +14 -0
- package/dist/network-error-thrower.js.map +1 -0
- package/dist/outlet-context.d.ts +13 -0
- package/dist/outlet-context.d.ts.map +1 -0
- package/dist/outlet-context.js +3 -0
- package/dist/outlet-context.js.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.js +148 -0
- package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
- package/dist/prerender/param-hash.d.ts +16 -0
- package/dist/prerender/param-hash.d.ts.map +1 -0
- package/dist/prerender/param-hash.js +36 -0
- package/dist/prerender/param-hash.js.map +1 -0
- package/dist/prerender/store.d.ts +38 -0
- package/dist/prerender/store.d.ts.map +1 -0
- package/dist/prerender/store.js +61 -0
- package/dist/prerender/store.js.map +1 -0
- package/dist/prerender.d.ts +66 -0
- package/dist/prerender.d.ts.map +1 -0
- package/dist/prerender.js +57 -0
- package/dist/prerender.js.map +1 -0
- package/dist/reverse.d.ts +196 -0
- package/dist/reverse.d.ts.map +1 -0
- package/dist/reverse.js +78 -0
- package/dist/reverse.js.map +1 -0
- package/dist/root-error-boundary.d.ts +33 -0
- package/dist/root-error-boundary.d.ts.map +1 -0
- package/dist/root-error-boundary.js +165 -0
- package/dist/root-error-boundary.js.map +1 -0
- package/dist/route-content-wrapper.d.ts +46 -0
- package/dist/route-content-wrapper.d.ts.map +1 -0
- package/dist/route-content-wrapper.js +77 -0
- package/dist/route-content-wrapper.js.map +1 -0
- package/dist/route-definition.d.ts +421 -0
- package/dist/route-definition.d.ts.map +1 -0
- package/dist/route-definition.js +868 -0
- package/dist/route-definition.js.map +1 -0
- package/dist/route-map-builder.d.ts +155 -0
- package/dist/route-map-builder.d.ts.map +1 -0
- package/dist/route-map-builder.js +237 -0
- package/dist/route-map-builder.js.map +1 -0
- package/dist/route-types.d.ts +165 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +7 -0
- package/dist/route-types.js.map +1 -0
- package/dist/router/__tests__/handler-context.test.d.ts +2 -0
- package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/handler-context.test.js +65 -0
- package/dist/router/__tests__/handler-context.test.js.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
- package/dist/router/__tests__/match-context.test.d.ts +2 -0
- package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-context.test.js +92 -0
- package/dist/router/__tests__/match-context.test.js.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.js +417 -0
- package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
- package/dist/router/__tests__/match-result.test.d.ts +2 -0
- package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-result.test.js +457 -0
- package/dist/router/__tests__/match-result.test.js.map +1 -0
- package/dist/router/__tests__/on-error.test.d.ts +2 -0
- package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
- package/dist/router/__tests__/on-error.test.js +678 -0
- package/dist/router/__tests__/on-error.test.js.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.js +629 -0
- package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
- package/dist/router/error-handling.d.ts +77 -0
- package/dist/router/error-handling.d.ts.map +1 -0
- package/dist/router/error-handling.js +202 -0
- package/dist/router/error-handling.js.map +1 -0
- package/dist/router/handler-context.d.ts +20 -0
- package/dist/router/handler-context.d.ts.map +1 -0
- package/dist/router/handler-context.js +198 -0
- package/dist/router/handler-context.js.map +1 -0
- package/dist/router/intercept-resolution.d.ts +66 -0
- package/dist/router/intercept-resolution.d.ts.map +1 -0
- package/dist/router/intercept-resolution.js +246 -0
- package/dist/router/intercept-resolution.js.map +1 -0
- package/dist/router/loader-resolution.d.ts +64 -0
- package/dist/router/loader-resolution.d.ts.map +1 -0
- package/dist/router/loader-resolution.js +284 -0
- package/dist/router/loader-resolution.js.map +1 -0
- package/dist/router/logging.d.ts +15 -0
- package/dist/router/logging.d.ts.map +1 -0
- package/dist/router/logging.js +99 -0
- package/dist/router/logging.js.map +1 -0
- package/dist/router/manifest.d.ts +22 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +181 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/router/match-api.d.ts +35 -0
- package/dist/router/match-api.d.ts.map +1 -0
- package/dist/router/match-api.js +406 -0
- package/dist/router/match-api.js.map +1 -0
- package/dist/router/match-context.d.ts +206 -0
- package/dist/router/match-context.d.ts.map +1 -0
- package/dist/router/match-context.js +17 -0
- package/dist/router/match-context.js.map +1 -0
- package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
- package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
- package/dist/router/match-middleware/background-revalidation.js +75 -0
- package/dist/router/match-middleware/background-revalidation.js.map +1 -0
- package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
- package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-lookup.js +257 -0
- package/dist/router/match-middleware/cache-lookup.js.map +1 -0
- package/dist/router/match-middleware/cache-store.d.ts +113 -0
- package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-store.js +108 -0
- package/dist/router/match-middleware/cache-store.js.map +1 -0
- package/dist/router/match-middleware/index.d.ts +81 -0
- package/dist/router/match-middleware/index.d.ts.map +1 -0
- package/dist/router/match-middleware/index.js +80 -0
- package/dist/router/match-middleware/index.js.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.js +134 -0
- package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
- package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
- package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/segment-resolution.js +53 -0
- package/dist/router/match-middleware/segment-resolution.js.map +1 -0
- package/dist/router/match-pipelines.d.ts +147 -0
- package/dist/router/match-pipelines.d.ts.map +1 -0
- package/dist/router/match-pipelines.js +82 -0
- package/dist/router/match-pipelines.js.map +1 -0
- package/dist/router/match-result.d.ts +126 -0
- package/dist/router/match-result.d.ts.map +1 -0
- package/dist/router/match-result.js +93 -0
- package/dist/router/match-result.js.map +1 -0
- package/dist/router/metrics.d.ts +20 -0
- package/dist/router/metrics.d.ts.map +1 -0
- package/dist/router/metrics.js +47 -0
- package/dist/router/metrics.js.map +1 -0
- package/dist/router/middleware.d.ts +249 -0
- package/dist/router/middleware.d.ts.map +1 -0
- package/dist/router/middleware.js +434 -0
- package/dist/router/middleware.js.map +1 -0
- package/dist/router/middleware.test.d.ts +2 -0
- package/dist/router/middleware.test.d.ts.map +1 -0
- package/dist/router/middleware.test.js +816 -0
- package/dist/router/middleware.test.js.map +1 -0
- package/dist/router/pattern-matching.d.ts +149 -0
- package/dist/router/pattern-matching.d.ts.map +1 -0
- package/dist/router/pattern-matching.js +349 -0
- package/dist/router/pattern-matching.js.map +1 -0
- package/dist/router/revalidation.d.ts +44 -0
- package/dist/router/revalidation.d.ts.map +1 -0
- package/dist/router/revalidation.js +147 -0
- package/dist/router/revalidation.js.map +1 -0
- package/dist/router/router-context.d.ts +135 -0
- package/dist/router/router-context.d.ts.map +1 -0
- package/dist/router/router-context.js +36 -0
- package/dist/router/router-context.js.map +1 -0
- package/dist/router/segment-resolution.d.ts +127 -0
- package/dist/router/segment-resolution.d.ts.map +1 -0
- package/dist/router/segment-resolution.js +919 -0
- package/dist/router/segment-resolution.js.map +1 -0
- package/dist/router/trie-matching.d.ts +40 -0
- package/dist/router/trie-matching.d.ts.map +1 -0
- package/dist/router/trie-matching.js +127 -0
- package/dist/router/trie-matching.js.map +1 -0
- package/dist/router/types.d.ts +136 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +7 -0
- package/dist/router/types.js.map +1 -0
- package/dist/router.d.ts +753 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.gen.d.ts +6 -0
- package/dist/router.gen.d.ts.map +1 -0
- package/dist/router.gen.js +6 -0
- package/dist/router.gen.js.map +1 -0
- package/dist/router.js +1304 -0
- package/dist/router.js.map +1 -0
- package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
- package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
- package/dist/rsc/__tests__/helpers.test.js +140 -0
- package/dist/rsc/__tests__/helpers.test.js.map +1 -0
- package/dist/rsc/handler.d.ts +45 -0
- package/dist/rsc/handler.d.ts.map +1 -0
- package/dist/rsc/handler.js +1172 -0
- package/dist/rsc/handler.js.map +1 -0
- package/dist/rsc/helpers.d.ts +16 -0
- package/dist/rsc/helpers.d.ts.map +1 -0
- package/dist/rsc/helpers.js +55 -0
- package/dist/rsc/helpers.js.map +1 -0
- package/dist/rsc/index.d.ts +22 -0
- package/dist/rsc/index.d.ts.map +1 -0
- package/dist/rsc/index.js +23 -0
- package/dist/rsc/index.js.map +1 -0
- package/dist/rsc/nonce.d.ts +9 -0
- package/dist/rsc/nonce.d.ts.map +1 -0
- package/dist/rsc/nonce.js +18 -0
- package/dist/rsc/nonce.js.map +1 -0
- package/dist/rsc/types.d.ts +206 -0
- package/dist/rsc/types.d.ts.map +1 -0
- package/dist/rsc/types.js +8 -0
- package/dist/rsc/types.js.map +1 -0
- package/dist/search-params.d.ts +103 -0
- package/dist/search-params.d.ts.map +1 -0
- package/dist/search-params.js +74 -0
- package/dist/search-params.js.map +1 -0
- package/dist/segment-system.d.ts +75 -0
- package/dist/segment-system.d.ts.map +1 -0
- package/dist/segment-system.js +336 -0
- package/dist/segment-system.js.map +1 -0
- package/dist/server/context.d.ts +245 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +197 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/fetchable-loader-store.d.ts +18 -0
- package/dist/server/fetchable-loader-store.d.ts.map +1 -0
- package/dist/server/fetchable-loader-store.js +18 -0
- package/dist/server/fetchable-loader-store.js.map +1 -0
- package/dist/server/handle-store.d.ts +85 -0
- package/dist/server/handle-store.d.ts.map +1 -0
- package/dist/server/handle-store.js +142 -0
- package/dist/server/handle-store.js.map +1 -0
- package/dist/server/loader-registry.d.ts +55 -0
- package/dist/server/loader-registry.d.ts.map +1 -0
- package/dist/server/loader-registry.js +132 -0
- package/dist/server/loader-registry.js.map +1 -0
- package/dist/server/request-context.d.ts +226 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +290 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/root-layout.d.ts +4 -0
- package/dist/server/root-layout.d.ts.map +1 -0
- package/dist/server/root-layout.js +5 -0
- package/dist/server/root-layout.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +20 -0
- package/dist/server.js.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
- package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
- package/dist/ssr/index.d.ts +98 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +158 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/static-handler.d.ts +50 -0
- package/dist/static-handler.d.ts.map +1 -0
- package/dist/static-handler.gen.d.ts +5 -0
- package/dist/static-handler.gen.d.ts.map +1 -0
- package/dist/static-handler.gen.js +5 -0
- package/dist/static-handler.gen.js.map +1 -0
- package/dist/static-handler.js +29 -0
- package/dist/static-handler.js.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +20 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +240 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/ThemeScript.d.ts +48 -0
- package/dist/theme/ThemeScript.d.ts.map +1 -0
- package/dist/theme/ThemeScript.js +13 -0
- package/dist/theme/ThemeScript.js.map +1 -0
- package/dist/theme/__tests__/theme.test.d.ts +2 -0
- package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
- package/dist/theme/__tests__/theme.test.js +103 -0
- package/dist/theme/__tests__/theme.test.js.map +1 -0
- package/dist/theme/constants.d.ts +29 -0
- package/dist/theme/constants.d.ts.map +1 -0
- package/dist/theme/constants.js +48 -0
- package/dist/theme/constants.js.map +1 -0
- package/dist/theme/index.d.ts +31 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +36 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-context.d.ts +40 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +60 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-script.d.ts +27 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +147 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/dist/theme/types.d.ts +163 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +11 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme/use-theme.d.ts +12 -0
- package/dist/theme/use-theme.d.ts.map +1 -0
- package/dist/theme/use-theme.js +40 -0
- package/dist/theme/use-theme.js.map +1 -0
- package/dist/types.d.ts +1479 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/urls.d.ts +441 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.gen.d.ts +8 -0
- package/dist/urls.gen.d.ts.map +1 -0
- package/dist/urls.gen.js +8 -0
- package/dist/urls.gen.js.map +1 -0
- package/dist/urls.js +443 -0
- package/dist/urls.js.map +1 -0
- package/dist/use-loader.d.ts +127 -0
- package/dist/use-loader.d.ts.map +1 -0
- package/dist/use-loader.js +237 -0
- package/dist/use-loader.js.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
- package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.js +39 -0
- package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
- package/dist/vite/ast-handler-extract.d.ts +49 -0
- package/dist/vite/ast-handler-extract.d.ts.map +1 -0
- package/dist/vite/ast-handler-extract.js +249 -0
- package/dist/vite/ast-handler-extract.js.map +1 -0
- package/dist/vite/expose-action-id.d.ts +19 -0
- package/dist/vite/expose-action-id.d.ts.map +1 -0
- package/dist/vite/expose-action-id.js +250 -0
- package/dist/vite/expose-action-id.js.map +1 -0
- package/dist/vite/expose-id-utils.d.ts +69 -0
- package/dist/vite/expose-id-utils.d.ts.map +1 -0
- package/dist/vite/expose-id-utils.js +289 -0
- package/dist/vite/expose-id-utils.js.map +1 -0
- package/dist/vite/expose-internal-ids.d.ts +22 -0
- package/dist/vite/expose-internal-ids.d.ts.map +1 -0
- package/dist/vite/expose-internal-ids.js +886 -0
- package/dist/vite/expose-internal-ids.js.map +1 -0
- package/dist/vite/index.d.ts +149 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +6148 -2425
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/index.named-routes.gen.ts +103 -0
- package/dist/vite/package-resolution.d.ts +43 -0
- package/dist/vite/package-resolution.d.ts.map +1 -0
- package/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
- package/dist/vite/package-resolution.js.map +1 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/dist/vite/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +12 -16
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +73 -66
- package/skills/breadcrumbs/SKILL.md +252 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +473 -0
- package/skills/caching/SKILL.md +94 -24
- package/skills/composability/SKILL.md +197 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +18 -16
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +524 -71
- package/skills/host-router/SKILL.md +243 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +173 -8
- package/skills/layout/SKILL.md +123 -5
- package/skills/links/SKILL.md +316 -25
- package/skills/loader/SKILL.md +620 -50
- package/skills/middleware/SKILL.md +211 -37
- package/skills/migrate-nextjs/SKILL.md +562 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +271 -3
- package/skills/prerender/SKILL.md +448 -63
- package/skills/rango/SKILL.md +273 -21
- package/skills/response-routes/SKILL.md +210 -100
- package/skills/route/SKILL.md +310 -14
- package/skills/router-setup/SKILL.md +211 -33
- package/skills/server-actions/SKILL.md +751 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +622 -91
- package/skills/use-cache/SKILL.md +324 -0
- package/skills/view-transitions/SKILL.md +212 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +117 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +136 -68
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +370 -561
- package/src/browser/navigation-client.ts +228 -70
- package/src/browser/navigation-store.ts +97 -55
- package/src/browser/navigation-transaction.ts +293 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +376 -315
- package/src/browser/prefetch/cache.ts +314 -0
- package/src/browser/prefetch/fetch.ts +282 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +191 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +152 -0
- package/src/browser/react/Link.tsx +255 -71
- package/src/browser/react/NavigationProvider.tsx +152 -24
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +55 -0
- package/src/browser/react/index.ts +15 -12
- package/src/browser/react/location-state-shared.ts +176 -53
- package/src/browser/react/location-state.ts +90 -19
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +41 -123
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +44 -65
- package/src/browser/react/use-params.ts +78 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +99 -0
- package/src/browser/react/use-router.ts +96 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +85 -99
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +254 -72
- package/src/browser/scroll-restoration.ts +132 -49
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +510 -603
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +158 -48
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +87 -26
- package/src/build/generate-route-types.ts +39 -828
- package/src/build/index.ts +2 -5
- package/src/build/route-trie.ts +84 -31
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +418 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +128 -0
- package/src/build/route-types/router-processing.ts +618 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/runtime-discovery.ts +231 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +342 -0
- package/src/cache/cache-scope.ts +167 -307
- package/src/cache/cf/cf-cache-store.ts +573 -21
- package/src/cache/cf/index.ts +13 -3
- package/src/cache/document-cache.ts +116 -77
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +1 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +6 -1
- package/src/client.tsx +117 -303
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +156 -0
- package/src/debug.ts +19 -9
- package/src/errors.ts +78 -8
- package/src/handle.ts +56 -11
- package/src/handles/MetaTags.tsx +73 -20
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +30 -13
- package/src/host/cookie-handler.ts +21 -15
- package/src/host/errors.ts +8 -8
- package/src/host/index.ts +6 -9
- package/src/host/pattern-matcher.ts +27 -27
- package/src/host/router.ts +176 -82
- package/src/host/testing.ts +8 -8
- package/src/host/types.ts +46 -9
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +196 -56
- package/src/index.rsc.ts +140 -22
- package/src/index.ts +214 -53
- package/src/internal-debug.ts +11 -0
- package/src/loader-store.ts +463 -0
- package/src/loader.rsc.ts +25 -143
- package/src/loader.ts +27 -10
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +4 -2
- package/src/prerender/store.ts +122 -17
- package/src/prerender.ts +397 -29
- package/src/response-utils.ts +28 -0
- package/src/reverse.ts +231 -121
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +1134 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +485 -0
- package/src/route-definition/index.ts +55 -0
- package/src/route-definition/redirect.ts +101 -0
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-definition.ts +1 -1431
- package/src/route-map-builder.ts +162 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +64 -9
- package/src/router/content-negotiation.ts +215 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +10 -10
- package/src/router/find-match.ts +160 -0
- package/src/router/handler-context.ts +376 -109
- package/src/router/intercept-resolution.ts +35 -20
- package/src/router/lazy-includes.ts +237 -0
- package/src/router/loader-resolution.ts +330 -145
- package/src/router/logging.ts +251 -0
- package/src/router/manifest.ts +70 -22
- package/src/router/match-api.ts +196 -261
- package/src/router/match-context.ts +4 -2
- package/src/router/match-handlers.ts +441 -0
- package/src/router/match-middleware/background-revalidation.ts +108 -93
- package/src/router/match-middleware/cache-lookup.ts +414 -91
- package/src/router/match-middleware/cache-store.ts +91 -29
- package/src/router/match-middleware/intercept-resolution.ts +48 -21
- package/src/router/match-middleware/segment-resolution.ts +73 -9
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +154 -35
- package/src/router/metrics.ts +241 -16
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +209 -0
- package/src/router/middleware.ts +373 -371
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +291 -54
- package/src/router/prerender-match.ts +502 -0
- package/src/router/preview-match.ts +98 -0
- package/src/router/request-classification.ts +310 -0
- package/src/router/revalidation.ts +195 -40
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +41 -21
- package/src/router/router-interfaces.ts +490 -0
- package/src/router/router-options.ts +618 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +756 -0
- package/src/router/segment-resolution/helpers.ts +268 -0
- package/src/router/segment-resolution/loader-cache.ts +199 -0
- package/src/router/segment-resolution/revalidation.ts +1407 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -1336
- package/src/router/segment-wrappers.ts +291 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +299 -0
- package/src/router/telemetry.ts +300 -0
- package/src/router/timeout.ts +148 -0
- package/src/router/trie-matching.ts +111 -39
- package/src/router/types.ts +17 -9
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +707 -2291
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +864 -1117
- package/src/rsc/helpers.ts +181 -19
- package/src/rsc/index.ts +1 -21
- package/src/rsc/loader-fetch.ts +229 -0
- package/src/rsc/manifest-init.ts +90 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +395 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +360 -0
- package/src/rsc/rsc-rendering.ts +256 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +360 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +52 -11
- package/src/search-params.ts +230 -0
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +187 -38
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +344 -70
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +113 -15
- package/src/server/loader-registry.ts +24 -64
- package/src/server/request-context.ts +603 -109
- package/src/server.ts +35 -155
- package/src/ssr/index.tsx +107 -30
- package/src/static-handler.ts +126 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +5 -2
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +4 -30
- package/src/theme/theme-script.ts +21 -18
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +806 -0
- package/src/types/index.ts +89 -0
- package/src/types/loader-types.ts +209 -0
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +120 -0
- package/src/types/segments.ts +167 -0
- package/src/types.ts +1 -1763
- package/src/urls/include-helper.ts +207 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +372 -0
- package/src/urls/path-helper.ts +364 -0
- package/src/urls/pattern-types.ts +141 -0
- package/src/urls/response-types.ts +108 -0
- package/src/urls/type-extraction.ts +377 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -1288
- package/src/use-loader.tsx +511 -107
- package/src/vite/debug.ts +184 -0
- package/src/vite/discovery/bundle-postprocess.ts +181 -0
- package/src/vite/discovery/discover-routers.ts +374 -0
- 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 +480 -0
- package/src/vite/discovery/route-types-writer.ts +258 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +143 -0
- package/src/vite/discovery/virtual-module-codegen.ts +193 -0
- package/src/vite/index.ts +15 -2012
- package/src/vite/plugin-types.ts +103 -0
- package/src/vite/plugins/cjs-to-esm.ts +98 -0
- package/src/vite/plugins/client-ref-dedup.ts +131 -0
- package/src/vite/plugins/client-ref-hashing.ts +117 -0
- 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 +214 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +109 -66
- package/src/vite/plugins/expose-id-utils.ts +303 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +320 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +209 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +127 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +816 -0
- package/src/vite/plugins/performance-tracks.ts +92 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +336 -0
- package/src/vite/plugins/version-injector.ts +109 -0
- package/src/vite/plugins/version-plugin.ts +323 -0
- package/src/vite/plugins/virtual-entries.ts +123 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +509 -0
- package/src/vite/router-discovery.ts +1511 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +139 -0
- package/src/vite/utils/forward-user-plugins.ts +193 -0
- package/src/vite/utils/manifest-utils.ts +86 -0
- package/src/vite/utils/package-resolution.ts +161 -0
- package/src/vite/utils/prerender-utils.ts +222 -0
- package/src/vite/utils/shared-utils.ts +174 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/router.gen.ts +0 -6
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -426
- package/src/vite/expose-location-state-id.ts +0 -177
- package/src/vite/expose-prerender-handler-id.ts +0 -429
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -1,442 +1,48 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
NavigationBridge,
|
|
3
3
|
NavigationBridgeConfig,
|
|
4
|
-
|
|
5
|
-
NavigationStore,
|
|
4
|
+
NavigateOptionsInternal,
|
|
6
5
|
ResolvedSegment,
|
|
7
6
|
} from "./types.js";
|
|
7
|
+
import { setAppVersion } from "./app-version.js";
|
|
8
|
+
import { setRangoStateLocal } from "./rango-state.js";
|
|
9
|
+
import type { AppShell, AppShellRef } from "./app-shell.js";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { startTransition } from "react";
|
|
8
12
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "./
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
): state is Record<string, unknown> {
|
|
19
|
-
if (state === null || typeof state !== "object") return false;
|
|
20
|
-
return Object.keys(state).some((key) => key.startsWith("__rsc_ls_"));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Resolve navigation state - handles both LocationStateEntry[] and legacy formats
|
|
25
|
-
*/
|
|
26
|
-
function resolveNavigationState(state: unknown): unknown {
|
|
27
|
-
// Check if it's an array of LocationStateEntry
|
|
28
|
-
if (
|
|
29
|
-
Array.isArray(state) &&
|
|
30
|
-
state.length > 0 &&
|
|
31
|
-
isLocationStateEntry(state[0])
|
|
32
|
-
) {
|
|
33
|
-
return resolveLocationStateEntries(state);
|
|
34
|
-
}
|
|
35
|
-
// Return as-is for legacy formats
|
|
36
|
-
return state;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Build history state object from user state
|
|
41
|
-
* - Typed state: spread directly into history.state
|
|
42
|
-
* - Legacy state: store in history.state.state
|
|
43
|
-
*/
|
|
44
|
-
function buildHistoryState(
|
|
45
|
-
userState: unknown,
|
|
46
|
-
routerState?: { intercept?: boolean; sourceUrl?: string }
|
|
47
|
-
): Record<string, unknown> | null {
|
|
48
|
-
const result: Record<string, unknown> = {};
|
|
49
|
-
|
|
50
|
-
// Add router internal state
|
|
51
|
-
if (routerState?.intercept) {
|
|
52
|
-
result.intercept = true;
|
|
53
|
-
if (routerState.sourceUrl) {
|
|
54
|
-
result.sourceUrl = routerState.sourceUrl;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
13
|
+
createNavigationTransaction,
|
|
14
|
+
resolveNavigationState,
|
|
15
|
+
} from "./navigation-transaction.js";
|
|
16
|
+
import { buildHistoryState, pushHistoryWithIdx } from "./history-state.js";
|
|
17
|
+
import {
|
|
18
|
+
handleNavigationStart,
|
|
19
|
+
handleNavigationEnd,
|
|
20
|
+
ensureHistoryKey,
|
|
21
|
+
} from "./scroll-restoration.js";
|
|
57
22
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// Typed state: spread directly
|
|
62
|
-
Object.assign(result, userState);
|
|
63
|
-
} else {
|
|
64
|
-
// Legacy state: store in .state
|
|
65
|
-
result.state = userState;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
23
|
+
// addTransitionType is only available in React experimental
|
|
24
|
+
const addTransitionType: ((type: string) => void) | undefined =
|
|
25
|
+
"addTransitionType" in React ? (React as any).addTransitionType : undefined;
|
|
68
26
|
|
|
69
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
70
|
-
}
|
|
71
27
|
import { setupLinkInterception } from "./link-interceptor.js";
|
|
72
28
|
import { createPartialUpdater } from "./partial-update.js";
|
|
73
29
|
import { generateHistoryKey } from "./navigation-store.js";
|
|
30
|
+
import type { EventController } from "./event-controller.js";
|
|
31
|
+
import { isInterceptOnlyCache } from "./intercept-utils.js";
|
|
74
32
|
import {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
} from "./
|
|
79
|
-
import
|
|
80
|
-
import {
|
|
81
|
-
import {
|
|
82
|
-
import { createElement, startTransition } from "react";
|
|
33
|
+
toNetworkError,
|
|
34
|
+
emitNetworkError,
|
|
35
|
+
isBackgroundSuppressible,
|
|
36
|
+
} from "./network-error-handler.js";
|
|
37
|
+
import { debugLog } from "./logging.js";
|
|
38
|
+
import { ServerRedirect } from "../errors.js";
|
|
39
|
+
import { validateRedirectOrigin } from "./validate-redirect-origin.js";
|
|
83
40
|
|
|
84
41
|
// Polyfill Symbol.dispose for Safari and older browsers
|
|
85
42
|
if (typeof Symbol.dispose === "undefined") {
|
|
86
43
|
(Symbol as any).dispose = Symbol("Symbol.dispose");
|
|
87
44
|
}
|
|
88
45
|
|
|
89
|
-
/**
|
|
90
|
-
* Check if a segment is an intercept segment
|
|
91
|
-
* Intercept segments have namespace starting with "intercept:" or ID containing .@
|
|
92
|
-
*/
|
|
93
|
-
function isInterceptSegment(s: ResolvedSegment): boolean {
|
|
94
|
-
return (
|
|
95
|
-
s.namespace?.startsWith("intercept:") ||
|
|
96
|
-
(s.type === "parallel" && s.id.includes(".@"))
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Check if cached segments are intercept-only (no main route segments)
|
|
102
|
-
* Intercept responses shouldn't be used for optimistic rendering since
|
|
103
|
-
* whether interception happens depends on the current page context
|
|
104
|
-
*/
|
|
105
|
-
function isInterceptOnlyCache(segments: ResolvedSegment[]): boolean {
|
|
106
|
-
return segments.some(isInterceptSegment);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Options for committing a navigation transaction
|
|
111
|
-
*/
|
|
112
|
-
interface CommitOptions {
|
|
113
|
-
url: string;
|
|
114
|
-
segmentIds: string[];
|
|
115
|
-
segments: ResolvedSegment[];
|
|
116
|
-
replace?: boolean;
|
|
117
|
-
scroll?: boolean;
|
|
118
|
-
/** User-provided state to store in history.state */
|
|
119
|
-
state?: unknown;
|
|
120
|
-
/** If true, only update store without changing URL/history (for server actions) */
|
|
121
|
-
storeOnly?: boolean;
|
|
122
|
-
/** If true, this is an intercept route - store in history.state for popstate handling */
|
|
123
|
-
intercept?: boolean;
|
|
124
|
-
/** Source URL where the intercept was triggered from (stored in history.state) */
|
|
125
|
-
interceptSourceUrl?: string;
|
|
126
|
-
/** If true, only update cache without touching store or history (for background stale revalidation) */
|
|
127
|
-
cacheOnly?: boolean;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Options that can override the pre-configured commit settings
|
|
132
|
-
*/
|
|
133
|
-
interface BoundCommitOverrides {
|
|
134
|
-
/** Override scroll behavior (e.g., disable for intercepts) */
|
|
135
|
-
scroll?: boolean;
|
|
136
|
-
/** Override replace behavior (e.g., force replace for intercepts) */
|
|
137
|
-
replace?: boolean;
|
|
138
|
-
/** Override user-provided state */
|
|
139
|
-
state?: unknown;
|
|
140
|
-
/** Mark this as an intercept route */
|
|
141
|
-
intercept?: boolean;
|
|
142
|
-
/** Source URL where intercept was triggered from */
|
|
143
|
-
interceptSourceUrl?: string;
|
|
144
|
-
/** If true, only update cache (for stale revalidation) */
|
|
145
|
-
cacheOnly?: boolean;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Token for tracking an active stream - call end() when stream completes
|
|
150
|
-
*/
|
|
151
|
-
export interface StreamingToken {
|
|
152
|
-
end(): void;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Bound transaction with pre-configured commit options (without segmentIds/segments)
|
|
157
|
-
*/
|
|
158
|
-
export interface BoundTransaction {
|
|
159
|
-
readonly currentUrl: string;
|
|
160
|
-
/** Start streaming and get a token to end it when the stream completes */
|
|
161
|
-
startStreaming(): StreamingToken;
|
|
162
|
-
commit(
|
|
163
|
-
segmentIds: string[],
|
|
164
|
-
segments: ResolvedSegment[],
|
|
165
|
-
overrides?: BoundCommitOverrides
|
|
166
|
-
): void;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Navigation transaction for managing state during navigation
|
|
171
|
-
* Uses the event controller handle for lifecycle management
|
|
172
|
-
*/
|
|
173
|
-
interface NavigationTransaction extends Disposable {
|
|
174
|
-
/** Optimistically commit from cache - instant render before revalidation */
|
|
175
|
-
optimisticCommit(options: CommitOptions): void;
|
|
176
|
-
/** Final commit with server data (or reconciliation after optimistic) */
|
|
177
|
-
commit(options: CommitOptions): void;
|
|
178
|
-
with(
|
|
179
|
-
options: Omit<CommitOptions, "segmentIds" | "segments">
|
|
180
|
-
): BoundTransaction;
|
|
181
|
-
/** The navigation handle from the event controller */
|
|
182
|
-
handle: NavigationHandle;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Creates a navigation transaction that coordinates with the event controller.
|
|
187
|
-
* Handles loading state transitions and cleanup on completion/abort.
|
|
188
|
-
*
|
|
189
|
-
* Supports optimistic navigation: render from cache immediately,
|
|
190
|
-
* then revalidate in background and reconcile if data changed.
|
|
191
|
-
*/
|
|
192
|
-
function createNavigationTransaction(
|
|
193
|
-
store: NavigationStore,
|
|
194
|
-
eventController: EventController,
|
|
195
|
-
url: string,
|
|
196
|
-
options?: NavigateOptions & { skipLoadingState?: boolean }
|
|
197
|
-
): NavigationTransaction {
|
|
198
|
-
let committed = false;
|
|
199
|
-
let optimisticallyCommitted = false;
|
|
200
|
-
let earlyStatePushed = false;
|
|
201
|
-
const currentUrl = window.location.href;
|
|
202
|
-
|
|
203
|
-
// Start navigation in event controller (this sets loading state)
|
|
204
|
-
const handle = eventController.startNavigation(url, options);
|
|
205
|
-
|
|
206
|
-
// If state is provided, push it to history immediately so loading UI can access it
|
|
207
|
-
// This enables "optimistic state" - showing product names in skeletons etc.
|
|
208
|
-
if (options?.state !== undefined && !options?.replace) {
|
|
209
|
-
const earlyHistoryState = buildHistoryState(options.state);
|
|
210
|
-
window.history.pushState(earlyHistoryState, "", url);
|
|
211
|
-
earlyStatePushed = true;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Optimistically commit from cache - renders immediately before revalidation
|
|
216
|
-
* Sets optimisticallyCommitted flag so final commit() knows to reconcile
|
|
217
|
-
*/
|
|
218
|
-
function optimisticCommit(opts: CommitOptions): void {
|
|
219
|
-
optimisticallyCommitted = true;
|
|
220
|
-
|
|
221
|
-
const { url, segmentIds, segments, replace, scroll } = opts;
|
|
222
|
-
const parsedUrl = new URL(url, window.location.origin);
|
|
223
|
-
|
|
224
|
-
// Save current scroll position before navigating
|
|
225
|
-
handleNavigationStart();
|
|
226
|
-
|
|
227
|
-
// Update segment state
|
|
228
|
-
store.setSegmentIds(segmentIds);
|
|
229
|
-
store.setCurrentUrl(url);
|
|
230
|
-
store.setPath(parsedUrl.pathname);
|
|
231
|
-
|
|
232
|
-
// Generate history key from URL
|
|
233
|
-
const historyKey = generateHistoryKey(url);
|
|
234
|
-
store.setHistoryKey(historyKey);
|
|
235
|
-
|
|
236
|
-
// Cache segments with current handleData (will be overwritten by fresh data on final commit)
|
|
237
|
-
const currentHandleData = eventController.getHandleState().data;
|
|
238
|
-
store.cacheSegmentsForHistory(historyKey, segments, currentHandleData);
|
|
239
|
-
|
|
240
|
-
// Build history state with user state if provided
|
|
241
|
-
const historyState = buildHistoryState(opts.state);
|
|
242
|
-
|
|
243
|
-
// Update browser URL
|
|
244
|
-
// Use replaceState if we already pushed early (for optimistic state access)
|
|
245
|
-
if (replace || earlyStatePushed) {
|
|
246
|
-
window.history.replaceState(historyState, "", url);
|
|
247
|
-
} else {
|
|
248
|
-
window.history.pushState(historyState, "", url);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Ensure new history entry has a scroll restoration key
|
|
252
|
-
ensureHistoryKey();
|
|
253
|
-
|
|
254
|
-
// Complete the navigation in event controller (sets idle state)
|
|
255
|
-
handle.complete(parsedUrl);
|
|
256
|
-
|
|
257
|
-
// Handle scroll after navigation
|
|
258
|
-
handleNavigationEnd({ scroll });
|
|
259
|
-
|
|
260
|
-
console.log(
|
|
261
|
-
"[Browser] Optimistic commit from cache, historyKey:",
|
|
262
|
-
historyKey
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Commit the navigation - updates store and URL atomically
|
|
268
|
-
* If optimisticCommit was called, this becomes a reconciliation
|
|
269
|
-
*/
|
|
270
|
-
function commit(opts: CommitOptions): void {
|
|
271
|
-
committed = true;
|
|
272
|
-
|
|
273
|
-
// If optimistic commit already done, adjust options for reconciliation
|
|
274
|
-
const isReconciliation = optimisticallyCommitted;
|
|
275
|
-
const {
|
|
276
|
-
url,
|
|
277
|
-
segmentIds,
|
|
278
|
-
segments,
|
|
279
|
-
storeOnly,
|
|
280
|
-
intercept,
|
|
281
|
-
interceptSourceUrl,
|
|
282
|
-
cacheOnly,
|
|
283
|
-
} = opts;
|
|
284
|
-
// For reconciliation: always replace (URL already pushed), no scroll
|
|
285
|
-
const replace = isReconciliation ? true : opts.replace;
|
|
286
|
-
const scroll = isReconciliation ? false : opts.scroll;
|
|
287
|
-
|
|
288
|
-
const parsedUrl = new URL(url, window.location.origin);
|
|
289
|
-
|
|
290
|
-
// Generate history key from URL (with intercept suffix for separate caching)
|
|
291
|
-
const historyKey = generateHistoryKey(url, { intercept });
|
|
292
|
-
|
|
293
|
-
// For cache-only commits (stale revalidation), only update cache and return
|
|
294
|
-
// Don't touch store state or history - user may have navigated elsewhere
|
|
295
|
-
if (cacheOnly) {
|
|
296
|
-
const currentHandleData = eventController.getHandleState().data;
|
|
297
|
-
store.cacheSegmentsForHistory(historyKey, segments, currentHandleData);
|
|
298
|
-
console.log("[Browser] Cache-only commit, historyKey:", historyKey);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// Save current scroll position before navigating (only for non-reconciliation)
|
|
303
|
-
if (!isReconciliation) {
|
|
304
|
-
handleNavigationStart();
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Update segment state atomically
|
|
308
|
-
store.setSegmentIds(segmentIds);
|
|
309
|
-
store.setCurrentUrl(url);
|
|
310
|
-
store.setPath(parsedUrl.pathname);
|
|
311
|
-
|
|
312
|
-
store.setHistoryKey(historyKey);
|
|
313
|
-
|
|
314
|
-
// Cache segments with current handleData for this history entry (fresh data overwrites optimistic)
|
|
315
|
-
const currentHandleData = eventController.getHandleState().data;
|
|
316
|
-
store.cacheSegmentsForHistory(historyKey, segments, currentHandleData);
|
|
317
|
-
|
|
318
|
-
// For server actions, skip URL/history updates but still complete navigation
|
|
319
|
-
if (storeOnly) {
|
|
320
|
-
console.log("[Browser] Store updated (action)");
|
|
321
|
-
// Complete navigation to clear loading state
|
|
322
|
-
handle.complete(parsedUrl);
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Build history state - include user state and intercept info for popstate handling
|
|
327
|
-
const historyState = buildHistoryState(opts.state, {
|
|
328
|
-
intercept,
|
|
329
|
-
sourceUrl: interceptSourceUrl,
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// Update browser URL (skip if reconciliation - already done in optimisticCommit)
|
|
333
|
-
if (!isReconciliation) {
|
|
334
|
-
// Use replaceState if we already pushed early (for optimistic state access) or replace requested
|
|
335
|
-
if (replace || earlyStatePushed) {
|
|
336
|
-
window.history.replaceState(historyState, "", url);
|
|
337
|
-
} else {
|
|
338
|
-
window.history.pushState(historyState, "", url);
|
|
339
|
-
}
|
|
340
|
-
// Ensure new history entry has a scroll restoration key
|
|
341
|
-
ensureHistoryKey();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Complete the navigation in event controller (sets idle state, updates location)
|
|
345
|
-
handle.complete(parsedUrl);
|
|
346
|
-
|
|
347
|
-
// Handle scroll after navigation (skip if reconciliation)
|
|
348
|
-
if (!isReconciliation) {
|
|
349
|
-
handleNavigationEnd({ scroll });
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (isReconciliation) {
|
|
353
|
-
console.log("[Browser] Reconciliation commit, historyKey:", historyKey);
|
|
354
|
-
} else {
|
|
355
|
-
console.log(
|
|
356
|
-
"[Browser] Navigation committed, historyKey:",
|
|
357
|
-
historyKey,
|
|
358
|
-
intercept ? "(intercept)" : ""
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return {
|
|
364
|
-
handle,
|
|
365
|
-
optimisticCommit,
|
|
366
|
-
commit,
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Create a bound transaction with pre-configured URL options
|
|
370
|
-
* segmentIds and segments provided at commit time (after they're resolved)
|
|
371
|
-
*/
|
|
372
|
-
with(
|
|
373
|
-
opts: Omit<CommitOptions, "segmentIds" | "segments">
|
|
374
|
-
): BoundTransaction {
|
|
375
|
-
return {
|
|
376
|
-
get currentUrl() {
|
|
377
|
-
return currentUrl;
|
|
378
|
-
},
|
|
379
|
-
startStreaming() {
|
|
380
|
-
return handle.startStreaming();
|
|
381
|
-
},
|
|
382
|
-
commit: (
|
|
383
|
-
segmentIds: string[],
|
|
384
|
-
segments: ResolvedSegment[],
|
|
385
|
-
overrides?: BoundCommitOverrides
|
|
386
|
-
) => {
|
|
387
|
-
// Allow overrides to disable scroll (e.g., for intercepts)
|
|
388
|
-
const finalScroll =
|
|
389
|
-
overrides?.scroll !== undefined ? overrides.scroll : opts.scroll;
|
|
390
|
-
// Allow overrides to force replace (e.g., for intercepts)
|
|
391
|
-
const finalReplace =
|
|
392
|
-
overrides?.replace !== undefined ? overrides.replace : opts.replace;
|
|
393
|
-
// Intercept info: overrides take precedence, fallback to opts
|
|
394
|
-
const intercept =
|
|
395
|
-
overrides?.intercept !== undefined
|
|
396
|
-
? overrides.intercept
|
|
397
|
-
: opts.intercept;
|
|
398
|
-
const interceptSourceUrl =
|
|
399
|
-
overrides?.interceptSourceUrl !== undefined
|
|
400
|
-
? overrides.interceptSourceUrl
|
|
401
|
-
: opts.interceptSourceUrl;
|
|
402
|
-
// Cache-only mode: overrides take precedence, fallback to opts
|
|
403
|
-
const cacheOnly =
|
|
404
|
-
overrides?.cacheOnly !== undefined
|
|
405
|
-
? overrides.cacheOnly
|
|
406
|
-
: opts.cacheOnly;
|
|
407
|
-
// User state: overrides take precedence, fallback to opts
|
|
408
|
-
const state =
|
|
409
|
-
overrides?.state !== undefined ? overrides.state : opts.state;
|
|
410
|
-
commit({
|
|
411
|
-
...opts,
|
|
412
|
-
segmentIds,
|
|
413
|
-
segments,
|
|
414
|
-
scroll: finalScroll,
|
|
415
|
-
replace: finalReplace,
|
|
416
|
-
state,
|
|
417
|
-
intercept,
|
|
418
|
-
interceptSourceUrl,
|
|
419
|
-
cacheOnly,
|
|
420
|
-
});
|
|
421
|
-
},
|
|
422
|
-
};
|
|
423
|
-
},
|
|
424
|
-
|
|
425
|
-
[Symbol.dispose]() {
|
|
426
|
-
// If aborted, another navigation took over - don't touch state
|
|
427
|
-
if (handle.signal.aborted) return;
|
|
428
|
-
|
|
429
|
-
// If not committed (and not optimistically committed), the handle's dispose
|
|
430
|
-
// will reset state to idle via the event controller
|
|
431
|
-
if (!committed && !optimisticallyCommitted) {
|
|
432
|
-
handle[Symbol.dispose]();
|
|
433
|
-
// The NavigationHandle's [Symbol.dispose] handles this
|
|
434
|
-
}
|
|
435
|
-
},
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// Export for use by server-action-bridge
|
|
440
46
|
export { createNavigationTransaction };
|
|
441
47
|
|
|
442
48
|
/**
|
|
@@ -444,8 +50,13 @@ export { createNavigationTransaction };
|
|
|
444
50
|
*/
|
|
445
51
|
export interface NavigationBridgeConfigWithController extends NavigationBridgeConfig {
|
|
446
52
|
eventController: EventController;
|
|
447
|
-
/** RSC version from initial payload metadata */
|
|
53
|
+
/** RSC version from initial payload metadata (fallback when appShellRef is not provided) */
|
|
448
54
|
version?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Live app-shell ref. When supplied, the bridge reads version/basename
|
|
57
|
+
* from this ref so cross-app navigations propagate correctly.
|
|
58
|
+
*/
|
|
59
|
+
appShellRef?: AppShellRef;
|
|
449
60
|
}
|
|
450
61
|
|
|
451
62
|
/**
|
|
@@ -462,9 +73,47 @@ export interface NavigationBridgeConfigWithController extends NavigationBridgeCo
|
|
|
462
73
|
* @returns NavigationBridge instance
|
|
463
74
|
*/
|
|
464
75
|
export function createNavigationBridge(
|
|
465
|
-
config: NavigationBridgeConfigWithController
|
|
76
|
+
config: NavigationBridgeConfigWithController,
|
|
466
77
|
): NavigationBridge {
|
|
467
|
-
const {
|
|
78
|
+
const {
|
|
79
|
+
store,
|
|
80
|
+
client,
|
|
81
|
+
eventController,
|
|
82
|
+
onUpdate,
|
|
83
|
+
renderSegments,
|
|
84
|
+
appShellRef,
|
|
85
|
+
} = config;
|
|
86
|
+
let version = config.version;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Replace the active app-shell snapshot atomically. Called by the partial
|
|
90
|
+
* updater when a response's routerId indicates the navigation crossed
|
|
91
|
+
* into a different app. Runs the local-only side-effects tied to
|
|
92
|
+
* app-shell fields (app version, rango-state namespace) so the new app
|
|
93
|
+
* owns them after the swap. Theme, warmup, and prefetch TTL are
|
|
94
|
+
* document-lifetime and are NOT touched here.
|
|
95
|
+
*/
|
|
96
|
+
function applyAppShell(next: AppShell): void {
|
|
97
|
+
if (appShellRef) {
|
|
98
|
+
appShellRef.update(next);
|
|
99
|
+
}
|
|
100
|
+
if (next.version !== undefined) {
|
|
101
|
+
version = next.version;
|
|
102
|
+
setAppVersion(next.version);
|
|
103
|
+
// Use the local-only setter — initRangoState writes the shared
|
|
104
|
+
// localStorage key and fires a storage event in other tabs still in
|
|
105
|
+
// the old app. setRangoStateLocal only mutates this tab's in-memory
|
|
106
|
+
// cache and rebinds it to the target app's routerId-scoped key,
|
|
107
|
+
// preserving the "local-only, no broadcast/rotation" contract for
|
|
108
|
+
// smooth app-switch transitions.
|
|
109
|
+
setRangoStateLocal(next.version, next.routerId);
|
|
110
|
+
}
|
|
111
|
+
// Cross-app: prior cache entries belong to a different app's segments.
|
|
112
|
+
// Drop them locally only — do NOT broadcast invalidation or rotate the
|
|
113
|
+
// shared X-Rango-State token, since other tabs still in the old app are
|
|
114
|
+
// unaffected by this tab's transition.
|
|
115
|
+
store.clearHistoryCacheLocal();
|
|
116
|
+
}
|
|
468
117
|
|
|
469
118
|
// Create shared partial updater
|
|
470
119
|
const fetchPartialUpdate = createPartialUpdater({
|
|
@@ -472,25 +121,124 @@ export function createNavigationBridge(
|
|
|
472
121
|
client,
|
|
473
122
|
onUpdate,
|
|
474
123
|
renderSegments,
|
|
475
|
-
version,
|
|
124
|
+
getVersion: () => version,
|
|
125
|
+
applyAppShell,
|
|
476
126
|
});
|
|
477
127
|
|
|
478
128
|
return {
|
|
479
129
|
/**
|
|
480
130
|
* Navigate to a URL
|
|
481
|
-
* Uses
|
|
131
|
+
* Uses cached segments for SWR revalidation when available
|
|
482
132
|
*/
|
|
483
|
-
async navigate(
|
|
133
|
+
async navigate(
|
|
134
|
+
url: string,
|
|
135
|
+
options?: NavigateOptionsInternal,
|
|
136
|
+
): Promise<void> {
|
|
484
137
|
// Resolve LocationStateEntry[] to flat object if needed
|
|
485
138
|
const resolvedState =
|
|
486
139
|
options?.state !== undefined
|
|
487
140
|
? resolveNavigationState(options.state)
|
|
488
141
|
: undefined;
|
|
489
142
|
|
|
143
|
+
// Cross-origin URLs are not handled by SPA navigation.
|
|
144
|
+
// Fall back to a full browser navigation for http/https only.
|
|
145
|
+
let targetUrl: URL;
|
|
146
|
+
try {
|
|
147
|
+
targetUrl = new URL(url, window.location.origin);
|
|
148
|
+
} catch {
|
|
149
|
+
console.warn(`[rango] navigate() ignored: malformed URL "${url}"`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (targetUrl.origin !== window.location.origin) {
|
|
153
|
+
if (targetUrl.protocol !== "http:" && targetUrl.protocol !== "https:") {
|
|
154
|
+
console.error(
|
|
155
|
+
`[rango] navigate() blocked: unsupported scheme "${targetUrl.protocol}"`,
|
|
156
|
+
);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
window.location.href = targetUrl.href;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Shallow navigation: skip RSC fetch when revalidate is false
|
|
164
|
+
// and the pathname hasn't changed (search param / hash only change).
|
|
165
|
+
if (
|
|
166
|
+
options?.revalidate === false &&
|
|
167
|
+
targetUrl.pathname === new URL(window.location.href).pathname
|
|
168
|
+
) {
|
|
169
|
+
// Preserve intercept context from the current history entry so that
|
|
170
|
+
// popstate uses the correct cache key (:intercept suffix) and restores
|
|
171
|
+
// the right full-page vs modal semantics.
|
|
172
|
+
const currentHistoryState = window.history.state;
|
|
173
|
+
const isIntercept = currentHistoryState?.intercept === true;
|
|
174
|
+
const interceptSourceUrl = isIntercept
|
|
175
|
+
? currentHistoryState?.sourceUrl
|
|
176
|
+
: undefined;
|
|
177
|
+
|
|
178
|
+
const historyKey = generateHistoryKey(url, { intercept: isIntercept });
|
|
179
|
+
|
|
180
|
+
// Copy current segments to the new history key so back/forward restores instantly
|
|
181
|
+
const currentKey = store.getHistoryKey();
|
|
182
|
+
const currentCache = store.getCachedSegments(currentKey);
|
|
183
|
+
if (currentCache?.segments) {
|
|
184
|
+
const currentHandleData = eventController.getHandleState().data;
|
|
185
|
+
store.cacheSegmentsForHistory(
|
|
186
|
+
historyKey,
|
|
187
|
+
currentCache.segments,
|
|
188
|
+
currentHandleData,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Save current scroll position before changing URL
|
|
193
|
+
handleNavigationStart();
|
|
194
|
+
|
|
195
|
+
// Snapshot old state before pushState/replaceState overwrites it
|
|
196
|
+
const oldState = window.history.state;
|
|
197
|
+
|
|
198
|
+
// Update browser URL (carry intercept context into history state)
|
|
199
|
+
const historyState = buildHistoryState(
|
|
200
|
+
resolvedState,
|
|
201
|
+
{
|
|
202
|
+
intercept: isIntercept || undefined,
|
|
203
|
+
sourceUrl: interceptSourceUrl,
|
|
204
|
+
},
|
|
205
|
+
{},
|
|
206
|
+
);
|
|
207
|
+
pushHistoryWithIdx(historyState, url, options?.replace ?? false);
|
|
208
|
+
|
|
209
|
+
// Ensure new history entry has a scroll restoration key
|
|
210
|
+
ensureHistoryKey();
|
|
211
|
+
|
|
212
|
+
// Notify useLocationState() hooks when state changes
|
|
213
|
+
const hasOldState =
|
|
214
|
+
oldState &&
|
|
215
|
+
typeof oldState === "object" &&
|
|
216
|
+
("state" in oldState ||
|
|
217
|
+
Object.keys(oldState).some((k) => k.startsWith("__rsc_ls_")));
|
|
218
|
+
const hasNewState =
|
|
219
|
+
historyState &&
|
|
220
|
+
("state" in historyState ||
|
|
221
|
+
Object.keys(historyState).some((k) => k.startsWith("__rsc_ls_")));
|
|
222
|
+
if (hasOldState || hasNewState) {
|
|
223
|
+
window.dispatchEvent(new Event("__rsc_locationstate"));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Update store history key so future navigations reference the right cache
|
|
227
|
+
store.setHistoryKey(historyKey);
|
|
228
|
+
store.setCurrentUrl(url);
|
|
229
|
+
|
|
230
|
+
// Notify hooks — location updates, state stays idle
|
|
231
|
+
eventController.setLocation(targetUrl);
|
|
232
|
+
|
|
233
|
+
// Handle post-navigation scroll
|
|
234
|
+
handleNavigationEnd({ scroll: options.scroll });
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
490
238
|
// Only abort pending requests when navigating to a different route
|
|
491
239
|
// Same-route navigation (e.g., /todos -> /todos) should not cancel in-flight actions
|
|
492
240
|
const currentPath = new URL(window.location.href).pathname;
|
|
493
|
-
const targetPath =
|
|
241
|
+
const targetPath = targetUrl.pathname;
|
|
494
242
|
if (currentPath !== targetPath) {
|
|
495
243
|
eventController.abortNavigation();
|
|
496
244
|
}
|
|
@@ -503,7 +251,9 @@ export function createNavigationBridge(
|
|
|
503
251
|
const isLeavingIntercept = isCurrentlyIntercept && isSamePathNavigation;
|
|
504
252
|
|
|
505
253
|
if (isLeavingIntercept) {
|
|
506
|
-
|
|
254
|
+
debugLog(
|
|
255
|
+
"[Browser] Leaving intercept - same URL navigation from intercept",
|
|
256
|
+
);
|
|
507
257
|
// Clear intercept source URL to ensure server doesn't treat this as intercept
|
|
508
258
|
store.setInterceptSourceUrl(null);
|
|
509
259
|
}
|
|
@@ -517,7 +267,7 @@ export function createNavigationBridge(
|
|
|
517
267
|
store.cacheSegmentsForHistory(
|
|
518
268
|
sourceHistoryKey,
|
|
519
269
|
sourceCached.segments,
|
|
520
|
-
currentHandleData
|
|
270
|
+
currentHandleData,
|
|
521
271
|
);
|
|
522
272
|
}
|
|
523
273
|
|
|
@@ -532,7 +282,7 @@ export function createNavigationBridge(
|
|
|
532
282
|
const cachedHandleData = cached?.handleData;
|
|
533
283
|
if (cachedSegments && sourceCached?.segments) {
|
|
534
284
|
const sourceSegmentMap = new Map(
|
|
535
|
-
sourceCached.segments.map((s) => [s.id, s])
|
|
285
|
+
sourceCached.segments.map((s) => [s.id, s]),
|
|
536
286
|
);
|
|
537
287
|
cachedSegments = cachedSegments.map((targetSeg) => {
|
|
538
288
|
const sourceSeg = sourceSegmentMap.get(targetSeg.id);
|
|
@@ -547,28 +297,40 @@ export function createNavigationBridge(
|
|
|
547
297
|
const interceptHistoryKey = generateHistoryKey(url, { intercept: true });
|
|
548
298
|
const hasInterceptCache = store.hasHistoryCache(interceptHistoryKey);
|
|
549
299
|
|
|
550
|
-
// Skip
|
|
300
|
+
// Skip cached SWR for:
|
|
551
301
|
// 1. intercept caches - interception depends on source page context
|
|
552
302
|
// 2. routes that CAN be intercepted - we don't know if this navigation will intercept
|
|
553
303
|
// 3. when leaving intercept - we need fresh non-intercept segments from server
|
|
304
|
+
// 4. redirect-with-state - force re-render so hooks read fresh state
|
|
305
|
+
// 5. stale cache - server action invalidated it, need fresh data with loading state
|
|
554
306
|
const hasUsableCache =
|
|
555
307
|
cachedSegments &&
|
|
556
308
|
cachedSegments.length > 0 &&
|
|
557
309
|
!isInterceptOnlyCache(cachedSegments) &&
|
|
558
310
|
!hasInterceptCache &&
|
|
559
|
-
!isLeavingIntercept
|
|
560
|
-
|
|
561
|
-
|
|
311
|
+
!isLeavingIntercept &&
|
|
312
|
+
!cached?.stale &&
|
|
313
|
+
!options?._skipCache;
|
|
314
|
+
|
|
315
|
+
// Forward navigations always await fetchPartialUpdate before rendering,
|
|
316
|
+
// so useNavigation should always report "loading". skipLoadingState is
|
|
317
|
+
// only used for popstate background revalidation (line ~526) where
|
|
318
|
+
// cached content renders instantly without a network wait.
|
|
319
|
+
const tx = createNavigationTransaction(store, eventController, url, {
|
|
562
320
|
...options,
|
|
563
321
|
state: resolvedState,
|
|
564
|
-
skipLoadingState:
|
|
322
|
+
skipLoadingState: false,
|
|
565
323
|
});
|
|
566
324
|
|
|
567
325
|
// REVALIDATE: Fetch fresh data from server
|
|
568
326
|
try {
|
|
569
327
|
await fetchPartialUpdate(
|
|
570
328
|
url,
|
|
571
|
-
hasUsableCache
|
|
329
|
+
hasUsableCache
|
|
330
|
+
? cachedSegments!.map((s) => s.id)
|
|
331
|
+
: options?._skipCache
|
|
332
|
+
? [] // Action redirect: send no segments so server renders everything fresh
|
|
333
|
+
: undefined,
|
|
572
334
|
false,
|
|
573
335
|
tx.handle.signal,
|
|
574
336
|
tx.with({
|
|
@@ -577,55 +339,56 @@ export function createNavigationBridge(
|
|
|
577
339
|
scroll: options?.scroll,
|
|
578
340
|
state: resolvedState,
|
|
579
341
|
}),
|
|
580
|
-
// Pass cached segments (merged with current page's fresh segments for shared IDs)
|
|
581
|
-
// so the segment map is consistent with what we tell the server we have.
|
|
582
|
-
// Server decides what needs revalidation based on route matching and custom functions.
|
|
583
|
-
// No need for staleRevalidation flag - we're sending the freshest segments we have.
|
|
584
|
-
// Also pass cached handle data for restoring breadcrumbs when server returns empty diff.
|
|
585
|
-
// When leaving intercept, pass the flag so fetchPartialUpdate knows to filter segments.
|
|
586
342
|
hasUsableCache
|
|
587
|
-
? {
|
|
343
|
+
? {
|
|
344
|
+
type: "navigate" as const,
|
|
345
|
+
targetCacheSegments: cachedSegments,
|
|
346
|
+
targetCacheHandleData: cachedHandleData,
|
|
347
|
+
}
|
|
588
348
|
: isLeavingIntercept
|
|
589
|
-
? {
|
|
590
|
-
: undefined
|
|
349
|
+
? { type: "leave-intercept" as const }
|
|
350
|
+
: undefined,
|
|
591
351
|
);
|
|
592
352
|
} catch (error) {
|
|
593
|
-
//
|
|
353
|
+
// Server-side redirect with location state: the current transaction's
|
|
354
|
+
// cleanup resets loading state. Re-navigate to the redirect
|
|
355
|
+
// target carrying the server-set state into history.pushState.
|
|
356
|
+
if (error instanceof ServerRedirect) {
|
|
357
|
+
const redirectUrl = validateRedirectOrigin(
|
|
358
|
+
error.url,
|
|
359
|
+
window.location.origin,
|
|
360
|
+
);
|
|
361
|
+
if (!redirectUrl) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
return this.navigate(redirectUrl, {
|
|
365
|
+
state: error.state,
|
|
366
|
+
replace: options?.replace,
|
|
367
|
+
_skipCache: true,
|
|
368
|
+
} as NavigateOptionsInternal);
|
|
369
|
+
}
|
|
370
|
+
|
|
594
371
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
595
|
-
|
|
372
|
+
debugLog("[Browser] Navigation aborted by newer navigation");
|
|
596
373
|
return;
|
|
597
374
|
}
|
|
598
375
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
: new NetworkError(
|
|
605
|
-
"Unable to connect to server. Please check your connection.",
|
|
606
|
-
{ cause: error, url, operation: "navigation" }
|
|
607
|
-
);
|
|
608
|
-
|
|
376
|
+
const networkError = toNetworkError(error, {
|
|
377
|
+
url,
|
|
378
|
+
operation: "navigation",
|
|
379
|
+
});
|
|
380
|
+
if (networkError) {
|
|
609
381
|
console.error(
|
|
610
382
|
"[Browser] Network error during navigation:",
|
|
611
|
-
networkError
|
|
383
|
+
networkError,
|
|
612
384
|
);
|
|
613
|
-
|
|
614
|
-
// Emit update with NetworkErrorThrower to trigger root error boundary
|
|
615
|
-
startTransition(() => {
|
|
616
|
-
onUpdate({
|
|
617
|
-
root: createElement(NetworkErrorThrower, { error: networkError }),
|
|
618
|
-
metadata: {
|
|
619
|
-
pathname: url,
|
|
620
|
-
segments: [],
|
|
621
|
-
isError: true,
|
|
622
|
-
},
|
|
623
|
-
});
|
|
624
|
-
});
|
|
385
|
+
emitNetworkError(onUpdate, networkError, url);
|
|
625
386
|
return;
|
|
626
387
|
}
|
|
627
388
|
|
|
628
389
|
throw error;
|
|
390
|
+
} finally {
|
|
391
|
+
tx[Symbol.dispose]();
|
|
629
392
|
}
|
|
630
393
|
},
|
|
631
394
|
|
|
@@ -635,11 +398,11 @@ export function createNavigationBridge(
|
|
|
635
398
|
async refresh(): Promise<void> {
|
|
636
399
|
eventController.abortNavigation();
|
|
637
400
|
|
|
638
|
-
|
|
401
|
+
const tx = createNavigationTransaction(
|
|
639
402
|
store,
|
|
640
403
|
eventController,
|
|
641
404
|
window.location.href,
|
|
642
|
-
{ replace: true }
|
|
405
|
+
{ replace: true },
|
|
643
406
|
);
|
|
644
407
|
|
|
645
408
|
try {
|
|
@@ -649,41 +412,24 @@ export function createNavigationBridge(
|
|
|
649
412
|
[],
|
|
650
413
|
false,
|
|
651
414
|
tx.handle.signal,
|
|
652
|
-
tx.with({ url: window.location.href, replace: true, scroll: false })
|
|
415
|
+
tx.with({ url: window.location.href, replace: true, scroll: false }),
|
|
653
416
|
);
|
|
654
417
|
} catch (error) {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
: new NetworkError(
|
|
661
|
-
"Unable to connect to server. Please check your connection.",
|
|
662
|
-
{
|
|
663
|
-
cause: error,
|
|
664
|
-
url: window.location.href,
|
|
665
|
-
operation: "revalidation",
|
|
666
|
-
}
|
|
667
|
-
);
|
|
668
|
-
|
|
418
|
+
const networkError = toNetworkError(error, {
|
|
419
|
+
url: window.location.href,
|
|
420
|
+
operation: "revalidation",
|
|
421
|
+
});
|
|
422
|
+
if (networkError) {
|
|
669
423
|
console.error(
|
|
670
424
|
"[Browser] Network error during refresh:",
|
|
671
|
-
networkError
|
|
425
|
+
networkError,
|
|
672
426
|
);
|
|
673
|
-
|
|
674
|
-
startTransition(() => {
|
|
675
|
-
onUpdate({
|
|
676
|
-
root: createElement(NetworkErrorThrower, { error: networkError }),
|
|
677
|
-
metadata: {
|
|
678
|
-
pathname: window.location.href,
|
|
679
|
-
segments: [],
|
|
680
|
-
isError: true,
|
|
681
|
-
},
|
|
682
|
-
});
|
|
683
|
-
});
|
|
427
|
+
emitNetworkError(onUpdate, networkError, window.location.href);
|
|
684
428
|
return;
|
|
685
429
|
}
|
|
686
430
|
throw error;
|
|
431
|
+
} finally {
|
|
432
|
+
tx[Symbol.dispose]();
|
|
687
433
|
}
|
|
688
434
|
},
|
|
689
435
|
|
|
@@ -707,20 +453,29 @@ export function createNavigationBridge(
|
|
|
707
453
|
const currentInterceptSource = store.getInterceptSourceUrl();
|
|
708
454
|
const newInterceptSource = interceptSourceUrl ?? null;
|
|
709
455
|
if (currentInterceptSource !== newInterceptSource) {
|
|
710
|
-
|
|
711
|
-
`[Browser] Intercept context changing (${currentInterceptSource} -> ${newInterceptSource}), aborting in-flight actions
|
|
456
|
+
debugLog(
|
|
457
|
+
`[Browser] Intercept context changing (${currentInterceptSource} -> ${newInterceptSource}), aborting in-flight actions`,
|
|
712
458
|
);
|
|
713
459
|
eventController.abortAllActions();
|
|
714
460
|
}
|
|
715
461
|
|
|
462
|
+
// Popstate that exits an intercept to a non-intercept destination. The
|
|
463
|
+
// fallback fetch path below needs `leave-intercept` mode so it filters
|
|
464
|
+
// the cached @modal segment from the request and forces a re-render —
|
|
465
|
+
// otherwise a cache-miss popstate whose server response has an empty
|
|
466
|
+
// diff hits the "no changes" branch in partial-update and the modal
|
|
467
|
+
// stays on screen.
|
|
468
|
+
const isLeavingIntercept =
|
|
469
|
+
!isIntercept && currentInterceptSource !== null;
|
|
470
|
+
|
|
716
471
|
// Compute history key from URL (with intercept suffix if applicable)
|
|
717
472
|
const historyKey = generateHistoryKey(url, { intercept: isIntercept });
|
|
718
473
|
|
|
719
|
-
|
|
474
|
+
debugLog(
|
|
720
475
|
"[Browser] Popstate -",
|
|
721
476
|
isIntercept ? "intercept" : "normal",
|
|
722
477
|
"key:",
|
|
723
|
-
historyKey
|
|
478
|
+
historyKey,
|
|
724
479
|
);
|
|
725
480
|
|
|
726
481
|
// Update location in event controller
|
|
@@ -749,12 +504,27 @@ export function createNavigationBridge(
|
|
|
749
504
|
store.setCurrentUrl(url);
|
|
750
505
|
store.setPath(new URL(url).pathname);
|
|
751
506
|
|
|
507
|
+
// Restore router identity from cache so subsequent navigations
|
|
508
|
+
// don't falsely detect an app switch.
|
|
509
|
+
if (cached?.routerId) {
|
|
510
|
+
store.setRouterId?.(cached.routerId);
|
|
511
|
+
}
|
|
512
|
+
|
|
752
513
|
// Render from cache - force await to skip loading fallbacks
|
|
753
514
|
try {
|
|
754
|
-
const root = renderSegments(cachedSegments, {
|
|
515
|
+
const root = await renderSegments(cachedSegments, {
|
|
755
516
|
forceAwait: true,
|
|
756
517
|
});
|
|
757
|
-
|
|
518
|
+
// Merge params from cached segments for useParams restoration.
|
|
519
|
+
// Set params on event controller before onUpdate so both location
|
|
520
|
+
// and params are current when the debounced notify() fires.
|
|
521
|
+
const cachedParams: Record<string, string> = {};
|
|
522
|
+
for (const s of cachedSegments) {
|
|
523
|
+
if (s.params) Object.assign(cachedParams, s.params);
|
|
524
|
+
}
|
|
525
|
+
eventController.setParams(cachedParams);
|
|
526
|
+
|
|
527
|
+
const popstateUpdate = {
|
|
758
528
|
root,
|
|
759
529
|
metadata: {
|
|
760
530
|
pathname: new URL(url).pathname,
|
|
@@ -763,23 +533,40 @@ export function createNavigationBridge(
|
|
|
763
533
|
matched: cachedSegments.map((s) => s.id),
|
|
764
534
|
diff: [],
|
|
765
535
|
cachedHandleData,
|
|
536
|
+
params: cachedParams,
|
|
766
537
|
},
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
//
|
|
770
|
-
|
|
538
|
+
scroll: { restore: true, isStreaming },
|
|
539
|
+
};
|
|
540
|
+
// Intercept-driven popstate (entering OR leaving an intercept) only
|
|
541
|
+
// mutates the parallel slot; the main outlet shows the same content.
|
|
542
|
+
// Skip startViewTransition in those cases — same rationale as the
|
|
543
|
+
// intercept guard in partial-update.ts's hasTransition computation.
|
|
544
|
+
const hasTransition =
|
|
545
|
+
!isIntercept &&
|
|
546
|
+
!isLeavingIntercept &&
|
|
547
|
+
cachedSegments.some((s) => s.transition);
|
|
548
|
+
if (hasTransition) {
|
|
549
|
+
startTransition(() => {
|
|
550
|
+
if (addTransitionType) {
|
|
551
|
+
addTransitionType("navigation-back");
|
|
552
|
+
}
|
|
553
|
+
onUpdate(popstateUpdate);
|
|
554
|
+
});
|
|
555
|
+
} else {
|
|
556
|
+
onUpdate(popstateUpdate);
|
|
557
|
+
}
|
|
771
558
|
|
|
772
559
|
// SWR: If stale, trigger background revalidation
|
|
773
560
|
if (isStale) {
|
|
774
|
-
|
|
561
|
+
debugLog("[Browser] Cache is stale, background revalidating...");
|
|
775
562
|
// Background revalidation - don't await, just fire and forget
|
|
776
563
|
const segmentIds = cachedSegments.map((s) => s.id);
|
|
777
564
|
|
|
778
|
-
|
|
565
|
+
const tx = createNavigationTransaction(
|
|
779
566
|
store,
|
|
780
567
|
eventController,
|
|
781
568
|
url,
|
|
782
|
-
{ skipLoadingState: true, replace: true }
|
|
569
|
+
{ skipLoadingState: true, replace: true },
|
|
783
570
|
);
|
|
784
571
|
|
|
785
572
|
fetchPartialUpdate(
|
|
@@ -795,41 +582,33 @@ export function createNavigationBridge(
|
|
|
795
582
|
interceptSourceUrl,
|
|
796
583
|
cacheOnly: true,
|
|
797
584
|
}),
|
|
798
|
-
{
|
|
799
|
-
)
|
|
800
|
-
|
|
801
|
-
error
|
|
802
|
-
error
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
return;
|
|
806
|
-
}
|
|
807
|
-
// For background revalidation, network errors are logged but don't trigger error boundary
|
|
808
|
-
// since the user is already seeing cached content
|
|
809
|
-
if (error instanceof NetworkError || isNetworkError(error)) {
|
|
810
|
-
console.warn(
|
|
811
|
-
"[Browser] Background revalidation network error (cached content preserved):",
|
|
812
|
-
error.message
|
|
585
|
+
{ type: "stale-revalidation", interceptSourceUrl },
|
|
586
|
+
)
|
|
587
|
+
.catch((error) => {
|
|
588
|
+
if (isBackgroundSuppressible(error)) return;
|
|
589
|
+
console.error(
|
|
590
|
+
"[Browser] Background revalidation failed:",
|
|
591
|
+
error,
|
|
813
592
|
);
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
593
|
+
})
|
|
594
|
+
.finally(() => {
|
|
595
|
+
tx[Symbol.dispose]();
|
|
596
|
+
});
|
|
818
597
|
}
|
|
819
598
|
return;
|
|
820
599
|
} catch (error) {
|
|
821
600
|
console.warn(
|
|
822
601
|
"[Browser] Failed to render from cache, fetching:",
|
|
823
|
-
error
|
|
602
|
+
error,
|
|
824
603
|
);
|
|
825
604
|
// Fall through to fetch
|
|
826
605
|
}
|
|
827
606
|
} else {
|
|
828
|
-
|
|
607
|
+
debugLog("[Browser] History cache miss for key:", historyKey);
|
|
829
608
|
}
|
|
830
609
|
|
|
831
610
|
// Fetch if not cached
|
|
832
|
-
|
|
611
|
+
const tx = createNavigationTransaction(store, eventController, url, {
|
|
833
612
|
replace: true,
|
|
834
613
|
});
|
|
835
614
|
|
|
@@ -839,45 +618,43 @@ export function createNavigationBridge(
|
|
|
839
618
|
undefined,
|
|
840
619
|
false,
|
|
841
620
|
tx.handle.signal,
|
|
842
|
-
tx.with({
|
|
621
|
+
tx.with({
|
|
622
|
+
url,
|
|
623
|
+
replace: true,
|
|
624
|
+
scroll: false,
|
|
625
|
+
intercept: isIntercept,
|
|
626
|
+
interceptSourceUrl,
|
|
627
|
+
}),
|
|
628
|
+
isIntercept
|
|
629
|
+
? { type: "navigate", interceptSourceUrl }
|
|
630
|
+
: isLeavingIntercept
|
|
631
|
+
? { type: "leave-intercept" }
|
|
632
|
+
: undefined,
|
|
843
633
|
);
|
|
844
634
|
// Restore scroll position after fetch completes
|
|
845
635
|
handleNavigationEnd({ restore: true, isStreaming });
|
|
846
636
|
} catch (error) {
|
|
847
637
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
848
|
-
|
|
638
|
+
debugLog("[Browser] Popstate navigation aborted");
|
|
849
639
|
return;
|
|
850
640
|
}
|
|
851
641
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
: new NetworkError(
|
|
858
|
-
"Unable to connect to server. Please check your connection.",
|
|
859
|
-
{ cause: error, url, operation: "navigation" }
|
|
860
|
-
);
|
|
861
|
-
|
|
642
|
+
const networkError = toNetworkError(error, {
|
|
643
|
+
url,
|
|
644
|
+
operation: "navigation",
|
|
645
|
+
});
|
|
646
|
+
if (networkError) {
|
|
862
647
|
console.error(
|
|
863
|
-
"[Browser] Network error during popstate
|
|
864
|
-
networkError
|
|
648
|
+
"[Browser] Network error during popstate:",
|
|
649
|
+
networkError,
|
|
865
650
|
);
|
|
866
|
-
|
|
867
|
-
startTransition(() => {
|
|
868
|
-
onUpdate({
|
|
869
|
-
root: createElement(NetworkErrorThrower, { error: networkError }),
|
|
870
|
-
metadata: {
|
|
871
|
-
pathname: url,
|
|
872
|
-
segments: [],
|
|
873
|
-
isError: true,
|
|
874
|
-
},
|
|
875
|
-
});
|
|
876
|
-
});
|
|
651
|
+
emitNetworkError(onUpdate, networkError, url);
|
|
877
652
|
return;
|
|
878
653
|
}
|
|
879
654
|
|
|
880
655
|
throw error;
|
|
656
|
+
} finally {
|
|
657
|
+
tx[Symbol.dispose]();
|
|
881
658
|
}
|
|
882
659
|
},
|
|
883
660
|
|
|
@@ -894,19 +671,51 @@ export function createNavigationBridge(
|
|
|
894
671
|
this.handlePopstate();
|
|
895
672
|
};
|
|
896
673
|
|
|
674
|
+
// When the browser restores a page from bfcache (back-forward cache),
|
|
675
|
+
// any in-flight navigation state is stale. This happens when:
|
|
676
|
+
// 1. A navigation triggers X-RSC-Reload (e.g., response route hit via SPA)
|
|
677
|
+
// 2. window.location.href does a hard navigation
|
|
678
|
+
// 3. The user presses back and the browser restores from bfcache
|
|
679
|
+
// At that point, currentNavigation is still set from step 1, so
|
|
680
|
+
// getState() returns "loading" and the progress bar shows.
|
|
681
|
+
// Abort the stale navigation to reset state to idle.
|
|
682
|
+
const handlePageShow = (event: PageTransitionEvent) => {
|
|
683
|
+
if (event.persisted) {
|
|
684
|
+
debugLog(
|
|
685
|
+
"[Browser] Page restored from bfcache, resetting navigation state",
|
|
686
|
+
);
|
|
687
|
+
eventController.abortNavigation();
|
|
688
|
+
// pagehide flips scrollRestoration to "auto" for bfcache compat;
|
|
689
|
+
// restore "manual" so the router controls scroll on SPA navigations.
|
|
690
|
+
window.history.scrollRestoration = "manual";
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
|
|
897
694
|
// Register cross-tab refresh callback with the store
|
|
898
695
|
store.setCrossTabRefreshCallback(() => {
|
|
899
696
|
this.refresh();
|
|
900
697
|
});
|
|
901
698
|
|
|
902
699
|
window.addEventListener("popstate", handlePopstate);
|
|
903
|
-
|
|
700
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
701
|
+
debugLog("[Browser] Navigation bridge ready");
|
|
904
702
|
|
|
905
703
|
return () => {
|
|
906
704
|
cleanupLinks();
|
|
907
705
|
window.removeEventListener("popstate", handlePopstate);
|
|
706
|
+
window.removeEventListener("pageshow", handlePageShow);
|
|
908
707
|
};
|
|
909
708
|
},
|
|
709
|
+
|
|
710
|
+
updateVersion(newVersion: string): void {
|
|
711
|
+
version = newVersion;
|
|
712
|
+
setAppVersion(newVersion);
|
|
713
|
+
store.clearHistoryCache();
|
|
714
|
+
},
|
|
715
|
+
|
|
716
|
+
updateAppShell(next: AppShell): void {
|
|
717
|
+
applyAppShell(next);
|
|
718
|
+
},
|
|
910
719
|
};
|
|
911
720
|
}
|
|
912
721
|
|