@rangojs/router 0.0.0-experimental.259 → 0.0.0-experimental.25dbaac3
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/{CLAUDE.md → AGENTS.md} +4 -0
- package/README.md +471 -51
- 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 +490 -94
- 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 +3423 -1718
- 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/dist/vite/package-resolution.js +112 -0
- 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/dist/vite/virtual-entries.js +110 -0
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +21 -18
- package/skills/breadcrumbs/SKILL.md +252 -0
- package/skills/cache-guide/SKILL.md +41 -5
- package/skills/caching/SKILL.md +49 -8
- package/skills/document-cache/SKILL.md +2 -2
- package/skills/handler-use/SKILL.md +362 -0
- package/skills/hooks/SKILL.md +94 -52
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +99 -0
- package/skills/layout/SKILL.md +84 -2
- package/skills/links/SKILL.md +93 -17
- package/skills/loader/SKILL.md +367 -36
- package/skills/middleware/SKILL.md +145 -33
- package/skills/migrate-nextjs/SKILL.md +562 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/parallel/SKILL.md +249 -2
- package/skills/prerender/SKILL.md +261 -49
- package/skills/rango/SKILL.md +26 -24
- package/skills/response-routes/SKILL.md +11 -3
- package/skills/route/SKILL.md +100 -5
- package/skills/router-setup/SKILL.md +172 -5
- package/skills/server-actions/SKILL.md +739 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/theme/SKILL.md +5 -4
- package/skills/typesafety/SKILL.md +95 -38
- package/skills/use-cache/SKILL.md +16 -2
- package/src/__internal.ts +93 -1
- package/src/bin/rango.ts +56 -19
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +78 -52
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +1 -1
- package/src/browser/link-interceptor.ts +23 -3
- package/src/browser/merge-segment-loaders.ts +9 -2
- package/src/browser/navigation-bridge.ts +234 -453
- package/src/browser/navigation-client.ts +191 -86
- package/src/browser/navigation-store.ts +71 -41
- package/src/browser/navigation-transaction.ts +297 -0
- package/src/browser/partial-update.ts +215 -167
- 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 +241 -47
- package/src/browser/react/NavigationProvider.tsx +136 -16
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +55 -0
- package/src/browser/react/index.ts +2 -6
- package/src/browser/react/location-state-shared.ts +29 -11
- package/src/browser/react/location-state.ts +6 -4
- 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 +23 -45
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +28 -120
- package/src/browser/react/use-navigation.ts +29 -34
- package/src/browser/react/use-params.ts +16 -35
- package/src/browser/react/use-pathname.ts +2 -3
- package/src/browser/react/use-router.ts +31 -14
- package/src/browser/react/use-search-params.ts +2 -1
- package/src/browser/react/use-segments.ts +82 -118
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +202 -67
- package/src/browser/scroll-restoration.ts +47 -45
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/server-action-bridge.ts +464 -409
- package/src/browser/types.ts +100 -40
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +44 -19
- package/src/build/generate-route-types.ts +7 -0
- package/src/build/index.ts +1 -0
- package/src/build/route-trie.ts +67 -25
- package/src/build/route-types/codegen.ts +13 -4
- package/src/build/route-types/include-resolution.ts +21 -1
- package/src/build/route-types/per-module-writer.ts +15 -3
- package/src/build/route-types/router-processing.ts +391 -90
- package/src/build/route-types/scan-filter.ts +8 -1
- package/src/build/runtime-discovery.ts +13 -1
- 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 +140 -123
- package/src/cache/cache-scope.ts +124 -90
- package/src/cache/cf/cf-cache-store.ts +467 -22
- package/src/cache/cf/index.ts +5 -1
- package/src/cache/document-cache.ts +109 -75
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/index.ts +1 -15
- package/src/cache/memory-segment-store.ts +43 -69
- package/src/cache/profile-registry.ts +43 -8
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +140 -117
- package/src/cache/taint.ts +85 -3
- package/src/cache/types.ts +1 -115
- package/src/client.rsc.tsx +2 -1
- package/src/client.tsx +86 -254
- package/src/context-var.ts +72 -2
- package/src/debug.ts +2 -2
- package/src/errors.ts +6 -1
- package/src/handle.ts +41 -1
- package/src/handles/MetaTags.tsx +5 -2
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/host/cookie-handler.ts +8 -3
- package/src/host/index.ts +0 -3
- package/src/host/router.ts +14 -1
- package/src/href-client.ts +3 -1
- package/src/index.rsc.ts +48 -32
- package/src/index.ts +104 -64
- package/src/loader.rsc.ts +12 -4
- package/src/loader.ts +8 -0
- package/src/outlet-context.ts +1 -1
- package/src/prerender/store.ts +61 -18
- package/src/prerender.ts +207 -88
- package/src/response-utils.ts +28 -0
- package/src/reverse.ts +36 -7
- package/src/root-error-boundary.tsx +30 -26
- package/src/route-definition/dsl-helpers.ts +249 -46
- package/src/route-definition/helpers-types.ts +73 -20
- package/src/route-definition/index.ts +3 -3
- package/src/route-definition/redirect.ts +24 -4
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-map-builder.ts +45 -3
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +25 -0
- package/src/router/content-negotiation.ts +101 -2
- package/src/router/debug-manifest.ts +16 -3
- package/src/router/find-match.ts +4 -2
- package/src/router/handler-context.ts +221 -39
- package/src/router/intercept-resolution.ts +17 -8
- package/src/router/lazy-includes.ts +12 -5
- package/src/router/loader-resolution.ts +164 -31
- package/src/router/logging.ts +104 -4
- package/src/router/manifest.ts +53 -9
- package/src/router/match-api.ts +150 -206
- package/src/router/match-context.ts +3 -0
- package/src/router/match-handlers.ts +186 -11
- package/src/router/match-middleware/background-revalidation.ts +94 -86
- package/src/router/match-middleware/cache-lookup.ts +164 -19
- package/src/router/match-middleware/cache-store.ts +55 -10
- package/src/router/match-middleware/intercept-resolution.ts +9 -7
- package/src/router/match-middleware/segment-resolution.ts +61 -5
- package/src/router/match-pipelines.ts +8 -43
- package/src/router/match-result.ts +122 -18
- package/src/router/metrics.ts +238 -13
- package/src/router/middleware-types.ts +64 -61
- package/src/router/middleware.ts +316 -145
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +134 -15
- package/src/router/prerender-match.ts +150 -16
- package/src/router/preview-match.ts +30 -96
- package/src/router/request-classification.ts +310 -0
- package/src/router/revalidation.ts +102 -9
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +20 -0
- package/src/router/router-interfaces.ts +200 -43
- package/src/router/router-options.ts +265 -12
- package/src/router/router-registry.ts +5 -2
- package/src/router/segment-resolution/fresh.ts +365 -256
- package/src/router/segment-resolution/helpers.ts +268 -0
- package/src/router/segment-resolution/loader-cache.ts +103 -98
- package/src/router/segment-resolution/revalidation.ts +711 -423
- package/src/router/segment-resolution/static-store.ts +2 -2
- package/src/router/segment-resolution.ts +1 -3
- package/src/router/segment-wrappers.ts +5 -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 +30 -6
- package/src/router/types.ts +8 -1
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +269 -25
- package/src/rsc/handler-context.ts +13 -2
- package/src/rsc/handler.ts +784 -629
- package/src/rsc/helpers.ts +168 -20
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +105 -43
- package/src/rsc/manifest-init.ts +7 -2
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +262 -20
- package/src/rsc/response-route-handler.ts +360 -0
- package/src/rsc/rsc-rendering.ts +70 -44
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +178 -66
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +37 -3
- package/src/search-params.ts +38 -23
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +109 -23
- package/src/server/context.ts +227 -24
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +103 -12
- package/src/server/loader-registry.ts +20 -54
- package/src/server/request-context.ts +475 -105
- package/src/server.ts +6 -0
- package/src/ssr/index.tsx +74 -27
- package/src/static-handler.ts +25 -6
- package/src/theme/ThemeProvider.tsx +6 -1
- package/src/theme/index.ts +4 -18
- package/src/theme/theme-context.ts +1 -28
- package/src/theme/theme-script.ts +2 -1
- package/src/types/cache-types.ts +10 -5
- package/src/types/error-types.ts +3 -0
- package/src/types/global-namespace.ts +22 -0
- package/src/types/handler-context.ts +242 -82
- package/src/types/index.ts +1 -1
- package/src/types/loader-types.ts +50 -21
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-config.ts +17 -26
- package/src/types/route-entry.ts +46 -0
- package/src/types/segments.ts +19 -5
- package/src/urls/include-helper.ts +72 -21
- package/src/urls/index.ts +1 -0
- package/src/urls/path-helper-types.ts +69 -18
- package/src/urls/path-helper.ts +65 -15
- package/src/urls/pattern-types.ts +33 -1
- package/src/urls/response-types.ts +47 -23
- package/src/urls/type-extraction.ts +23 -15
- package/src/use-loader.tsx +103 -13
- package/src/vite/debug.ts +184 -0
- package/src/vite/discovery/bundle-postprocess.ts +62 -85
- package/src/vite/discovery/discover-routers.ts +87 -29
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +224 -106
- package/src/vite/discovery/route-types-writer.ts +7 -7
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +20 -13
- package/src/vite/discovery/virtual-module-codegen.ts +5 -2
- package/src/vite/index.ts +14 -51
- package/src/vite/plugin-types.ts +51 -79
- package/src/vite/plugins/cjs-to-esm.ts +5 -0
- package/src/vite/plugins/client-ref-dedup.ts +131 -0
- package/src/vite/plugins/client-ref-hashing.ts +19 -7
- 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/plugins/expose-action-id.ts +53 -31
- package/src/vite/plugins/expose-id-utils.ts +12 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
- package/src/vite/plugins/expose-internal-ids.ts +567 -319
- package/src/vite/plugins/performance-tracks.ts +96 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +139 -38
- package/src/vite/plugins/version-injector.ts +37 -11
- package/src/vite/plugins/version-plugin.ts +200 -18
- package/src/vite/rango.ts +233 -221
- package/src/vite/router-discovery.ts +887 -176
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/package-resolution.ts +41 -1
- package/src/vite/utils/prerender-utils.ts +113 -0
- package/src/vite/utils/shared-utils.ts +22 -11
- package/skills/testing/SKILL.md +0 -226
- package/src/browser/lru-cache.ts +0 -61
- package/src/browser/react/prefetch.ts +0 -27
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/route-definition/route-function.ts +0 -119
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
package/src/rsc/handler.ts
CHANGED
|
@@ -8,33 +8,46 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createElement } from "react";
|
|
11
|
-
import { RouteNotFoundError
|
|
11
|
+
import { RouteNotFoundError } from "../errors.js";
|
|
12
12
|
import { matchMiddleware, executeMiddleware } from "../router/middleware.js";
|
|
13
13
|
import {
|
|
14
14
|
runWithRequestContext,
|
|
15
15
|
setRequestContextParams,
|
|
16
16
|
requireRequestContext,
|
|
17
|
+
getRequestContext,
|
|
18
|
+
_getRequestContext,
|
|
17
19
|
createRequestContext,
|
|
18
|
-
getLocationState,
|
|
19
20
|
} from "../server/request-context.js";
|
|
20
|
-
import { resolveLocationStateEntries } from "../browser/react/location-state-shared.js";
|
|
21
21
|
import * as rscDeps from "@vitejs/plugin-rsc/rsc";
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
import type {
|
|
23
|
+
RscPayload,
|
|
24
|
+
CreateRSCHandlerOptions,
|
|
25
|
+
LoadSSRModule,
|
|
26
|
+
SSRModule,
|
|
27
|
+
} from "./types.js";
|
|
24
28
|
import {
|
|
25
29
|
createResponseWithMergedHeaders,
|
|
26
|
-
|
|
30
|
+
finalizeResponse,
|
|
31
|
+
interceptRedirectForPartial,
|
|
32
|
+
buildRouteMiddlewareEntries,
|
|
27
33
|
} from "./helpers.js";
|
|
34
|
+
import { isWebSocketUpgradeResponse } from "../response-utils.js";
|
|
35
|
+
import {
|
|
36
|
+
handleResponseRoute,
|
|
37
|
+
type ResponseRouteMatch,
|
|
38
|
+
} from "./response-route-handler.js";
|
|
28
39
|
import { generateNonce, nonce as nonceToken } from "./nonce.js";
|
|
29
40
|
import { VERSION } from "@rangojs/router:version";
|
|
30
41
|
import type { ErrorPhase } from "../types.js";
|
|
31
42
|
import type { RouterRequestInput } from "../router/router-interfaces.js";
|
|
32
43
|
import { invokeOnError } from "../router/error-handling.js";
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
import {
|
|
44
|
+
import {
|
|
45
|
+
createReverseFunction,
|
|
46
|
+
stripInternalParams,
|
|
47
|
+
} from "../router/handler-context.js";
|
|
48
|
+
import { getRouterContext } from "../router/router-context.js";
|
|
49
|
+
import { resolveSink, safeEmit } from "../router/telemetry.js";
|
|
50
|
+
import { contextSet } from "../context-var.js";
|
|
38
51
|
import {
|
|
39
52
|
hasCachedManifest,
|
|
40
53
|
getRouteTrie,
|
|
@@ -44,12 +57,39 @@ import {
|
|
|
44
57
|
getRouterTrie,
|
|
45
58
|
} from "../route-map-builder.js";
|
|
46
59
|
import type { HandlerContext } from "./handler-context.js";
|
|
47
|
-
import {
|
|
60
|
+
import type { SegmentCacheStore } from "../cache/types.js";
|
|
48
61
|
import { buildRouterTrieFromUrlpatterns } from "./manifest-init.js";
|
|
49
62
|
import { handleProgressiveEnhancement } from "./progressive-enhancement.js";
|
|
50
|
-
import {
|
|
63
|
+
import {
|
|
64
|
+
executeServerAction,
|
|
65
|
+
revalidateAfterAction,
|
|
66
|
+
type ActionContinuation,
|
|
67
|
+
} from "./server-action.js";
|
|
51
68
|
import { handleLoaderFetch } from "./loader-fetch.js";
|
|
69
|
+
import { checkRequestOrigin, type OriginCheckPhase } from "./origin-guard.js";
|
|
52
70
|
import { handleRscRendering } from "./rsc-rendering.js";
|
|
71
|
+
import {
|
|
72
|
+
withTimeout,
|
|
73
|
+
RouterTimeoutError,
|
|
74
|
+
createDefaultTimeoutResponse,
|
|
75
|
+
type TimeoutPhase,
|
|
76
|
+
} from "../router/timeout.js";
|
|
77
|
+
import {
|
|
78
|
+
createMetricsStore,
|
|
79
|
+
appendMetric,
|
|
80
|
+
buildMetricsTiming,
|
|
81
|
+
} from "../router/metrics.js";
|
|
82
|
+
import {
|
|
83
|
+
startSSRSetup,
|
|
84
|
+
getSSRSetup,
|
|
85
|
+
mayNeedSSR,
|
|
86
|
+
SSR_SETUP_VAR,
|
|
87
|
+
} from "./ssr-setup.js";
|
|
88
|
+
import {
|
|
89
|
+
classifyRequest,
|
|
90
|
+
type RequestPlan,
|
|
91
|
+
type ExecutableRequestPlan,
|
|
92
|
+
} from "../router/request-classification.js";
|
|
53
93
|
|
|
54
94
|
/**
|
|
55
95
|
* Create an RSC request handler.
|
|
@@ -84,13 +124,6 @@ import { handleRscRendering } from "./rsc-rendering.js";
|
|
|
84
124
|
* });
|
|
85
125
|
* ```
|
|
86
126
|
*/
|
|
87
|
-
// Only cache successful responses. Non-200 statuses (errors, redirects) are
|
|
88
|
-
// not cached — notFound() produces 500 in response routes, and explicit
|
|
89
|
-
// non-200 Responses are rare enough that caching them would be surprising.
|
|
90
|
-
function isCacheableStatus(status: number): boolean {
|
|
91
|
-
return status === 200;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
127
|
export function createRSCHandler<
|
|
95
128
|
TEnv = unknown,
|
|
96
129
|
TRoutes extends Record<string, string> = Record<string, string>,
|
|
@@ -108,27 +141,41 @@ export function createRSCHandler<
|
|
|
108
141
|
decodeFormState,
|
|
109
142
|
} = deps;
|
|
110
143
|
|
|
111
|
-
// Use provided loadSSRModule or default to vite RSC module loader
|
|
112
|
-
|
|
144
|
+
// Use provided loadSSRModule or default to vite RSC module loader.
|
|
145
|
+
// In production the SSR module is stable across requests, so memoize
|
|
146
|
+
// the dynamic import to avoid repeated module resolution overhead.
|
|
147
|
+
// In dev mode Vite may hot-reload the module, so skip memoization.
|
|
148
|
+
const rawLoadSSRModule: LoadSSRModule =
|
|
113
149
|
options.loadSSRModule ??
|
|
114
150
|
(() => import.meta.viteRsc.loadModule("ssr", "index"));
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
151
|
+
let _ssrModulePromise: Promise<SSRModule> | undefined;
|
|
152
|
+
const loadSSRModule: LoadSSRModule =
|
|
153
|
+
process.env.NODE_ENV === "production"
|
|
154
|
+
? () =>
|
|
155
|
+
(_ssrModulePromise ??= rawLoadSSRModule().catch((err) => {
|
|
156
|
+
_ssrModulePromise = undefined;
|
|
157
|
+
throw err;
|
|
158
|
+
}))
|
|
159
|
+
: rawLoadSSRModule;
|
|
119
160
|
|
|
120
161
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
162
|
+
* Per-request error reporter that deduplicates via the ALS request context.
|
|
163
|
+
*
|
|
164
|
+
* Uses the same _reportedErrors WeakSet as the router layer so errors
|
|
165
|
+
* that propagate across layers are only reported once per request.
|
|
123
166
|
*/
|
|
124
167
|
function callOnError(
|
|
125
168
|
error: unknown,
|
|
126
169
|
phase: ErrorPhase,
|
|
127
170
|
context: Parameters<typeof invokeOnError<TEnv>>[3],
|
|
128
171
|
): void {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
172
|
+
// Guard: abort signal handlers fire asynchronously outside the ALS
|
|
173
|
+
// request scope, so the context may be gone. Skip dedup in that
|
|
174
|
+
// case — the error is from a cancelled stream, not a real failure.
|
|
175
|
+
const reqCtx = _getRequestContext();
|
|
176
|
+
if (error != null && typeof error === "object" && reqCtx) {
|
|
177
|
+
if (reqCtx._reportedErrors.has(error)) return;
|
|
178
|
+
reqCtx._reportedErrors.add(error);
|
|
132
179
|
}
|
|
133
180
|
invokeOnError(router.onError, error, phase, context, "RSC");
|
|
134
181
|
}
|
|
@@ -143,6 +190,72 @@ export function createRSCHandler<
|
|
|
143
190
|
return routeMap;
|
|
144
191
|
}
|
|
145
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Handle a timeout by reporting the error, emitting telemetry,
|
|
195
|
+
* and returning either the custom onTimeout response or a default 504.
|
|
196
|
+
*/
|
|
197
|
+
async function handleTimeoutResponse(
|
|
198
|
+
request: Request,
|
|
199
|
+
env: TEnv,
|
|
200
|
+
url: URL,
|
|
201
|
+
phase: TimeoutPhase,
|
|
202
|
+
durationMs: number,
|
|
203
|
+
routeKey?: string,
|
|
204
|
+
actionId?: string,
|
|
205
|
+
): Promise<Response> {
|
|
206
|
+
const timeoutError = new RouterTimeoutError(phase, durationMs);
|
|
207
|
+
|
|
208
|
+
callOnError(timeoutError, phase === "action" ? "action" : "handler", {
|
|
209
|
+
request,
|
|
210
|
+
url,
|
|
211
|
+
env,
|
|
212
|
+
routeKey,
|
|
213
|
+
actionId,
|
|
214
|
+
handledByBoundary: false,
|
|
215
|
+
metadata: { timeout: true, phase, durationMs },
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
const routerCtx = getRouterContext();
|
|
220
|
+
if (routerCtx?.telemetry) {
|
|
221
|
+
safeEmit(resolveSink(routerCtx.telemetry), {
|
|
222
|
+
type: "request.timeout" as const,
|
|
223
|
+
timestamp: performance.now(),
|
|
224
|
+
requestId: routerCtx.requestId,
|
|
225
|
+
phase,
|
|
226
|
+
pathname: url.pathname,
|
|
227
|
+
routeKey,
|
|
228
|
+
actionId,
|
|
229
|
+
durationMs,
|
|
230
|
+
customHandler: !!router.onTimeout,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
} catch {
|
|
234
|
+
// Router context may not be available
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (router.onTimeout) {
|
|
238
|
+
try {
|
|
239
|
+
return await router.onTimeout({
|
|
240
|
+
phase,
|
|
241
|
+
request,
|
|
242
|
+
url,
|
|
243
|
+
env,
|
|
244
|
+
routeKey,
|
|
245
|
+
actionId,
|
|
246
|
+
durationMs,
|
|
247
|
+
});
|
|
248
|
+
} catch (e) {
|
|
249
|
+
if (process.env.NODE_ENV !== "production") {
|
|
250
|
+
console.error("[RSC] onTimeout callback error:", e);
|
|
251
|
+
}
|
|
252
|
+
return createDefaultTimeoutResponse(phase);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return createDefaultTimeoutResponse(phase);
|
|
257
|
+
}
|
|
258
|
+
|
|
146
259
|
/**
|
|
147
260
|
* Build a 200 Flight response that carries a redirect URL and optional state.
|
|
148
261
|
* Used when a partial/action request results in a redirect -- fetch
|
|
@@ -167,7 +280,8 @@ export function createRSCHandler<
|
|
|
167
280
|
});
|
|
168
281
|
}
|
|
169
282
|
|
|
170
|
-
// Bundle shared dependencies for extracted handler functions
|
|
283
|
+
// Bundle shared dependencies for extracted handler functions.
|
|
284
|
+
// callOnError reads from ALS so it's inherently per-request scoped.
|
|
171
285
|
const handlerCtx: HandlerContext<TEnv> = {
|
|
172
286
|
router,
|
|
173
287
|
version,
|
|
@@ -181,6 +295,11 @@ export function createRSCHandler<
|
|
|
181
295
|
callOnError,
|
|
182
296
|
getRequiredRouteMap,
|
|
183
297
|
createRedirectFlightResponse,
|
|
298
|
+
resolveStreamMode: async (request, env, url) => {
|
|
299
|
+
const resolver = router.ssr?.resolveStreaming;
|
|
300
|
+
if (!resolver) return "stream";
|
|
301
|
+
return resolver({ request, env, url });
|
|
302
|
+
},
|
|
184
303
|
};
|
|
185
304
|
|
|
186
305
|
return async function handler(
|
|
@@ -188,6 +307,11 @@ export function createRSCHandler<
|
|
|
188
307
|
input: RouterRequestInput<TEnv> = {},
|
|
189
308
|
): Promise<Response> {
|
|
190
309
|
const handlerStart = performance.now();
|
|
310
|
+
// Create the metrics store at handler start so handler:total has startTime=0
|
|
311
|
+
// and all metrics are relative to the request entry point.
|
|
312
|
+
const earlyMetricsStore = router.debugPerformance
|
|
313
|
+
? createMetricsStore(true, handlerStart)
|
|
314
|
+
: undefined;
|
|
191
315
|
|
|
192
316
|
const { env = {} as TEnv, vars: initialVars, ctx: executionCtx } = input;
|
|
193
317
|
|
|
@@ -230,7 +354,7 @@ export function createRSCHandler<
|
|
|
230
354
|
// Resolve cache store configuration
|
|
231
355
|
// Priority: options.cache (handler override) > router.cache (router default)
|
|
232
356
|
// Store is enabled only if: config provided, enabled, and no ?__no_cache query param
|
|
233
|
-
let cacheStore
|
|
357
|
+
let cacheStore: SegmentCacheStore | undefined;
|
|
234
358
|
const cacheOption = options.cache ?? router.cache;
|
|
235
359
|
if (cacheOption && !url.searchParams.has("__no_cache")) {
|
|
236
360
|
const cacheConfig =
|
|
@@ -287,9 +411,6 @@ export function createRSCHandler<
|
|
|
287
411
|
}
|
|
288
412
|
const manifestCacheDur = performance.now() - manifestCacheStart;
|
|
289
413
|
|
|
290
|
-
// Note: Route map for useHref() is loaded lazily via getGlobalRouteMap()
|
|
291
|
-
// This allows it to include all routes from lazy includes after manifest loading
|
|
292
|
-
|
|
293
414
|
// Create unified request context with all methods
|
|
294
415
|
// Includes: stub response, handle store, loader memoization, use(), cookies, headers, cache store
|
|
295
416
|
// params starts empty, populated after route matching via setRequestContextParams
|
|
@@ -300,9 +421,27 @@ export function createRSCHandler<
|
|
|
300
421
|
url,
|
|
301
422
|
variables,
|
|
302
423
|
cacheStore,
|
|
424
|
+
cacheProfiles: router.cacheProfiles,
|
|
303
425
|
executionContext: executionCtx,
|
|
304
426
|
themeConfig: router.themeConfig,
|
|
305
427
|
});
|
|
428
|
+
if (earlyMetricsStore) {
|
|
429
|
+
requestContext._debugPerformance = true;
|
|
430
|
+
requestContext._metricsStore = earlyMetricsStore;
|
|
431
|
+
}
|
|
432
|
+
// Wire background error reporting so "use cache" and other subsystems
|
|
433
|
+
// can surface non-fatal errors through the router's onError callback.
|
|
434
|
+
requestContext._reportBackgroundError = (
|
|
435
|
+
error: unknown,
|
|
436
|
+
category: string,
|
|
437
|
+
) => {
|
|
438
|
+
callOnError(error, "cache", {
|
|
439
|
+
request,
|
|
440
|
+
url,
|
|
441
|
+
metadata: { category },
|
|
442
|
+
});
|
|
443
|
+
};
|
|
444
|
+
|
|
306
445
|
const ctxCreateDur = performance.now() - ctxCreateStart;
|
|
307
446
|
|
|
308
447
|
// Accumulate handler-level timing for Server-Timing header
|
|
@@ -324,6 +463,9 @@ export function createRSCHandler<
|
|
|
324
463
|
// - Server components during rendering
|
|
325
464
|
// - Error boundaries
|
|
326
465
|
// - Streaming
|
|
466
|
+
// Store basename on request context (scoped per-request via existing ALS)
|
|
467
|
+
requestContext._basename = router.basename;
|
|
468
|
+
|
|
327
469
|
return runWithRequestContext(requestContext, async () => {
|
|
328
470
|
// Core handler logic (wrapped by middleware)
|
|
329
471
|
const coreHandler = async (): Promise<Response> => {
|
|
@@ -331,6 +473,7 @@ export function createRSCHandler<
|
|
|
331
473
|
};
|
|
332
474
|
|
|
333
475
|
// Execute middleware chain if any, otherwise call core handler directly
|
|
476
|
+
let response: Response;
|
|
334
477
|
if (matchedMiddleware.length > 0) {
|
|
335
478
|
const mwResponse = await executeMiddleware(
|
|
336
479
|
matchedMiddleware,
|
|
@@ -341,34 +484,68 @@ export function createRSCHandler<
|
|
|
341
484
|
createReverseFunction(getRequiredRouteMap()),
|
|
342
485
|
);
|
|
343
486
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (locationState) {
|
|
356
|
-
return createRedirectFlightResponse(
|
|
357
|
-
redirectUrl,
|
|
358
|
-
resolveLocationStateEntries(locationState),
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
return createSimpleRedirectResponse(redirectUrl);
|
|
487
|
+
if (
|
|
488
|
+
url.searchParams.has("_rsc_partial") ||
|
|
489
|
+
url.searchParams.has("_rsc_action")
|
|
490
|
+
) {
|
|
491
|
+
const intercepted = interceptRedirectForPartial(
|
|
492
|
+
mwResponse,
|
|
493
|
+
createRedirectFlightResponse,
|
|
494
|
+
);
|
|
495
|
+
response = intercepted ?? finalizeResponse(mwResponse);
|
|
496
|
+
} else {
|
|
497
|
+
response = finalizeResponse(mwResponse);
|
|
362
498
|
}
|
|
499
|
+
} else {
|
|
500
|
+
response = await coreHandler();
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Finalize metrics after all middleware (including post-next work)
|
|
504
|
+
// has completed so :post spans are captured in the timeline.
|
|
505
|
+
// Handler timing parts are always emitted (even without debug metrics)
|
|
506
|
+
// so non-debug requests still get bootstrap Server-Timing entries.
|
|
507
|
+
const handlerTimingArr: string[] = variables.__handlerTiming || [];
|
|
508
|
+
// Preserve any existing Server-Timing set by response routes or middleware
|
|
509
|
+
const existingTiming = response.headers.get("Server-Timing");
|
|
510
|
+
const timingParts = existingTiming
|
|
511
|
+
? [existingTiming, ...handlerTimingArr]
|
|
512
|
+
: [...handlerTimingArr];
|
|
513
|
+
|
|
514
|
+
const metricsStore = requestContext._metricsStore;
|
|
515
|
+
if (metricsStore) {
|
|
516
|
+
// When the store was created at handler start (earlyMetricsStore),
|
|
517
|
+
// handler:total covers the full request. When ctx.debugPerformance()
|
|
518
|
+
// created the store mid-request, use its requestStart to avoid a
|
|
519
|
+
// negative startTime offset.
|
|
520
|
+
const totalStart = earlyMetricsStore
|
|
521
|
+
? handlerStart
|
|
522
|
+
: metricsStore.requestStart;
|
|
523
|
+
appendMetric(
|
|
524
|
+
metricsStore,
|
|
525
|
+
"handler:total",
|
|
526
|
+
totalStart,
|
|
527
|
+
performance.now() - totalStart,
|
|
528
|
+
);
|
|
529
|
+
const metricsTiming = buildMetricsTiming(
|
|
530
|
+
request.method,
|
|
531
|
+
url.pathname,
|
|
532
|
+
metricsStore,
|
|
533
|
+
);
|
|
534
|
+
if (metricsTiming) timingParts.push(metricsTiming);
|
|
535
|
+
}
|
|
363
536
|
|
|
364
|
-
|
|
537
|
+
const fullTiming = timingParts.join(", ");
|
|
538
|
+
if (fullTiming && !isWebSocketUpgradeResponse(response)) {
|
|
539
|
+
response.headers.set("Server-Timing", fullTiming);
|
|
365
540
|
}
|
|
366
541
|
|
|
367
|
-
return
|
|
542
|
+
return response;
|
|
368
543
|
});
|
|
369
544
|
};
|
|
370
545
|
|
|
371
|
-
// Core request handling logic (separated for middleware wrapping)
|
|
546
|
+
// Core request handling logic (separated for middleware wrapping).
|
|
547
|
+
// Uses the classify → execute model: classifyRequest produces a RequestPlan,
|
|
548
|
+
// then execution dispatches on the plan mode.
|
|
372
549
|
async function coreRequestHandler(
|
|
373
550
|
request: Request,
|
|
374
551
|
env: TEnv,
|
|
@@ -376,663 +553,641 @@ export function createRSCHandler<
|
|
|
376
553
|
variables: Record<string, any>,
|
|
377
554
|
nonce: string | undefined,
|
|
378
555
|
): Promise<Response> {
|
|
379
|
-
// First, check for route-level middleware
|
|
380
|
-
const previewStart = performance.now();
|
|
381
|
-
const preview = await router.previewMatch(request, { env });
|
|
382
|
-
const previewDur = performance.now() - previewStart;
|
|
383
556
|
const handlerTiming: string[] = variables.__handlerTiming || [];
|
|
384
|
-
handlerTiming.push(`handler-preview-match;dur=${previewDur.toFixed(2)}`);
|
|
385
|
-
// Response route short-circuit: skip entire RSC pipeline
|
|
386
|
-
if (preview?.responseType && preview.handler) {
|
|
387
|
-
const isPartial = url.searchParams.has("_rsc_partial");
|
|
388
|
-
|
|
389
|
-
// Partial requests (client-side navigation) to response routes
|
|
390
|
-
// get X-RSC-Reload to trigger hard navigation in the browser
|
|
391
|
-
if (isPartial) {
|
|
392
|
-
const cleanUrl = new URL(url);
|
|
393
|
-
cleanUrl.searchParams.delete("_rsc_partial");
|
|
394
|
-
cleanUrl.searchParams.delete("_rsc_segments");
|
|
395
|
-
cleanUrl.searchParams.delete("_rsc_v");
|
|
396
|
-
cleanUrl.searchParams.delete("_rsc_stale");
|
|
397
|
-
cleanUrl.searchParams.delete("_rsc_action");
|
|
398
|
-
cleanUrl.searchParams.delete("_rsc_prev");
|
|
399
|
-
|
|
400
|
-
return createResponseWithMergedHeaders(null, {
|
|
401
|
-
status: 200,
|
|
402
|
-
headers: {
|
|
403
|
-
"X-RSC-Reload": cleanUrl.toString(),
|
|
404
|
-
"content-type": "text/x-component;charset=utf-8",
|
|
405
|
-
},
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
557
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
558
|
+
// Debug manifest endpoint: handled before classification since it
|
|
559
|
+
// doesn't need a route match and needs trie access from the closure.
|
|
560
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
561
|
+
if (
|
|
562
|
+
url.searchParams.has("__debug_manifest") &&
|
|
563
|
+
(isDev || router.allowDebugManifest)
|
|
564
|
+
) {
|
|
565
|
+
const trie = getRouterTrie(router.id) ?? getRouteTrie();
|
|
566
|
+
const routeManifest = getRequiredRouteMap();
|
|
567
|
+
const { extractAncestryFromTrie } =
|
|
568
|
+
await import("../build/route-trie.js");
|
|
569
|
+
return new Response(
|
|
570
|
+
JSON.stringify(
|
|
571
|
+
{
|
|
572
|
+
routerId: router.id,
|
|
573
|
+
routeManifest,
|
|
574
|
+
routeAncestry: trie ? extractAncestryFromTrie(trie) : {},
|
|
575
|
+
routeTrie: trie,
|
|
576
|
+
precomputedEntries: getPrecomputedEntries(),
|
|
577
|
+
},
|
|
578
|
+
null,
|
|
579
|
+
2,
|
|
580
|
+
),
|
|
581
|
+
{
|
|
582
|
+
headers: { "Content-Type": "application/json" },
|
|
429
583
|
},
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
setCookie: (name: string, value: string, options?: any) =>
|
|
433
|
-
reqCtx.setCookie(name, value, options),
|
|
434
|
-
_responseType: preview.responseType,
|
|
435
|
-
};
|
|
436
|
-
// Brand with taint symbol so "use cache" detects it as request-scoped
|
|
437
|
-
// and extracts route-identifying properties (params, pathname, _responseType)
|
|
438
|
-
(responseHandlerCtx as any)[NOCACHE_SYMBOL] = true;
|
|
439
|
-
|
|
440
|
-
// Call handler directly, wrapped by route middleware if present
|
|
441
|
-
const callHandler = async () => {
|
|
442
|
-
// JSON response routes: wrap in { data } / { error } envelope
|
|
443
|
-
if (preview.responseType === "json") {
|
|
444
|
-
const errorCtx = { request, url, env };
|
|
445
|
-
try {
|
|
446
|
-
const result = await (preview.handler as Function)(
|
|
447
|
-
responseHandlerCtx,
|
|
448
|
-
);
|
|
449
|
-
if (result instanceof Response) {
|
|
450
|
-
const mergedHeaders: Record<string, string> = {};
|
|
451
|
-
result.headers.forEach((value, key) => {
|
|
452
|
-
mergedHeaders[key] = value;
|
|
453
|
-
});
|
|
454
|
-
return createResponseWithMergedHeaders(result.body, {
|
|
455
|
-
status: result.status,
|
|
456
|
-
headers: mergedHeaders,
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
return createResponseWithMergedHeaders(
|
|
460
|
-
JSON.stringify({ data: result }),
|
|
461
|
-
{
|
|
462
|
-
status: 200,
|
|
463
|
-
headers: { "content-type": "application/json;charset=utf-8" },
|
|
464
|
-
},
|
|
465
|
-
);
|
|
466
|
-
} catch (error) {
|
|
467
|
-
callOnError(error, "handler", errorCtx);
|
|
468
|
-
const isDev = process.env.NODE_ENV !== "production";
|
|
469
|
-
const status = error instanceof RouterError ? error.status : 500;
|
|
470
|
-
return createResponseWithMergedHeaders(
|
|
471
|
-
JSON.stringify({
|
|
472
|
-
error: createResponseErrorPayload(error, isDev),
|
|
473
|
-
}),
|
|
474
|
-
{
|
|
475
|
-
status,
|
|
476
|
-
headers: { "content-type": "application/json;charset=utf-8" },
|
|
477
|
-
},
|
|
478
|
-
);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// Non-JSON response routes: catch errors and return plain Response
|
|
483
|
-
const errorCtx = { request, url, env };
|
|
484
|
-
try {
|
|
485
|
-
const result = await (preview.handler as Function)(
|
|
486
|
-
responseHandlerCtx,
|
|
487
|
-
);
|
|
488
|
-
|
|
489
|
-
if (result instanceof Response) {
|
|
490
|
-
// Handler returned a Response directly -- pass through
|
|
491
|
-
const mergedHeaders: Record<string, string> = {};
|
|
492
|
-
result.headers.forEach((value, key) => {
|
|
493
|
-
mergedHeaders[key] = value;
|
|
494
|
-
});
|
|
495
|
-
return createResponseWithMergedHeaders(result.body, {
|
|
496
|
-
status: result.status,
|
|
497
|
-
headers: mergedHeaders,
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// Auto-wrap based on response type tag
|
|
502
|
-
switch (preview.responseType) {
|
|
503
|
-
case "text":
|
|
504
|
-
return createResponseWithMergedHeaders(String(result), {
|
|
505
|
-
status: 200,
|
|
506
|
-
headers: { "content-type": "text/plain;charset=utf-8" },
|
|
507
|
-
});
|
|
508
|
-
case "html":
|
|
509
|
-
return createResponseWithMergedHeaders(String(result), {
|
|
510
|
-
status: 200,
|
|
511
|
-
headers: { "content-type": "text/html;charset=utf-8" },
|
|
512
|
-
});
|
|
513
|
-
case "xml":
|
|
514
|
-
return createResponseWithMergedHeaders(String(result), {
|
|
515
|
-
status: 200,
|
|
516
|
-
headers: { "content-type": "application/xml;charset=utf-8" },
|
|
517
|
-
});
|
|
518
|
-
case "md":
|
|
519
|
-
return createResponseWithMergedHeaders(String(result), {
|
|
520
|
-
status: 200,
|
|
521
|
-
headers: { "content-type": "text/markdown;charset=utf-8" },
|
|
522
|
-
});
|
|
523
|
-
default:
|
|
524
|
-
// image, stream, any -- must return Response
|
|
525
|
-
throw new Error(
|
|
526
|
-
`Response route handler for "${preview.responseType}" must return a Response object, got ${typeof result}`,
|
|
527
|
-
);
|
|
528
|
-
}
|
|
529
|
-
} catch (error) {
|
|
530
|
-
callOnError(error, "handler", errorCtx);
|
|
531
|
-
const isDev = process.env.NODE_ENV !== "production";
|
|
532
|
-
const status = error instanceof RouterError ? error.status : 500;
|
|
533
|
-
const message =
|
|
534
|
-
error instanceof RouterError
|
|
535
|
-
? error.message
|
|
536
|
-
: isDev && error instanceof Error
|
|
537
|
-
? error.message
|
|
538
|
-
: "Internal Server Error";
|
|
539
|
-
return createResponseWithMergedHeaders(message, {
|
|
540
|
-
status,
|
|
541
|
-
headers: { "content-type": "text/plain;charset=utf-8" },
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
// Wrap callHandler to append Vary: Accept on content-negotiated responses
|
|
547
|
-
const callHandlerWithVary = async () => {
|
|
548
|
-
const response = await callHandler();
|
|
549
|
-
if (preview.negotiated) {
|
|
550
|
-
response.headers.append("Vary", "Accept");
|
|
551
|
-
}
|
|
552
|
-
return response;
|
|
553
|
-
};
|
|
554
|
-
|
|
555
|
-
// Wrap with response caching if cache() config is present
|
|
556
|
-
const executeHandler = async () => {
|
|
557
|
-
if (preview.routeMiddleware && preview.routeMiddleware.length > 0) {
|
|
558
|
-
const middlewareEntries = preview.routeMiddleware.map((mw) => ({
|
|
559
|
-
entry: {
|
|
560
|
-
pattern: null,
|
|
561
|
-
regex: null,
|
|
562
|
-
paramNames: [],
|
|
563
|
-
handler: mw.handler,
|
|
564
|
-
mountPrefix: null,
|
|
565
|
-
},
|
|
566
|
-
params: mw.params,
|
|
567
|
-
}));
|
|
568
|
-
return executeMiddleware(
|
|
569
|
-
middlewareEntries,
|
|
570
|
-
request,
|
|
571
|
-
env,
|
|
572
|
-
variables,
|
|
573
|
-
callHandlerWithVary,
|
|
574
|
-
createReverseFunction(getRequiredRouteMap()),
|
|
575
|
-
);
|
|
576
|
-
}
|
|
577
|
-
return callHandlerWithVary();
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
// Resolve cache config from entry tree (same pattern as match-api.ts)
|
|
581
|
-
if (preview.manifestEntry) {
|
|
582
|
-
const entries = [...traverseBack(preview.manifestEntry)];
|
|
583
|
-
let cacheScope: ReturnType<typeof createCacheScope> = null;
|
|
584
|
-
for (const entry of entries) {
|
|
585
|
-
if (entry.cache) {
|
|
586
|
-
cacheScope = createCacheScope(entry.cache, cacheScope);
|
|
587
|
-
}
|
|
588
|
-
}
|
|
584
|
+
);
|
|
585
|
+
}
|
|
589
586
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
`[ResponseCache] Revalidation failed:`,
|
|
628
|
-
error,
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
return cached.response;
|
|
634
|
-
}
|
|
635
|
-
} catch (error) {
|
|
636
|
-
console.error(`[ResponseCache] Cache lookup failed:`, error);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Cache miss - execute handler and cache the result
|
|
640
|
-
const response = await executeHandler();
|
|
641
|
-
|
|
642
|
-
if (isCacheableStatus(response.status)) {
|
|
643
|
-
reqCtx.waitUntil(async () => {
|
|
644
|
-
try {
|
|
645
|
-
await store.putResponse!(
|
|
646
|
-
cacheKey,
|
|
647
|
-
response.clone(),
|
|
648
|
-
cacheScope!.ttl,
|
|
649
|
-
cacheScope!.swr,
|
|
650
|
-
);
|
|
651
|
-
} catch (error) {
|
|
652
|
-
console.error(`[ResponseCache] Cache write failed:`, error);
|
|
653
|
-
}
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
return response;
|
|
658
|
-
}
|
|
659
|
-
}
|
|
587
|
+
// ---- 1. Classify ----
|
|
588
|
+
// classifyRequest may throw RouteNotFoundError for unknown routes.
|
|
589
|
+
// In that case, fall through to a full-render plan so the pipeline
|
|
590
|
+
// can render the 404 page via the existing error handling path.
|
|
591
|
+
const classifyStart = performance.now();
|
|
592
|
+
let plan: RequestPlan<TEnv>;
|
|
593
|
+
try {
|
|
594
|
+
plan = await classifyRequest<TEnv>(request, url, {
|
|
595
|
+
findMatch: router.findMatch,
|
|
596
|
+
routerVersion: version,
|
|
597
|
+
routerId: router.id,
|
|
598
|
+
});
|
|
599
|
+
} catch (error) {
|
|
600
|
+
if (
|
|
601
|
+
error instanceof RouteNotFoundError ||
|
|
602
|
+
(error instanceof Error && error.name === "RouteNotFoundError")
|
|
603
|
+
) {
|
|
604
|
+
// Let the render path handle 404 — match()/matchPartial() will
|
|
605
|
+
// re-throw RouteNotFoundError and the catch block in
|
|
606
|
+
// executeRenderWithMiddleware renders the not-found page.
|
|
607
|
+
plan = {
|
|
608
|
+
mode: "full-render",
|
|
609
|
+
route: {
|
|
610
|
+
matched: null as any,
|
|
611
|
+
manifestEntry: null as any,
|
|
612
|
+
entries: [],
|
|
613
|
+
routeKey: "",
|
|
614
|
+
localRouteName: "",
|
|
615
|
+
params: {},
|
|
616
|
+
routeMiddleware: [],
|
|
617
|
+
cacheScope: null,
|
|
618
|
+
isPassthrough: false,
|
|
619
|
+
},
|
|
620
|
+
negotiated: false,
|
|
621
|
+
};
|
|
622
|
+
} else {
|
|
623
|
+
throw error;
|
|
660
624
|
}
|
|
661
|
-
|
|
662
|
-
return executeHandler();
|
|
663
625
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
preview?.params,
|
|
674
|
-
preview?.routeKey,
|
|
675
|
-
);
|
|
676
|
-
if (preview?.negotiated) {
|
|
677
|
-
response.headers.append("Vary", "Accept");
|
|
626
|
+
const classifyDur = performance.now() - classifyStart;
|
|
627
|
+
handlerTiming.push(`handler-classify;dur=${classifyDur.toFixed(2)}`);
|
|
628
|
+
|
|
629
|
+
// ---- 2. Terminal plans (no execution needed) ----
|
|
630
|
+
if (plan.mode === "redirect") {
|
|
631
|
+
// Redirects are handled by the pipeline (match/matchPartial),
|
|
632
|
+
// but for partial requests we short-circuit with a Flight redirect.
|
|
633
|
+
if (url.searchParams.has("_rsc_partial")) {
|
|
634
|
+
return createRedirectFlightResponse(plan.redirectUrl);
|
|
678
635
|
}
|
|
679
|
-
|
|
680
|
-
|
|
636
|
+
// Full requests: let the pipeline handle the redirect via match()
|
|
637
|
+
// which returns { redirect: url }. Fall through to full-render.
|
|
638
|
+
}
|
|
681
639
|
|
|
682
|
-
if (
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
640
|
+
if (plan.mode === "version-mismatch") {
|
|
641
|
+
console.log(
|
|
642
|
+
`[RSC] Version mismatch: client=${url.searchParams.get("_rsc_v")}, server=${version}. Forcing reload.`,
|
|
643
|
+
);
|
|
644
|
+
return createResponseWithMergedHeaders(null, {
|
|
645
|
+
status: 200,
|
|
646
|
+
headers: {
|
|
647
|
+
"X-RSC-Reload": plan.reloadUrl,
|
|
648
|
+
"content-type": "text/x-component;charset=utf-8",
|
|
691
649
|
},
|
|
692
|
-
|
|
693
|
-
|
|
650
|
+
});
|
|
651
|
+
}
|
|
694
652
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
653
|
+
// ---- 3. Origin guard (gate for action/loader/PE modes) ----
|
|
654
|
+
const originPhase: OriginCheckPhase | null =
|
|
655
|
+
plan.mode === "action"
|
|
656
|
+
? "action"
|
|
657
|
+
: plan.mode === "loader"
|
|
658
|
+
? "loader"
|
|
659
|
+
: plan.mode === "pe-render"
|
|
660
|
+
? "pe-form"
|
|
661
|
+
: null;
|
|
662
|
+
if (originPhase) {
|
|
663
|
+
const originResult = await checkRequestOrigin(
|
|
698
664
|
request,
|
|
665
|
+
url,
|
|
666
|
+
router.originCheck,
|
|
699
667
|
env,
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
createReverseFunction(getRequiredRouteMap()),
|
|
668
|
+
router.id,
|
|
669
|
+
originPhase,
|
|
703
670
|
);
|
|
671
|
+
if (originResult) {
|
|
672
|
+
const originError = new Error(
|
|
673
|
+
`Origin check rejected: ${request.headers.get("origin") ?? "none"} vs ${request.headers.get("host") ?? "none"}`,
|
|
674
|
+
);
|
|
675
|
+
originError.name = "OriginCheckError";
|
|
704
676
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
677
|
+
callOnError(originError, "origin", {
|
|
678
|
+
request,
|
|
679
|
+
url,
|
|
680
|
+
env,
|
|
681
|
+
handledByBoundary: false,
|
|
682
|
+
metadata: {
|
|
683
|
+
phase: originPhase,
|
|
684
|
+
origin: request.headers.get("origin"),
|
|
685
|
+
host: request.headers.get("host"),
|
|
686
|
+
},
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
try {
|
|
690
|
+
const routerCtx = getRouterContext();
|
|
691
|
+
if (routerCtx?.telemetry) {
|
|
692
|
+
safeEmit(resolveSink(routerCtx.telemetry), {
|
|
693
|
+
type: "request.origin-rejected" as const,
|
|
694
|
+
timestamp: performance.now(),
|
|
695
|
+
requestId: routerCtx.requestId,
|
|
696
|
+
method: request.method,
|
|
697
|
+
pathname: url.pathname,
|
|
698
|
+
phase: originPhase,
|
|
699
|
+
origin: request.headers.get("origin"),
|
|
700
|
+
host: request.headers.get("host"),
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
} catch {
|
|
704
|
+
// Router context may not be available
|
|
721
705
|
}
|
|
722
|
-
return createSimpleRedirectResponse(mwRedirectUrl);
|
|
723
|
-
}
|
|
724
706
|
|
|
725
|
-
|
|
707
|
+
return originResult;
|
|
708
|
+
}
|
|
726
709
|
}
|
|
727
710
|
|
|
728
|
-
//
|
|
729
|
-
return
|
|
711
|
+
// ---- 4. Execute ----
|
|
712
|
+
return executeRequest(
|
|
713
|
+
plan as ExecutableRequestPlan<TEnv>,
|
|
714
|
+
request,
|
|
715
|
+
env,
|
|
716
|
+
url,
|
|
717
|
+
variables,
|
|
718
|
+
nonce,
|
|
719
|
+
);
|
|
730
720
|
}
|
|
731
721
|
|
|
732
|
-
//
|
|
733
|
-
|
|
722
|
+
// Execute a classified request plan. Dispatches to the appropriate handler
|
|
723
|
+
// based on plan.mode. Lives in the createRSCHandler closure for access to
|
|
724
|
+
// handlerCtx, router, callOnError, etc.
|
|
725
|
+
// Only receives executable plans (version-mismatch is handled above).
|
|
726
|
+
async function executeRequest(
|
|
727
|
+
plan: ExecutableRequestPlan<TEnv>,
|
|
734
728
|
request: Request,
|
|
735
729
|
env: TEnv,
|
|
736
730
|
url: URL,
|
|
737
731
|
variables: Record<string, any>,
|
|
738
732
|
nonce: string | undefined,
|
|
739
|
-
routeParams?: Record<string, string>,
|
|
740
|
-
routeKey?: string,
|
|
741
733
|
): Promise<Response> {
|
|
742
|
-
|
|
743
|
-
const
|
|
744
|
-
request.headers.has("rsc-action") || url.searchParams.has("_rsc_action");
|
|
745
|
-
const actionId =
|
|
746
|
-
request.headers.get("rsc-action") || url.searchParams.get("_rsc_action");
|
|
747
|
-
|
|
748
|
-
// Version mismatch detection - client may have stale code after HMR/deployment
|
|
749
|
-
// If versions don't match, tell the client to reload
|
|
750
|
-
const clientVersion = url.searchParams.get("_rsc_v");
|
|
751
|
-
if (version && clientVersion && clientVersion !== version) {
|
|
752
|
-
console.log(
|
|
753
|
-
`[RSC] Version mismatch: client=${clientVersion}, server=${version}. Forcing reload.`,
|
|
754
|
-
);
|
|
734
|
+
// Common setup
|
|
735
|
+
const handleStore = requireRequestContext()._handleStore;
|
|
755
736
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
}
|
|
737
|
+
// Wire up error reporting for late streaming-handle failures
|
|
738
|
+
handleStore.onError = (error: Error) => {
|
|
739
|
+
const reqCtx = requireRequestContext();
|
|
740
|
+
callOnError(error, "handler", {
|
|
741
|
+
request,
|
|
742
|
+
url,
|
|
743
|
+
routeKey: reqCtx._routeName,
|
|
744
|
+
params: reqCtx.params as Record<string, string>,
|
|
745
|
+
handledByBoundary: true,
|
|
746
|
+
});
|
|
747
|
+
try {
|
|
748
|
+
const routerCtx = getRouterContext();
|
|
749
|
+
if (routerCtx?.telemetry) {
|
|
750
|
+
safeEmit(resolveSink(routerCtx.telemetry), {
|
|
751
|
+
type: "handler.error" as const,
|
|
752
|
+
timestamp: performance.now(),
|
|
753
|
+
requestId: routerCtx.requestId,
|
|
754
|
+
error,
|
|
755
|
+
handledByBoundary: true,
|
|
756
|
+
pathname: url.pathname,
|
|
757
|
+
routeKey: reqCtx._routeName,
|
|
758
|
+
params: reqCtx.params as Record<string, string>,
|
|
759
|
+
});
|
|
780
760
|
}
|
|
761
|
+
} catch {
|
|
762
|
+
// Router context may not be available (e.g. prerender path)
|
|
781
763
|
}
|
|
764
|
+
};
|
|
782
765
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
},
|
|
790
|
-
});
|
|
766
|
+
// Set route params early so all execution paths can access ctx.params.
|
|
767
|
+
// Also store the classified snapshot so match/matchPartial can reuse it
|
|
768
|
+
// instead of calling resolveRoute again.
|
|
769
|
+
if (plan.mode !== "redirect") {
|
|
770
|
+
setRequestContextParams(plan.route.params, plan.route.routeKey);
|
|
771
|
+
requireRequestContext()._classifiedRoute = plan.route;
|
|
791
772
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
773
|
+
|
|
774
|
+
const routeReverse = createReverseFunction(getRequiredRouteMap());
|
|
775
|
+
|
|
776
|
+
// ---- Response route: skip entire RSC pipeline ----
|
|
777
|
+
if (plan.mode === "response") {
|
|
778
|
+
// Build ResponseRouteMatch from plan fields. handleResponseRoute
|
|
779
|
+
// expects a flat object with params at the top level.
|
|
780
|
+
const responseMatch: ResponseRouteMatch = {
|
|
781
|
+
responseType: plan.responseType,
|
|
782
|
+
handler: plan.handler,
|
|
783
|
+
params: plan.route.params,
|
|
784
|
+
negotiated: plan.negotiated,
|
|
785
|
+
manifestEntry: plan.manifestEntry,
|
|
786
|
+
routeMiddleware: plan.routeMiddleware,
|
|
787
|
+
};
|
|
788
|
+
const responseOutcome = await withTimeout(
|
|
789
|
+
handleResponseRoute(
|
|
790
|
+
handlerCtx,
|
|
791
|
+
responseMatch,
|
|
792
|
+
request,
|
|
793
|
+
env,
|
|
794
|
+
url,
|
|
795
|
+
variables,
|
|
814
796
|
),
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
},
|
|
797
|
+
router.timeouts.renderStartMs,
|
|
798
|
+
"render-start",
|
|
818
799
|
);
|
|
800
|
+
if (responseOutcome.timedOut) {
|
|
801
|
+
return handleTimeoutResponse(
|
|
802
|
+
request,
|
|
803
|
+
env,
|
|
804
|
+
url,
|
|
805
|
+
"render-start",
|
|
806
|
+
responseOutcome.durationMs,
|
|
807
|
+
plan.route.routeKey,
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
const response = responseOutcome.result;
|
|
811
|
+
if (plan.negotiated && !isWebSocketUpgradeResponse(response)) {
|
|
812
|
+
response.headers.append("Vary", "Accept");
|
|
813
|
+
}
|
|
814
|
+
return response;
|
|
819
815
|
}
|
|
820
816
|
|
|
821
|
-
//
|
|
822
|
-
|
|
817
|
+
// SSR setup: kick off in parallel for modes that need HTML rendering.
|
|
818
|
+
// Placed after response-route short-circuit so response/mime routes
|
|
819
|
+
// never pay for SSR work.
|
|
820
|
+
if (plan.mode !== "loader" && mayNeedSSR(request, url)) {
|
|
821
|
+
variables[SSR_SETUP_VAR] = startSSRSetup(
|
|
822
|
+
handlerCtx,
|
|
823
|
+
request,
|
|
824
|
+
env,
|
|
825
|
+
url,
|
|
826
|
+
router.debugPerformance
|
|
827
|
+
? () => requireRequestContext()._metricsStore
|
|
828
|
+
: undefined,
|
|
829
|
+
);
|
|
830
|
+
}
|
|
823
831
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
832
|
+
// ---- Loader fetch ----
|
|
833
|
+
if (plan.mode === "loader") {
|
|
834
|
+
return handleLoaderFetch(
|
|
835
|
+
handlerCtx,
|
|
836
|
+
request,
|
|
837
|
+
env,
|
|
838
|
+
url,
|
|
839
|
+
variables,
|
|
840
|
+
plan.route.params,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
831
843
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
const progressiveResult = await handleProgressiveEnhancement(
|
|
844
|
+
// ---- Progressive enhancement ----
|
|
845
|
+
if (plan.mode === "pe-render") {
|
|
846
|
+
const peResult = await handleProgressiveEnhancement(
|
|
836
847
|
handlerCtx,
|
|
837
848
|
request,
|
|
838
849
|
env,
|
|
839
850
|
url,
|
|
840
|
-
isAction
|
|
851
|
+
false, // isAction = false for PE
|
|
841
852
|
handleStore,
|
|
842
853
|
nonce,
|
|
854
|
+
{
|
|
855
|
+
routeMiddleware: plan.route.routeMiddleware,
|
|
856
|
+
variables,
|
|
857
|
+
routeReverse,
|
|
858
|
+
},
|
|
843
859
|
);
|
|
844
|
-
if (
|
|
845
|
-
|
|
846
|
-
|
|
860
|
+
if (peResult) return peResult;
|
|
861
|
+
// PE handler returned null (not a PE form) — fall through to render
|
|
862
|
+
}
|
|
847
863
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
864
|
+
// ---- Action: execute action, then revalidate wrapped in route middleware ----
|
|
865
|
+
if (plan.mode === "action") {
|
|
866
|
+
let actionContinuation: ActionContinuation | undefined;
|
|
867
|
+
try {
|
|
868
|
+
const actionOutcome = await withTimeout(
|
|
869
|
+
executeServerAction(
|
|
854
870
|
handlerCtx,
|
|
855
871
|
request,
|
|
856
872
|
env,
|
|
857
873
|
url,
|
|
858
|
-
actionId,
|
|
874
|
+
plan.actionId,
|
|
859
875
|
handleStore,
|
|
860
|
-
)
|
|
861
|
-
|
|
862
|
-
|
|
876
|
+
),
|
|
877
|
+
router.timeouts.actionMs,
|
|
878
|
+
"action",
|
|
879
|
+
);
|
|
880
|
+
if (actionOutcome.timedOut) {
|
|
881
|
+
return handleTimeoutResponse(
|
|
863
882
|
request,
|
|
864
|
-
url,
|
|
865
883
|
env,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
884
|
+
url,
|
|
885
|
+
"action",
|
|
886
|
+
actionOutcome.durationMs,
|
|
887
|
+
plan.route.routeKey,
|
|
888
|
+
plan.actionId,
|
|
889
|
+
);
|
|
871
890
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
if (isLoaderRequest) {
|
|
879
|
-
return handleLoaderFetch(
|
|
880
|
-
handlerCtx,
|
|
891
|
+
const result = actionOutcome.result;
|
|
892
|
+
// Response means redirect or error boundary — done.
|
|
893
|
+
if (result instanceof Response) return result;
|
|
894
|
+
actionContinuation = result;
|
|
895
|
+
} catch (error) {
|
|
896
|
+
callOnError(error, "action", {
|
|
881
897
|
request,
|
|
882
|
-
env,
|
|
883
898
|
url,
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
899
|
+
env,
|
|
900
|
+
actionId: plan.actionId,
|
|
901
|
+
handledByBoundary: false,
|
|
902
|
+
});
|
|
903
|
+
console.error(`[RSC] Action error:`, error);
|
|
904
|
+
throw error;
|
|
887
905
|
}
|
|
888
906
|
|
|
889
|
-
//
|
|
890
|
-
//
|
|
891
|
-
//
|
|
892
|
-
//
|
|
893
|
-
|
|
894
|
-
|
|
907
|
+
// Revalidation render wrapped in route middleware.
|
|
908
|
+
// Actions from client-side navigation include _rsc_partial — preserve
|
|
909
|
+
// the partial flag so the revalidation returns a Flight stream, not HTML.
|
|
910
|
+
// App-switch is already excluded by classifyRequest (would be full-render).
|
|
911
|
+
const isPartialAction = url.searchParams.has("_rsc_partial");
|
|
912
|
+
return executeRenderWithMiddleware(
|
|
913
|
+
plan.route.routeMiddleware,
|
|
914
|
+
plan.negotiated,
|
|
915
|
+
plan.route.routeKey,
|
|
916
|
+
routeReverse,
|
|
895
917
|
request,
|
|
896
918
|
env,
|
|
897
919
|
url,
|
|
898
|
-
|
|
920
|
+
variables,
|
|
921
|
+
nonce,
|
|
899
922
|
handleStore,
|
|
923
|
+
isPartialAction,
|
|
924
|
+
actionContinuation,
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// ---- Full render / Partial render (or PE that fell through) ----
|
|
929
|
+
if (plan.mode === "full-render" || plan.mode === "partial-render") {
|
|
930
|
+
const isPartial = plan.mode === "partial-render";
|
|
931
|
+
return executeRenderWithMiddleware(
|
|
932
|
+
plan.route.routeMiddleware,
|
|
933
|
+
plan.negotiated,
|
|
934
|
+
plan.route.routeKey,
|
|
935
|
+
routeReverse,
|
|
936
|
+
request,
|
|
937
|
+
env,
|
|
938
|
+
url,
|
|
939
|
+
variables,
|
|
900
940
|
nonce,
|
|
941
|
+
handleStore,
|
|
942
|
+
isPartial,
|
|
901
943
|
);
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// PE that fell through (handleProgressiveEnhancement returned null)
|
|
947
|
+
// falls back to full render
|
|
948
|
+
if (plan.mode === "pe-render") {
|
|
949
|
+
return executeRenderWithMiddleware(
|
|
950
|
+
plan.route.routeMiddleware,
|
|
951
|
+
false,
|
|
952
|
+
plan.route.routeKey,
|
|
953
|
+
routeReverse,
|
|
954
|
+
request,
|
|
955
|
+
env,
|
|
956
|
+
url,
|
|
957
|
+
variables,
|
|
958
|
+
nonce,
|
|
959
|
+
handleStore,
|
|
960
|
+
false,
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// Redirect plan that wasn't handled above (full-page redirect — let
|
|
965
|
+
// the pipeline handle it via match() which returns { redirect: url })
|
|
966
|
+
return executeRenderWithMiddleware(
|
|
967
|
+
plan.route.routeMiddleware,
|
|
968
|
+
false,
|
|
969
|
+
plan.route.routeKey,
|
|
970
|
+
routeReverse,
|
|
971
|
+
request,
|
|
972
|
+
env,
|
|
973
|
+
url,
|
|
974
|
+
variables,
|
|
975
|
+
nonce,
|
|
976
|
+
handleStore,
|
|
977
|
+
false,
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// Shared render execution: wraps handleRscRendering (or revalidateAfterAction)
|
|
982
|
+
// in route middleware and timeout handling. Consolidates the pattern used by
|
|
983
|
+
// action-revalidate, full-render, and partial-render modes.
|
|
984
|
+
async function executeRenderWithMiddleware(
|
|
985
|
+
routeMiddleware: import("../router/middleware-types.js").CollectedMiddleware[],
|
|
986
|
+
negotiated: boolean,
|
|
987
|
+
routeKey: string,
|
|
988
|
+
routeReverse: ReturnType<typeof createReverseFunction>,
|
|
989
|
+
request: Request,
|
|
990
|
+
env: TEnv,
|
|
991
|
+
url: URL,
|
|
992
|
+
variables: Record<string, any>,
|
|
993
|
+
nonce: string | undefined,
|
|
994
|
+
handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
|
|
995
|
+
isPartial: boolean,
|
|
996
|
+
actionContinuation?: ActionContinuation,
|
|
997
|
+
): Promise<Response> {
|
|
998
|
+
const renderHandler = async (): Promise<Response> => {
|
|
999
|
+
try {
|
|
1000
|
+
let response: Response;
|
|
1001
|
+
if (actionContinuation) {
|
|
1002
|
+
response = await revalidateAfterAction(
|
|
1003
|
+
handlerCtx,
|
|
1004
|
+
request,
|
|
1005
|
+
env,
|
|
1006
|
+
url,
|
|
1007
|
+
handleStore,
|
|
1008
|
+
actionContinuation,
|
|
1009
|
+
);
|
|
1010
|
+
} else {
|
|
1011
|
+
response = await handleRscRendering(
|
|
1012
|
+
handlerCtx,
|
|
1013
|
+
request,
|
|
1014
|
+
env,
|
|
1015
|
+
url,
|
|
1016
|
+
isPartial,
|
|
1017
|
+
handleStore,
|
|
1018
|
+
nonce,
|
|
914
1019
|
);
|
|
915
|
-
const cleanUrl = new URL(url);
|
|
916
|
-
cleanUrl.searchParams.delete("_rsc_partial");
|
|
917
|
-
cleanUrl.searchParams.delete("_rsc_segments");
|
|
918
|
-
cleanUrl.searchParams.delete("_rsc_v");
|
|
919
|
-
cleanUrl.searchParams.delete("_rsc_stale");
|
|
920
|
-
cleanUrl.searchParams.delete("_rsc_action");
|
|
921
|
-
cleanUrl.searchParams.delete("_rsc_prev");
|
|
922
|
-
return createResponseWithMergedHeaders(null, {
|
|
923
|
-
status: 200,
|
|
924
|
-
headers: {
|
|
925
|
-
"X-RSC-Reload": cleanUrl.toString(),
|
|
926
|
-
"content-type": "text/x-component;charset=utf-8",
|
|
927
|
-
},
|
|
928
|
-
});
|
|
929
1020
|
}
|
|
1021
|
+
if (negotiated && !isWebSocketUpgradeResponse(response)) {
|
|
1022
|
+
response.headers.append("Vary", "Accept");
|
|
1023
|
+
}
|
|
1024
|
+
return response;
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
// Check if middleware/handler returned Response
|
|
1027
|
+
if (error instanceof Response) {
|
|
1028
|
+
// During partial (client-side navigation), a 200 Response from a handler
|
|
1029
|
+
// means the route serves raw content (JSON, text, etc.), not JSX.
|
|
1030
|
+
// Signal the browser to hard-navigate so it renders the raw response.
|
|
1031
|
+
if (isPartial && error.status === 200) {
|
|
1032
|
+
console.warn(
|
|
1033
|
+
`[RSC] Route handler at ${url.pathname} returned a Response during client-side navigation. ` +
|
|
1034
|
+
`Falling back to hard navigation. Use data-external on the <Link> to avoid the extra round-trip.`,
|
|
1035
|
+
);
|
|
1036
|
+
return createResponseWithMergedHeaders(null, {
|
|
1037
|
+
status: 200,
|
|
1038
|
+
headers: {
|
|
1039
|
+
"X-RSC-Reload": stripInternalParams(url).toString(),
|
|
1040
|
+
"content-type": "text/x-component;charset=utf-8",
|
|
1041
|
+
},
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
930
1044
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
// - Without state: 204 + X-RSC-Redirect header (lightweight).
|
|
936
|
-
const redirectUrl = error.headers.get("Location");
|
|
937
|
-
const isRedirect =
|
|
938
|
-
error.status >= 300 && error.status < 400 && redirectUrl;
|
|
939
|
-
if (isPartial && isRedirect) {
|
|
940
|
-
const locationState = getLocationState();
|
|
941
|
-
if (locationState) {
|
|
942
|
-
return createRedirectFlightResponse(
|
|
943
|
-
redirectUrl,
|
|
944
|
-
resolveLocationStateEntries(locationState),
|
|
1045
|
+
if (isPartial) {
|
|
1046
|
+
const intercepted = interceptRedirectForPartial(
|
|
1047
|
+
error,
|
|
1048
|
+
createRedirectFlightResponse,
|
|
945
1049
|
);
|
|
1050
|
+
if (intercepted) return intercepted;
|
|
946
1051
|
}
|
|
947
|
-
|
|
1052
|
+
|
|
1053
|
+
return error;
|
|
948
1054
|
}
|
|
949
1055
|
|
|
950
|
-
|
|
951
|
-
|
|
1056
|
+
// Render 404 page for unmatched routes
|
|
1057
|
+
const isRouteNotFound =
|
|
1058
|
+
error instanceof RouteNotFoundError ||
|
|
1059
|
+
(error instanceof Error && error.name === "RouteNotFoundError");
|
|
1060
|
+
if (isRouteNotFound) {
|
|
1061
|
+
callOnError(error, "routing", {
|
|
1062
|
+
request,
|
|
1063
|
+
url,
|
|
1064
|
+
env,
|
|
1065
|
+
handledByBoundary: true,
|
|
1066
|
+
});
|
|
952
1067
|
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1068
|
+
const notFoundOption = router.notFound;
|
|
1069
|
+
const notFoundComponent =
|
|
1070
|
+
typeof notFoundOption === "function"
|
|
1071
|
+
? notFoundOption({ pathname: url.pathname })
|
|
1072
|
+
: (notFoundOption ?? createElement("h1", null, "Not Found"));
|
|
1073
|
+
|
|
1074
|
+
const notFoundSegment = {
|
|
1075
|
+
id: "notFound",
|
|
1076
|
+
namespace: "notFound",
|
|
1077
|
+
type: "route" as const,
|
|
1078
|
+
index: 0,
|
|
1079
|
+
component: notFoundComponent,
|
|
1080
|
+
params: {},
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
const payload: RscPayload = {
|
|
1084
|
+
metadata: {
|
|
1085
|
+
pathname: url.pathname,
|
|
1086
|
+
routerId: router.id,
|
|
1087
|
+
basename: router.basename,
|
|
1088
|
+
segments: [notFoundSegment],
|
|
1089
|
+
matched: [],
|
|
1090
|
+
diff: [],
|
|
1091
|
+
isPartial: false,
|
|
1092
|
+
rootLayout: router.rootLayout,
|
|
1093
|
+
handles: handleStore.stream(),
|
|
1094
|
+
version,
|
|
1095
|
+
themeConfig: router.themeConfig,
|
|
1096
|
+
warmupEnabled: router.warmupEnabled,
|
|
1097
|
+
initialTheme: requireRequestContext().theme,
|
|
1098
|
+
},
|
|
1099
|
+
};
|
|
965
1100
|
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
: (notFoundOption ?? createElement("h1", null, "Not Found"));
|
|
972
|
-
|
|
973
|
-
// Create a simple segment for the 404 page
|
|
974
|
-
const notFoundSegment = {
|
|
975
|
-
id: "notFound",
|
|
976
|
-
namespace: "notFound",
|
|
977
|
-
type: "route" as const,
|
|
978
|
-
index: 0,
|
|
979
|
-
component: notFoundComponent,
|
|
980
|
-
params: {},
|
|
981
|
-
};
|
|
1101
|
+
const rscStream = renderToReadableStream(payload, {
|
|
1102
|
+
onError: (error: unknown) => {
|
|
1103
|
+
callOnError(error, "rendering", { request, url, env });
|
|
1104
|
+
},
|
|
1105
|
+
});
|
|
982
1106
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
diff: [],
|
|
989
|
-
isPartial: false,
|
|
990
|
-
rootLayout: router.rootLayout,
|
|
991
|
-
handles: handleStore.stream(),
|
|
992
|
-
version,
|
|
993
|
-
themeConfig: router.themeConfig,
|
|
994
|
-
warmupEnabled: router.warmupEnabled,
|
|
995
|
-
initialTheme: requireRequestContext().theme,
|
|
996
|
-
// No routeName for not-found routes
|
|
997
|
-
},
|
|
998
|
-
};
|
|
1107
|
+
const isRscRequest =
|
|
1108
|
+
isPartial ||
|
|
1109
|
+
(!request.headers.get("accept")?.includes("text/html") &&
|
|
1110
|
+
!url.searchParams.has("__html")) ||
|
|
1111
|
+
url.searchParams.has("__rsc");
|
|
999
1112
|
|
|
1000
|
-
|
|
1113
|
+
if (isRscRequest) {
|
|
1114
|
+
return createResponseWithMergedHeaders(rscStream, {
|
|
1115
|
+
status: 404,
|
|
1116
|
+
headers: { "content-type": "text/x-component;charset=utf-8" },
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1001
1119
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1120
|
+
const [ssrModule, streamMode] = await getSSRSetup(
|
|
1121
|
+
handlerCtx,
|
|
1122
|
+
request,
|
|
1123
|
+
env,
|
|
1124
|
+
url,
|
|
1125
|
+
requireRequestContext()._metricsStore,
|
|
1126
|
+
);
|
|
1127
|
+
const htmlStream = await ssrModule.renderHTML(rscStream, {
|
|
1128
|
+
nonce,
|
|
1129
|
+
streamMode,
|
|
1130
|
+
});
|
|
1009
1131
|
|
|
1010
|
-
|
|
1011
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
1132
|
+
return createResponseWithMergedHeaders(htmlStream, {
|
|
1012
1133
|
status: 404,
|
|
1013
|
-
headers: { "content-type": "text/
|
|
1134
|
+
headers: { "content-type": "text/html;charset=utf-8" },
|
|
1014
1135
|
});
|
|
1015
1136
|
}
|
|
1016
1137
|
|
|
1017
|
-
//
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
headers: { "content-type": "text/html;charset=utf-8" },
|
|
1138
|
+
// Report unhandled errors
|
|
1139
|
+
callOnError(error, "routing", {
|
|
1140
|
+
request,
|
|
1141
|
+
url,
|
|
1142
|
+
env,
|
|
1143
|
+
handledByBoundary: false,
|
|
1024
1144
|
});
|
|
1145
|
+
console.error(`[RSC] Error:`, error);
|
|
1146
|
+
throw error;
|
|
1025
1147
|
}
|
|
1148
|
+
};
|
|
1149
|
+
|
|
1150
|
+
// Wrap the render path in a renderStartMs timeout
|
|
1151
|
+
const executeRender = async (): Promise<Response> => {
|
|
1152
|
+
if (routeMiddleware.length > 0) {
|
|
1153
|
+
const mwResponse = await executeMiddleware(
|
|
1154
|
+
buildRouteMiddlewareEntries<TEnv>(routeMiddleware),
|
|
1155
|
+
request,
|
|
1156
|
+
env,
|
|
1157
|
+
variables,
|
|
1158
|
+
renderHandler,
|
|
1159
|
+
routeReverse,
|
|
1160
|
+
);
|
|
1026
1161
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1162
|
+
if (isPartial || actionContinuation) {
|
|
1163
|
+
const intercepted = interceptRedirectForPartial(
|
|
1164
|
+
mwResponse,
|
|
1165
|
+
createRedirectFlightResponse,
|
|
1166
|
+
);
|
|
1167
|
+
if (intercepted) return intercepted;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
return finalizeResponse(mwResponse);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
return renderHandler();
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
const renderOutcome = await withTimeout(
|
|
1177
|
+
executeRender(),
|
|
1178
|
+
router.timeouts.renderStartMs,
|
|
1179
|
+
"render-start",
|
|
1180
|
+
);
|
|
1181
|
+
if (renderOutcome.timedOut) {
|
|
1182
|
+
return handleTimeoutResponse(
|
|
1029
1183
|
request,
|
|
1030
|
-
url,
|
|
1031
1184
|
env,
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1185
|
+
url,
|
|
1186
|
+
"render-start",
|
|
1187
|
+
renderOutcome.durationMs,
|
|
1188
|
+
routeKey,
|
|
1189
|
+
);
|
|
1036
1190
|
}
|
|
1191
|
+
return renderOutcome.result;
|
|
1037
1192
|
}
|
|
1038
1193
|
}
|