@rangojs/router 0.0.0-experimental.5 → 0.0.0-experimental.5035014b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -0
- package/README.md +884 -4
- package/dist/__internal.d.ts +83 -0
- package/dist/__internal.d.ts.map +1 -0
- package/dist/__internal.js +19 -0
- package/dist/__internal.js.map +1 -0
- package/dist/__mocks__/version.d.ts +7 -0
- package/dist/__mocks__/version.d.ts.map +1 -0
- package/dist/__mocks__/version.js +7 -0
- package/dist/__mocks__/version.js.map +1 -0
- package/dist/__tests__/client-href.test.d.ts +2 -0
- package/dist/__tests__/client-href.test.d.ts.map +1 -0
- package/dist/__tests__/client-href.test.js +74 -0
- package/dist/__tests__/client-href.test.js.map +1 -0
- package/dist/__tests__/component-utils.test.d.ts +2 -0
- package/dist/__tests__/component-utils.test.d.ts.map +1 -0
- package/dist/__tests__/component-utils.test.js +51 -0
- package/dist/__tests__/component-utils.test.js.map +1 -0
- package/dist/__tests__/event-controller.test.d.ts +2 -0
- package/dist/__tests__/event-controller.test.d.ts.map +1 -0
- package/dist/__tests__/event-controller.test.js +538 -0
- package/dist/__tests__/event-controller.test.js.map +1 -0
- package/dist/__tests__/helpers/route-tree.d.ts +118 -0
- package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
- package/dist/__tests__/helpers/route-tree.js +374 -0
- package/dist/__tests__/helpers/route-tree.js.map +1 -0
- package/dist/__tests__/match-result.test.d.ts +2 -0
- package/dist/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/__tests__/match-result.test.js +154 -0
- package/dist/__tests__/match-result.test.js.map +1 -0
- package/dist/__tests__/navigation-store.test.d.ts +2 -0
- package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
- package/dist/__tests__/navigation-store.test.js +440 -0
- package/dist/__tests__/navigation-store.test.js.map +1 -0
- package/dist/__tests__/partial-update.test.d.ts +2 -0
- package/dist/__tests__/partial-update.test.d.ts.map +1 -0
- package/dist/__tests__/partial-update.test.js +1009 -0
- package/dist/__tests__/partial-update.test.js.map +1 -0
- package/dist/__tests__/reverse-types.test.d.ts +8 -0
- package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-types.test.js +656 -0
- package/dist/__tests__/reverse-types.test.js.map +1 -0
- package/dist/__tests__/route-definition.test.d.ts +2 -0
- package/dist/__tests__/route-definition.test.d.ts.map +1 -0
- package/dist/__tests__/route-definition.test.js +55 -0
- package/dist/__tests__/route-definition.test.js.map +1 -0
- package/dist/__tests__/router-helpers.test.d.ts +2 -0
- package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/router-helpers.test.js +377 -0
- package/dist/__tests__/router-helpers.test.js.map +1 -0
- package/dist/__tests__/router-integration-2.test.d.ts +2 -0
- package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration-2.test.js +426 -0
- package/dist/__tests__/router-integration-2.test.js.map +1 -0
- package/dist/__tests__/router-integration.test.d.ts +2 -0
- package/dist/__tests__/router-integration.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration.test.js +1051 -0
- package/dist/__tests__/router-integration.test.js.map +1 -0
- package/dist/__tests__/search-params.test.d.ts +5 -0
- package/dist/__tests__/search-params.test.d.ts.map +1 -0
- package/dist/__tests__/search-params.test.js +306 -0
- package/dist/__tests__/search-params.test.js.map +1 -0
- package/dist/__tests__/segment-system.test.d.ts +2 -0
- package/dist/__tests__/segment-system.test.d.ts.map +1 -0
- package/dist/__tests__/segment-system.test.js +627 -0
- package/dist/__tests__/segment-system.test.js.map +1 -0
- package/dist/__tests__/static-handler-types.test.d.ts +8 -0
- package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
- package/dist/__tests__/static-handler-types.test.js +63 -0
- package/dist/__tests__/static-handler-types.test.js.map +1 -0
- package/dist/__tests__/urls.test.d.ts +2 -0
- package/dist/__tests__/urls.test.d.ts.map +1 -0
- package/dist/__tests__/urls.test.js +421 -0
- package/dist/__tests__/urls.test.js.map +1 -0
- package/dist/__tests__/use-mount.test.d.ts +2 -0
- package/dist/__tests__/use-mount.test.d.ts.map +1 -0
- package/dist/__tests__/use-mount.test.js +35 -0
- package/dist/__tests__/use-mount.test.js.map +1 -0
- package/dist/bin/rango.d.ts +2 -0
- package/dist/bin/rango.d.ts.map +1 -0
- package/dist/bin/rango.js +1606 -0
- 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 +4805 -864
- 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/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +16 -18
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +77 -58
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +294 -0
- package/skills/caching/SKILL.md +93 -23
- package/skills/composability/SKILL.md +172 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +18 -16
- package/skills/fonts/SKILL.md +167 -0
- package/skills/hooks/SKILL.md +334 -72
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +131 -8
- package/skills/layout/SKILL.md +100 -3
- package/skills/links/SKILL.md +89 -30
- package/skills/loader/SKILL.md +404 -44
- package/skills/middleware/SKILL.md +171 -34
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +204 -1
- package/skills/prerender/SKILL.md +643 -0
- package/skills/rango/SKILL.md +85 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +257 -14
- package/skills/router-setup/SKILL.md +175 -32
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +328 -89
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +321 -0
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/debug-channel.ts +93 -0
- package/src/browser/event-controller.ts +92 -64
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +282 -557
- package/src/browser/navigation-client.ts +174 -72
- package/src/browser/navigation-store.ts +33 -50
- package/src/browser/navigation-transaction.ts +297 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +303 -310
- package/src/browser/prefetch/cache.ts +206 -0
- package/src/browser/prefetch/fetch.ts +144 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +160 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +193 -73
- package/src/browser/react/NavigationProvider.tsx +162 -13
- package/src/browser/react/context.ts +6 -0
- package/src/browser/react/filter-segment-order.ts +11 -0
- package/src/browser/react/index.ts +12 -12
- package/src/browser/react/location-state-shared.ts +95 -53
- package/src/browser/react/location-state.ts +60 -15
- package/src/browser/react/mount-context.ts +24 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +32 -79
- package/src/browser/react/use-href.tsx +2 -2
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +22 -63
- package/src/browser/react/use-params.ts +65 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-router.ts +63 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +80 -97
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +188 -55
- package/src/browser/scroll-restoration.ts +117 -44
- package/src/browser/segment-reconciler.ts +221 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +516 -599
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +125 -47
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +235 -24
- package/src/build/generate-route-types.ts +36 -0
- package/src/build/index.ts +13 -0
- package/src/build/route-trie.ts +265 -0
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +411 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +128 -0
- package/src/build/route-types/router-processing.ts +479 -0
- package/src/build/route-types/scan-filter.ts +78 -0
- package/src/build/runtime-discovery.ts +231 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +342 -0
- package/src/cache/cache-scope.ts +167 -309
- package/src/cache/cf/cf-cache-store.ts +571 -17
- package/src/cache/cf/index.ts +13 -3
- package/src/cache/document-cache.ts +116 -77
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +1 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +106 -126
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +156 -0
- package/src/debug.ts +19 -9
- package/src/deps/browser.ts +1 -0
- package/src/errors.ts +108 -2
- package/src/handle.ts +15 -29
- package/src/handles/MetaTags.tsx +73 -20
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +30 -13
- package/src/host/cookie-handler.ts +165 -0
- package/src/host/errors.ts +97 -0
- package/src/host/index.ts +53 -0
- package/src/host/pattern-matcher.ts +214 -0
- package/src/host/router.ts +352 -0
- package/src/host/testing.ts +79 -0
- package/src/host/types.ts +146 -0
- package/src/host/utils.ts +25 -0
- package/src/href-client.ts +119 -29
- package/src/index.rsc.ts +153 -19
- package/src/index.ts +211 -30
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +26 -147
- package/src/loader.ts +27 -10
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +37 -0
- package/src/prerender/store.ts +185 -0
- package/src/prerender.ts +463 -0
- package/src/reverse.ts +330 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +959 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +431 -0
- package/src/route-definition/index.ts +52 -0
- package/src/route-definition/redirect.ts +93 -0
- package/src/route-definition.ts +1 -1428
- package/src/route-map-builder.ts +217 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +59 -8
- package/src/router/content-negotiation.ts +116 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +9 -9
- package/src/router/find-match.ts +160 -0
- package/src/router/handler-context.ts +400 -84
- package/src/router/intercept-resolution.ts +397 -0
- package/src/router/lazy-includes.ts +237 -0
- package/src/router/loader-resolution.ts +222 -123
- package/src/router/logging.ts +251 -0
- package/src/router/manifest.ts +154 -35
- package/src/router/match-api.ts +620 -0
- package/src/router/match-context.ts +5 -3
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +108 -93
- package/src/router/match-middleware/cache-lookup.ts +440 -10
- package/src/router/match-middleware/cache-store.ts +98 -26
- package/src/router/match-middleware/intercept-resolution.ts +57 -17
- package/src/router/match-middleware/segment-resolution.ts +27 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +55 -33
- package/src/router/metrics.ts +240 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +226 -0
- package/src/router/middleware.ts +327 -369
- package/src/router/pattern-matching.ts +211 -43
- package/src/router/prerender-match.ts +402 -0
- package/src/router/preview-match.ts +170 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/router-context.ts +41 -21
- package/src/router/router-interfaces.ts +452 -0
- package/src/router/router-options.ts +592 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +683 -0
- package/src/router/segment-resolution/helpers.ts +268 -0
- package/src/router/segment-resolution/loader-cache.ts +199 -0
- package/src/router/segment-resolution/revalidation.ts +1301 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -0
- package/src/router/segment-wrappers.ts +291 -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 +239 -0
- package/src/router/types.ts +78 -3
- package/src/router.ts +666 -4182
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +786 -755
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +214 -0
- package/src/rsc/manifest-init.ts +86 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +382 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +240 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +350 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +44 -11
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +172 -21
- package/src/server/context.ts +278 -58
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +94 -15
- package/src/server/loader-registry.ts +15 -56
- package/src/server/request-context.ts +481 -74
- package/src/server.ts +35 -128
- package/src/ssr/index.tsx +101 -31
- package/src/static-handler.ts +114 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +5 -2
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +4 -30
- package/src/theme/theme-script.ts +21 -18
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +100 -0
- package/src/types/handler-context.ts +785 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +183 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +109 -0
- package/src/types/segments.ts +150 -0
- package/src/types.ts +1 -1623
- package/src/urls/include-helper.ts +197 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +339 -0
- package/src/urls/path-helper.ts +329 -0
- package/src/urls/pattern-types.ts +95 -0
- package/src/urls/response-types.ts +106 -0
- package/src/urls/type-extraction.ts +372 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -802
- package/src/use-loader.tsx +85 -77
- package/src/vite/discovery/bundle-postprocess.ts +184 -0
- package/src/vite/discovery/discover-routers.ts +344 -0
- package/src/vite/discovery/prerender-collection.ts +385 -0
- package/src/vite/discovery/route-types-writer.ts +258 -0
- package/src/vite/discovery/self-gen-tracking.ts +47 -0
- package/src/vite/discovery/state.ts +108 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +11 -782
- package/src/vite/plugin-types.ts +48 -0
- package/src/vite/plugins/cjs-to-esm.ts +93 -0
- package/src/vite/plugins/client-ref-dedup.ts +115 -0
- package/src/vite/plugins/client-ref-hashing.ts +105 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -53
- package/src/vite/plugins/expose-id-utils.ts +287 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +569 -0
- package/src/vite/plugins/performance-tracks.ts +220 -0
- package/src/vite/plugins/refresh-cmd.ts +65 -0
- package/src/vite/plugins/use-cache-transform.ts +323 -0
- package/src/vite/plugins/version-injector.ts +83 -0
- package/src/vite/plugins/version-plugin.ts +266 -0
- package/src/vite/plugins/virtual-entries.ts +123 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +449 -0
- package/src/vite/router-discovery.ts +777 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +137 -0
- package/src/vite/utils/manifest-utils.ts +70 -0
- package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
- package/src/vite/utils/prerender-utils.ts +189 -0
- package/src/vite/utils/shared-utils.ts +169 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/href.ts +0 -255
- package/src/server/route-manifest-cache.ts +0 -173
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -426
- package/src/vite/expose-location-state-id.ts +0 -177
- package/src/warmup/connection-warmup.tsx +0 -94
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
package/src/rsc/handler.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="@vitejs/plugin-rsc/types" />
|
|
2
|
-
/// <reference path="../vite/version.d.ts" />
|
|
2
|
+
/// <reference path="../vite/plugins/version.d.ts" />
|
|
3
3
|
/**
|
|
4
4
|
* RSC Request Handler
|
|
5
5
|
*
|
|
@@ -8,36 +8,85 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createElement } from "react";
|
|
11
|
-
import { renderSegments } from "../segment-system.js";
|
|
12
11
|
import { RouteNotFoundError } from "../errors.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
matchMiddleware,
|
|
16
|
-
executeMiddleware,
|
|
17
|
-
executeLoaderMiddleware,
|
|
18
|
-
} from "../router/middleware.js";
|
|
12
|
+
import { matchMiddleware, executeMiddleware } from "../router/middleware.js";
|
|
19
13
|
import {
|
|
20
14
|
runWithRequestContext,
|
|
21
15
|
setRequestContextParams,
|
|
22
16
|
requireRequestContext,
|
|
17
|
+
getRequestContext,
|
|
23
18
|
createRequestContext,
|
|
24
|
-
type ExecutionContext,
|
|
25
19
|
} from "../server/request-context.js";
|
|
26
20
|
import * as rscDeps from "@vitejs/plugin-rsc/rsc";
|
|
21
|
+
import {
|
|
22
|
+
DEBUG_ID_HEADER,
|
|
23
|
+
createServerDebugChannel,
|
|
24
|
+
} from "../vite/plugins/performance-tracks.js";
|
|
27
25
|
|
|
28
26
|
import type {
|
|
29
27
|
RscPayload,
|
|
30
|
-
ReactFormState,
|
|
31
28
|
CreateRSCHandlerOptions,
|
|
29
|
+
LoadSSRModule,
|
|
30
|
+
SSRModule,
|
|
32
31
|
} from "./types.js";
|
|
33
|
-
import {
|
|
34
|
-
|
|
32
|
+
import {
|
|
33
|
+
createResponseWithMergedHeaders,
|
|
34
|
+
finalizeResponse,
|
|
35
|
+
interceptRedirectForPartial,
|
|
36
|
+
buildRouteMiddlewareEntries,
|
|
37
|
+
} from "./helpers.js";
|
|
38
|
+
import {
|
|
39
|
+
handleResponseRoute,
|
|
40
|
+
type ResponseRouteMatch,
|
|
41
|
+
} from "./response-route-handler.js";
|
|
42
|
+
import { generateNonce, nonce as nonceToken } from "./nonce.js";
|
|
35
43
|
import { VERSION } from "@rangojs/router:version";
|
|
36
44
|
import type { ErrorPhase } from "../types.js";
|
|
45
|
+
import type { RouterRequestInput } from "../router/router-interfaces.js";
|
|
37
46
|
import { invokeOnError } from "../router/error-handling.js";
|
|
38
|
-
import {
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
import {
|
|
48
|
+
createReverseFunction,
|
|
49
|
+
stripInternalParams,
|
|
50
|
+
} from "../router/handler-context.js";
|
|
51
|
+
import { getRouterContext } from "../router/router-context.js";
|
|
52
|
+
import { resolveSink, safeEmit } from "../router/telemetry.js";
|
|
53
|
+
import { contextSet } from "../context-var.js";
|
|
54
|
+
import {
|
|
55
|
+
hasCachedManifest,
|
|
56
|
+
getRouteTrie,
|
|
57
|
+
getPrecomputedEntries,
|
|
58
|
+
waitForManifestReady,
|
|
59
|
+
getRouterManifest,
|
|
60
|
+
getRouterTrie,
|
|
61
|
+
} from "../route-map-builder.js";
|
|
62
|
+
import type { HandlerContext } from "./handler-context.js";
|
|
63
|
+
import { buildRouterTrieFromUrlpatterns } from "./manifest-init.js";
|
|
64
|
+
import { handleProgressiveEnhancement } from "./progressive-enhancement.js";
|
|
65
|
+
import {
|
|
66
|
+
executeServerAction,
|
|
67
|
+
revalidateAfterAction,
|
|
68
|
+
type ActionContinuation,
|
|
69
|
+
} from "./server-action.js";
|
|
70
|
+
import { handleLoaderFetch } from "./loader-fetch.js";
|
|
71
|
+
import { checkRequestOrigin, type OriginCheckPhase } from "./origin-guard.js";
|
|
72
|
+
import { handleRscRendering } from "./rsc-rendering.js";
|
|
73
|
+
import {
|
|
74
|
+
withTimeout,
|
|
75
|
+
RouterTimeoutError,
|
|
76
|
+
createDefaultTimeoutResponse,
|
|
77
|
+
type TimeoutPhase,
|
|
78
|
+
} from "../router/timeout.js";
|
|
79
|
+
import {
|
|
80
|
+
createMetricsStore,
|
|
81
|
+
appendMetric,
|
|
82
|
+
buildMetricsTiming,
|
|
83
|
+
} from "../router/metrics.js";
|
|
84
|
+
import {
|
|
85
|
+
startSSRSetup,
|
|
86
|
+
getSSRSetup,
|
|
87
|
+
mayNeedSSR,
|
|
88
|
+
SSR_SETUP_VAR,
|
|
89
|
+
} from "./ssr-setup.js";
|
|
41
90
|
|
|
42
91
|
/**
|
|
43
92
|
* Create an RSC request handler.
|
|
@@ -89,31 +138,182 @@ export function createRSCHandler<
|
|
|
89
138
|
decodeFormState,
|
|
90
139
|
} = deps;
|
|
91
140
|
|
|
92
|
-
// Use provided loadSSRModule or default to vite RSC module loader
|
|
93
|
-
|
|
141
|
+
// Use provided loadSSRModule or default to vite RSC module loader.
|
|
142
|
+
// In production the SSR module is stable across requests, so memoize
|
|
143
|
+
// the dynamic import to avoid repeated module resolution overhead.
|
|
144
|
+
// In dev mode Vite may hot-reload the module, so skip memoization.
|
|
145
|
+
const rawLoadSSRModule: LoadSSRModule =
|
|
94
146
|
options.loadSSRModule ??
|
|
95
147
|
(() => import.meta.viteRsc.loadModule("ssr", "index"));
|
|
148
|
+
let _ssrModulePromise: Promise<SSRModule> | undefined;
|
|
149
|
+
const loadSSRModule: LoadSSRModule =
|
|
150
|
+
process.env.NODE_ENV === "production"
|
|
151
|
+
? () =>
|
|
152
|
+
(_ssrModulePromise ??= rawLoadSSRModule().catch((err) => {
|
|
153
|
+
_ssrModulePromise = undefined;
|
|
154
|
+
throw err;
|
|
155
|
+
}))
|
|
156
|
+
: rawLoadSSRModule;
|
|
96
157
|
|
|
97
158
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
159
|
+
* Per-request error reporter that deduplicates via the ALS request context.
|
|
160
|
+
*
|
|
161
|
+
* Uses the same _reportedErrors WeakSet as the router layer so errors
|
|
162
|
+
* that propagate across layers are only reported once per request.
|
|
100
163
|
*/
|
|
101
164
|
function callOnError(
|
|
102
165
|
error: unknown,
|
|
103
166
|
phase: ErrorPhase,
|
|
104
167
|
context: Parameters<typeof invokeOnError<TEnv>>[3],
|
|
105
168
|
): void {
|
|
169
|
+
if (error != null && typeof error === "object") {
|
|
170
|
+
const reportedErrors = requireRequestContext()._reportedErrors;
|
|
171
|
+
if (reportedErrors.has(error)) return;
|
|
172
|
+
reportedErrors.add(error);
|
|
173
|
+
}
|
|
106
174
|
invokeOnError(router.onError, error, phase, context, "RSC");
|
|
107
175
|
}
|
|
108
176
|
|
|
109
|
-
|
|
177
|
+
function getRequiredRouteMap(): Record<string, string> {
|
|
178
|
+
const routeMap = getRouterManifest(router.id);
|
|
179
|
+
if (!routeMap) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Route manifest for router "${router.id}" is not available.`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return routeMap;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Handle a timeout by reporting the error, emitting telemetry,
|
|
189
|
+
* and returning either the custom onTimeout response or a default 504.
|
|
190
|
+
*/
|
|
191
|
+
async function handleTimeoutResponse(
|
|
110
192
|
request: Request,
|
|
111
|
-
env: TEnv
|
|
112
|
-
|
|
193
|
+
env: TEnv,
|
|
194
|
+
url: URL,
|
|
195
|
+
phase: TimeoutPhase,
|
|
196
|
+
durationMs: number,
|
|
197
|
+
routeKey?: string,
|
|
198
|
+
actionId?: string,
|
|
199
|
+
): Promise<Response> {
|
|
200
|
+
const timeoutError = new RouterTimeoutError(phase, durationMs);
|
|
201
|
+
|
|
202
|
+
callOnError(timeoutError, phase === "action" ? "action" : "handler", {
|
|
203
|
+
request,
|
|
204
|
+
url,
|
|
205
|
+
env,
|
|
206
|
+
routeKey,
|
|
207
|
+
actionId,
|
|
208
|
+
handledByBoundary: false,
|
|
209
|
+
metadata: { timeout: true, phase, durationMs },
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
const routerCtx = getRouterContext();
|
|
214
|
+
if (routerCtx?.telemetry) {
|
|
215
|
+
safeEmit(resolveSink(routerCtx.telemetry), {
|
|
216
|
+
type: "request.timeout" as const,
|
|
217
|
+
timestamp: performance.now(),
|
|
218
|
+
requestId: routerCtx.requestId,
|
|
219
|
+
phase,
|
|
220
|
+
pathname: url.pathname,
|
|
221
|
+
routeKey,
|
|
222
|
+
actionId,
|
|
223
|
+
durationMs,
|
|
224
|
+
customHandler: !!router.onTimeout,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
} catch {
|
|
228
|
+
// Router context may not be available
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (router.onTimeout) {
|
|
232
|
+
try {
|
|
233
|
+
return await router.onTimeout({
|
|
234
|
+
phase,
|
|
235
|
+
request,
|
|
236
|
+
url,
|
|
237
|
+
env,
|
|
238
|
+
routeKey,
|
|
239
|
+
actionId,
|
|
240
|
+
durationMs,
|
|
241
|
+
});
|
|
242
|
+
} catch (e) {
|
|
243
|
+
if (process.env.NODE_ENV !== "production") {
|
|
244
|
+
console.error("[RSC] onTimeout callback error:", e);
|
|
245
|
+
}
|
|
246
|
+
return createDefaultTimeoutResponse(phase);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return createDefaultTimeoutResponse(phase);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Build a 200 Flight response that carries a redirect URL and optional state.
|
|
255
|
+
* Used when a partial/action request results in a redirect -- fetch
|
|
256
|
+
* auto-follows 3xx so we send the redirect as payload metadata instead.
|
|
257
|
+
*/
|
|
258
|
+
function createRedirectFlightResponse(
|
|
259
|
+
redirectUrl: string,
|
|
260
|
+
locationState?: Record<string, unknown>,
|
|
261
|
+
): Response {
|
|
262
|
+
const redirectPayload: RscPayload = {
|
|
263
|
+
metadata: {
|
|
264
|
+
pathname: redirectUrl,
|
|
265
|
+
segments: [],
|
|
266
|
+
redirect: { url: redirectUrl },
|
|
267
|
+
...(locationState && { locationState }),
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
const debugChannel = getRequestContext()?._debugChannel;
|
|
271
|
+
const rscStream = renderToReadableStream<RscPayload>(redirectPayload, {
|
|
272
|
+
...(debugChannel && { debugChannel }),
|
|
273
|
+
});
|
|
274
|
+
return createResponseWithMergedHeaders(rscStream, {
|
|
275
|
+
status: 200,
|
|
276
|
+
headers: { "content-type": "text/x-component;charset=utf-8" },
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Bundle shared dependencies for extracted handler functions.
|
|
281
|
+
// callOnError reads from ALS so it's inherently per-request scoped.
|
|
282
|
+
const handlerCtx: HandlerContext<TEnv> = {
|
|
283
|
+
router,
|
|
284
|
+
version,
|
|
285
|
+
renderToReadableStream,
|
|
286
|
+
decodeReply,
|
|
287
|
+
createTemporaryReferenceSet,
|
|
288
|
+
loadServerAction,
|
|
289
|
+
decodeAction,
|
|
290
|
+
decodeFormState,
|
|
291
|
+
loadSSRModule,
|
|
292
|
+
callOnError,
|
|
293
|
+
getRequiredRouteMap,
|
|
294
|
+
createRedirectFlightResponse,
|
|
295
|
+
resolveStreamMode: async (request, env, url) => {
|
|
296
|
+
const resolver = router.ssr?.resolveStreaming;
|
|
297
|
+
if (!resolver) return "stream";
|
|
298
|
+
return resolver({ request, env, url });
|
|
113
299
|
},
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
return async function handler(
|
|
303
|
+
request: Request,
|
|
304
|
+
input: RouterRequestInput<TEnv> = {},
|
|
114
305
|
): Promise<Response> {
|
|
306
|
+
const handlerStart = performance.now();
|
|
307
|
+
// Create the metrics store at handler start so handler:total has startTime=0
|
|
308
|
+
// and all metrics are relative to the request entry point.
|
|
309
|
+
const earlyMetricsStore = router.debugPerformance
|
|
310
|
+
? createMetricsStore(true, handlerStart)
|
|
311
|
+
: undefined;
|
|
312
|
+
|
|
313
|
+
const { env = {} as TEnv, vars: initialVars, ctx: executionCtx } = input;
|
|
314
|
+
|
|
115
315
|
// Connection warmup: return 204 immediately before any processing
|
|
116
|
-
if (router
|
|
316
|
+
if (router?.warmupEnabled && request.method === "HEAD") {
|
|
117
317
|
const warmupUrl = new URL(request.url);
|
|
118
318
|
if (warmupUrl.searchParams.has("_rsc_warmup")) {
|
|
119
319
|
return new Response(null, { status: 204 });
|
|
@@ -121,25 +321,30 @@ export function createRSCHandler<
|
|
|
121
321
|
}
|
|
122
322
|
|
|
123
323
|
// Resolve nonce if provider is set
|
|
324
|
+
const nonceStart = performance.now();
|
|
124
325
|
let nonce: string | undefined;
|
|
125
326
|
if (nonceProvider) {
|
|
126
327
|
const result = await nonceProvider(request, env);
|
|
127
328
|
nonce = result === true ? generateNonce() : result;
|
|
128
329
|
}
|
|
330
|
+
const nonceDur = performance.now() - nonceStart;
|
|
129
331
|
|
|
130
332
|
const url = new URL(request.url);
|
|
131
333
|
|
|
132
334
|
// Match global middleware
|
|
335
|
+
const mwMatchStart = performance.now();
|
|
133
336
|
const matchedMiddleware = matchMiddleware(url.pathname, router.middleware);
|
|
337
|
+
const mwMatchDur = performance.now() - mwMatchStart;
|
|
134
338
|
|
|
135
339
|
// Shared variables between middleware and route handlers
|
|
136
|
-
// Initialize from
|
|
137
|
-
const variables: Record<string, any> =
|
|
138
|
-
|
|
139
|
-
|
|
340
|
+
// Initialize from input.vars if provided (allows pre-seeding from worker entry)
|
|
341
|
+
const variables: Record<string, any> = initialVars
|
|
342
|
+
? { ...initialVars }
|
|
343
|
+
: {};
|
|
140
344
|
|
|
141
|
-
// Store nonce
|
|
345
|
+
// Store nonce via ContextVar token and string key for backward compat
|
|
142
346
|
if (nonce) {
|
|
347
|
+
contextSet(variables, nonceToken, nonce);
|
|
143
348
|
variables.nonce = nonce;
|
|
144
349
|
}
|
|
145
350
|
|
|
@@ -150,43 +355,113 @@ export function createRSCHandler<
|
|
|
150
355
|
const cacheOption = options.cache ?? router.cache;
|
|
151
356
|
if (cacheOption && !url.searchParams.has("__no_cache")) {
|
|
152
357
|
const cacheConfig =
|
|
153
|
-
typeof cacheOption === "function"
|
|
358
|
+
typeof cacheOption === "function"
|
|
359
|
+
? cacheOption(env, executionCtx)
|
|
360
|
+
: cacheOption;
|
|
154
361
|
|
|
155
362
|
if (cacheConfig.enabled !== false) {
|
|
156
363
|
cacheStore = cacheConfig.store;
|
|
157
364
|
}
|
|
158
365
|
}
|
|
159
366
|
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
367
|
+
// Route manifest is populated at startup via the virtual module
|
|
368
|
+
// (virtual:rsc-router/routes-manifest). In build/production, it's inlined
|
|
369
|
+
// into the bundle. In dev mode (Node), the discovery plugin populates it
|
|
370
|
+
// via setManifestReadyPromise(). In dev mode (Cloudflare), Miniflare runs
|
|
371
|
+
// in a separate isolate where module-level state doesn't carry over, so
|
|
372
|
+
// we generate inline from the router's urlpatterns.
|
|
373
|
+
//
|
|
374
|
+
// In multi-router setups (e.g. createHostRouter), each router must have
|
|
375
|
+
// its own per-router manifest. We check per-router data first: even if
|
|
376
|
+
// the global manifest was set by a different router, this router still
|
|
377
|
+
// needs its own trie and manifest for correct matching.
|
|
378
|
+
const manifestCacheStart = performance.now();
|
|
379
|
+
const hasRouterData = getRouterManifest(router.id) !== undefined;
|
|
380
|
+
if (!hasRouterData) {
|
|
381
|
+
if (!hasCachedManifest()) {
|
|
382
|
+
const readyPromise = waitForManifestReady();
|
|
383
|
+
if (readyPromise) {
|
|
384
|
+
await readyPromise;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (!getRouterManifest(router.id) && router.urlpatterns) {
|
|
388
|
+
// Cloudflare dev: generate manifest inline for this router.
|
|
389
|
+
// Each router generates its own manifest independently so
|
|
390
|
+
// multi-router setups (host routing) work correctly.
|
|
391
|
+
await buildRouterTrieFromUrlpatterns(router);
|
|
392
|
+
}
|
|
393
|
+
if (!getRouterManifest(router.id) && !hasCachedManifest()) {
|
|
394
|
+
throw new Error(
|
|
395
|
+
'Route manifest not available. Ensure "virtual:rsc-router/routes-manifest" is imported in your entry file.',
|
|
396
|
+
);
|
|
397
|
+
}
|
|
173
398
|
}
|
|
174
399
|
|
|
175
|
-
//
|
|
176
|
-
// This
|
|
400
|
+
// Rebuild the trie when the manifest exists but the per-router trie is
|
|
401
|
+
// missing. This happens in dev mode after HMR: the virtual module sets
|
|
402
|
+
// the manifest (from fresh gen files) but the trie is intentionally not
|
|
403
|
+
// injected to avoid stale discovery-time data. Without the trie, route
|
|
404
|
+
// matching falls back to regex iteration which does not handle wildcard
|
|
405
|
+
// priority correctly (catch-all patterns match before specific routes).
|
|
406
|
+
if (!getRouterTrie(router.id) && router.urlpatterns) {
|
|
407
|
+
await buildRouterTrieFromUrlpatterns(router);
|
|
408
|
+
}
|
|
409
|
+
const manifestCacheDur = performance.now() - manifestCacheStart;
|
|
177
410
|
|
|
178
411
|
// Create unified request context with all methods
|
|
179
412
|
// Includes: stub response, handle store, loader memoization, use(), cookies, headers, cache store
|
|
180
413
|
// params starts empty, populated after route matching via setRequestContextParams
|
|
414
|
+
const ctxCreateStart = performance.now();
|
|
181
415
|
const requestContext = createRequestContext({
|
|
182
416
|
env,
|
|
183
417
|
request,
|
|
184
418
|
url,
|
|
185
419
|
variables,
|
|
186
420
|
cacheStore,
|
|
187
|
-
|
|
421
|
+
cacheProfiles: router.cacheProfiles,
|
|
422
|
+
executionContext: executionCtx,
|
|
188
423
|
themeConfig: router.themeConfig,
|
|
189
424
|
});
|
|
425
|
+
if (earlyMetricsStore) {
|
|
426
|
+
requestContext._debugPerformance = true;
|
|
427
|
+
requestContext._metricsStore = earlyMetricsStore;
|
|
428
|
+
}
|
|
429
|
+
// Dev-only: wire debug channel for React Performance Tracks
|
|
430
|
+
if (process.env.NODE_ENV !== "production") {
|
|
431
|
+
const debugId = request.headers.get(DEBUG_ID_HEADER);
|
|
432
|
+
if (debugId) {
|
|
433
|
+
const channel = createServerDebugChannel(debugId);
|
|
434
|
+
if (channel) {
|
|
435
|
+
requestContext._debugChannel = channel;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// Wire background error reporting so "use cache" and other subsystems
|
|
440
|
+
// can surface non-fatal errors through the router's onError callback.
|
|
441
|
+
requestContext._reportBackgroundError = (
|
|
442
|
+
error: unknown,
|
|
443
|
+
category: string,
|
|
444
|
+
) => {
|
|
445
|
+
callOnError(error, "cache", {
|
|
446
|
+
request,
|
|
447
|
+
url,
|
|
448
|
+
metadata: { category },
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
const ctxCreateDur = performance.now() - ctxCreateStart;
|
|
453
|
+
|
|
454
|
+
// Accumulate handler-level timing for Server-Timing header
|
|
455
|
+
const handlerTiming = [
|
|
456
|
+
`handler-nonce;dur=${nonceDur.toFixed(2)}`,
|
|
457
|
+
`handler-mw-match;dur=${mwMatchDur.toFixed(2)}`,
|
|
458
|
+
`handler-manifest-cache;dur=${manifestCacheDur.toFixed(2)}`,
|
|
459
|
+
`handler-ctx-create;dur=${ctxCreateDur.toFixed(2)}`,
|
|
460
|
+
];
|
|
461
|
+
|
|
462
|
+
// Store timing data in variables for downstream access
|
|
463
|
+
variables.__handlerTiming = handlerTiming;
|
|
464
|
+
variables.__handlerStart = handlerStart;
|
|
190
465
|
|
|
191
466
|
// Wrap entire request handling in request context
|
|
192
467
|
// Makes context available via getRequestContext() throughout:
|
|
@@ -202,17 +477,71 @@ export function createRSCHandler<
|
|
|
202
477
|
};
|
|
203
478
|
|
|
204
479
|
// Execute middleware chain if any, otherwise call core handler directly
|
|
480
|
+
let response: Response;
|
|
205
481
|
if (matchedMiddleware.length > 0) {
|
|
206
|
-
|
|
482
|
+
const mwResponse = await executeMiddleware(
|
|
207
483
|
matchedMiddleware,
|
|
208
484
|
request,
|
|
209
485
|
env,
|
|
210
486
|
variables,
|
|
211
487
|
coreHandler,
|
|
488
|
+
createReverseFunction(getRequiredRouteMap()),
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
if (
|
|
492
|
+
url.searchParams.has("_rsc_partial") ||
|
|
493
|
+
url.searchParams.has("_rsc_action")
|
|
494
|
+
) {
|
|
495
|
+
const intercepted = interceptRedirectForPartial(
|
|
496
|
+
mwResponse,
|
|
497
|
+
createRedirectFlightResponse,
|
|
498
|
+
);
|
|
499
|
+
response = intercepted ?? finalizeResponse(mwResponse);
|
|
500
|
+
} else {
|
|
501
|
+
response = finalizeResponse(mwResponse);
|
|
502
|
+
}
|
|
503
|
+
} else {
|
|
504
|
+
response = await coreHandler();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Finalize metrics after all middleware (including post-next work)
|
|
508
|
+
// has completed so :post spans are captured in the timeline.
|
|
509
|
+
// Handler timing parts are always emitted (even without debug metrics)
|
|
510
|
+
// so non-debug requests still get bootstrap Server-Timing entries.
|
|
511
|
+
const handlerTimingArr: string[] = variables.__handlerTiming || [];
|
|
512
|
+
// Preserve any existing Server-Timing set by response routes or middleware
|
|
513
|
+
const existingTiming = response.headers.get("Server-Timing");
|
|
514
|
+
const timingParts = existingTiming
|
|
515
|
+
? [existingTiming, ...handlerTimingArr]
|
|
516
|
+
: [...handlerTimingArr];
|
|
517
|
+
|
|
518
|
+
const metricsStore = requestContext._metricsStore;
|
|
519
|
+
if (metricsStore) {
|
|
520
|
+
// When the store was created at handler start (earlyMetricsStore),
|
|
521
|
+
// handler:total covers the full request. When ctx.debugPerformance()
|
|
522
|
+
// created the store mid-request, use its requestStart to avoid a
|
|
523
|
+
// negative startTime offset.
|
|
524
|
+
const totalStart = earlyMetricsStore
|
|
525
|
+
? handlerStart
|
|
526
|
+
: metricsStore.requestStart;
|
|
527
|
+
appendMetric(
|
|
528
|
+
metricsStore,
|
|
529
|
+
"handler:total",
|
|
530
|
+
totalStart,
|
|
531
|
+
performance.now() - totalStart,
|
|
212
532
|
);
|
|
533
|
+
const metricsTiming = buildMetricsTiming(
|
|
534
|
+
request.method,
|
|
535
|
+
url.pathname,
|
|
536
|
+
metricsStore,
|
|
537
|
+
);
|
|
538
|
+
if (metricsTiming) timingParts.push(metricsTiming);
|
|
213
539
|
}
|
|
214
540
|
|
|
215
|
-
|
|
541
|
+
const fullTiming = timingParts.join(", ");
|
|
542
|
+
if (fullTiming) response.headers.set("Server-Timing", fullTiming);
|
|
543
|
+
|
|
544
|
+
return response;
|
|
216
545
|
});
|
|
217
546
|
};
|
|
218
547
|
|
|
@@ -224,57 +553,314 @@ export function createRSCHandler<
|
|
|
224
553
|
variables: Record<string, any>,
|
|
225
554
|
nonce: string | undefined,
|
|
226
555
|
): Promise<Response> {
|
|
227
|
-
|
|
228
|
-
const preview = await router.previewMatch(request, env);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
556
|
+
const previewStart = performance.now();
|
|
557
|
+
const preview = await router.previewMatch(request, { env });
|
|
558
|
+
const previewDur = performance.now() - previewStart;
|
|
559
|
+
const handlerTiming: string[] = variables.__handlerTiming || [];
|
|
560
|
+
handlerTiming.push(`handler-preview-match;dur=${previewDur.toFixed(2)}`);
|
|
561
|
+
// Response route short-circuit: skip entire RSC pipeline
|
|
562
|
+
if (preview?.responseType && preview.handler) {
|
|
563
|
+
const responseOutcome = await withTimeout(
|
|
564
|
+
handleResponseRoute(
|
|
565
|
+
handlerCtx,
|
|
566
|
+
preview as ResponseRouteMatch,
|
|
567
|
+
request,
|
|
568
|
+
env,
|
|
569
|
+
url,
|
|
570
|
+
variables,
|
|
571
|
+
),
|
|
572
|
+
router.timeouts.renderStartMs,
|
|
573
|
+
"render-start",
|
|
574
|
+
);
|
|
575
|
+
if (responseOutcome.timedOut) {
|
|
576
|
+
return handleTimeoutResponse(
|
|
577
|
+
request,
|
|
578
|
+
env,
|
|
579
|
+
url,
|
|
580
|
+
"render-start",
|
|
581
|
+
responseOutcome.durationMs,
|
|
582
|
+
preview?.routeKey,
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
return responseOutcome.result;
|
|
586
|
+
}
|
|
241
587
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
588
|
+
// Kick off SSR module loading + stream mode resolution in parallel with
|
|
589
|
+
// segment resolution. Placed after the response-route short-circuit so
|
|
590
|
+
// response/mime routes never pay for SSR work.
|
|
591
|
+
if (mayNeedSSR(request, url)) {
|
|
592
|
+
variables[SSR_SETUP_VAR] = startSSRSetup(
|
|
593
|
+
handlerCtx,
|
|
594
|
+
request,
|
|
595
|
+
env,
|
|
596
|
+
url,
|
|
597
|
+
router.debugPerformance
|
|
598
|
+
? () => requireRequestContext()._metricsStore
|
|
599
|
+
: undefined,
|
|
245
600
|
);
|
|
246
601
|
}
|
|
247
602
|
|
|
248
|
-
|
|
249
|
-
|
|
603
|
+
const routeReverse = createReverseFunction(getRequiredRouteMap());
|
|
604
|
+
|
|
605
|
+
const isAction =
|
|
606
|
+
request.headers.has("rsc-action") || url.searchParams.has("_rsc_action");
|
|
607
|
+
const isLoaderFetch = url.searchParams.has("_rsc_loader");
|
|
608
|
+
const actionId =
|
|
609
|
+
request.headers.get("rsc-action") || url.searchParams.get("_rsc_action");
|
|
610
|
+
|
|
611
|
+
// Origin guard: reject cross-origin actions, loader fetches, and
|
|
612
|
+
// PE form submissions before any execution. Regular page navigations
|
|
613
|
+
// (GET without _rsc_loader/_rsc_action) are not affected.
|
|
614
|
+
const originPhase: OriginCheckPhase | null = isAction
|
|
615
|
+
? "action"
|
|
616
|
+
: isLoaderFetch
|
|
617
|
+
? "loader"
|
|
618
|
+
: request.method === "POST"
|
|
619
|
+
? "pe-form"
|
|
620
|
+
: null;
|
|
621
|
+
if (originPhase) {
|
|
622
|
+
const originResult = await checkRequestOrigin(
|
|
623
|
+
request,
|
|
624
|
+
url,
|
|
625
|
+
router.originCheck,
|
|
626
|
+
env,
|
|
627
|
+
router.id,
|
|
628
|
+
originPhase,
|
|
629
|
+
);
|
|
630
|
+
if (originResult) {
|
|
631
|
+
const originError = new Error(
|
|
632
|
+
`Origin check rejected: ${request.headers.get("origin") ?? "none"} vs ${request.headers.get("host") ?? "none"}`,
|
|
633
|
+
);
|
|
634
|
+
originError.name = "OriginCheckError";
|
|
635
|
+
|
|
636
|
+
callOnError(originError, "origin", {
|
|
637
|
+
request,
|
|
638
|
+
url,
|
|
639
|
+
env,
|
|
640
|
+
handledByBoundary: false,
|
|
641
|
+
metadata: {
|
|
642
|
+
phase: originPhase,
|
|
643
|
+
origin: request.headers.get("origin"),
|
|
644
|
+
host: request.headers.get("host"),
|
|
645
|
+
},
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
try {
|
|
649
|
+
const routerCtx = getRouterContext();
|
|
650
|
+
if (routerCtx?.telemetry) {
|
|
651
|
+
safeEmit(resolveSink(routerCtx.telemetry), {
|
|
652
|
+
type: "request.origin-rejected" as const,
|
|
653
|
+
timestamp: performance.now(),
|
|
654
|
+
requestId: routerCtx.requestId,
|
|
655
|
+
method: request.method,
|
|
656
|
+
pathname: url.pathname,
|
|
657
|
+
phase: originPhase,
|
|
658
|
+
origin: request.headers.get("origin"),
|
|
659
|
+
host: request.headers.get("host"),
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
} catch {
|
|
663
|
+
// Router context may not be available
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
return originResult;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Get handle store from request context
|
|
671
|
+
const handleStore = requireRequestContext()._handleStore;
|
|
672
|
+
|
|
673
|
+
// Wire up error reporting for late streaming-handle failures
|
|
674
|
+
// (LateHandlePushError: handle pushed after stream completion).
|
|
675
|
+
// Without this, these errors are only caught by React's error boundary
|
|
676
|
+
// and never reach the router's onError callback or telemetry.
|
|
677
|
+
handleStore.onError = (error: Error) => {
|
|
678
|
+
const reqCtx = requireRequestContext();
|
|
679
|
+
callOnError(error, "handler", {
|
|
680
|
+
request,
|
|
681
|
+
url,
|
|
682
|
+
routeKey: reqCtx._routeName,
|
|
683
|
+
params: reqCtx.params as Record<string, string>,
|
|
684
|
+
handledByBoundary: true,
|
|
685
|
+
});
|
|
686
|
+
try {
|
|
687
|
+
const routerCtx = getRouterContext();
|
|
688
|
+
if (routerCtx?.telemetry) {
|
|
689
|
+
safeEmit(resolveSink(routerCtx.telemetry), {
|
|
690
|
+
type: "handler.error" as const,
|
|
691
|
+
timestamp: performance.now(),
|
|
692
|
+
requestId: routerCtx.requestId,
|
|
693
|
+
error,
|
|
694
|
+
handledByBoundary: true,
|
|
695
|
+
pathname: url.pathname,
|
|
696
|
+
routeKey: reqCtx._routeName,
|
|
697
|
+
params: reqCtx.params as Record<string, string>,
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
} catch {
|
|
701
|
+
// Router context may not be available (e.g. prerender path)
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
// Set route params early so all execution paths can access ctx.params.
|
|
706
|
+
if (preview?.params) {
|
|
707
|
+
setRequestContextParams(preview.params, preview.routeKey);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// Progressive enhancement runs before the normal action/render paths.
|
|
711
|
+
// Route middleware wraps the PE re-render so handlers see the same
|
|
712
|
+
// context variables regardless of JS/no-JS transport.
|
|
713
|
+
const progressiveResult = await handleProgressiveEnhancement(
|
|
714
|
+
handlerCtx,
|
|
715
|
+
request,
|
|
716
|
+
env,
|
|
717
|
+
url,
|
|
718
|
+
isAction,
|
|
719
|
+
handleStore,
|
|
720
|
+
nonce,
|
|
721
|
+
{
|
|
722
|
+
routeMiddleware: preview?.routeMiddleware,
|
|
723
|
+
variables,
|
|
724
|
+
routeReverse,
|
|
725
|
+
},
|
|
726
|
+
);
|
|
727
|
+
if (progressiveResult) {
|
|
728
|
+
return progressiveResult;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// --- Action execution: runs BEFORE route middleware ---
|
|
732
|
+
// Route middleware wraps rendering only. For actions, the action runs
|
|
733
|
+
// first in the global middleware context, then route middleware wraps
|
|
734
|
+
// the revalidation pass (identical to a normal render).
|
|
735
|
+
let actionContinuation: ActionContinuation | undefined;
|
|
736
|
+
if (isAction && actionId) {
|
|
737
|
+
try {
|
|
738
|
+
const actionOutcome = await withTimeout(
|
|
739
|
+
executeServerAction(
|
|
740
|
+
handlerCtx,
|
|
741
|
+
request,
|
|
742
|
+
env,
|
|
743
|
+
url,
|
|
744
|
+
actionId,
|
|
745
|
+
handleStore,
|
|
746
|
+
),
|
|
747
|
+
router.timeouts.actionMs,
|
|
748
|
+
"action",
|
|
749
|
+
);
|
|
750
|
+
if (actionOutcome.timedOut) {
|
|
751
|
+
return handleTimeoutResponse(
|
|
752
|
+
request,
|
|
753
|
+
env,
|
|
754
|
+
url,
|
|
755
|
+
"action",
|
|
756
|
+
actionOutcome.durationMs,
|
|
757
|
+
preview?.routeKey,
|
|
758
|
+
actionId,
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
const result = actionOutcome.result;
|
|
762
|
+
// Response means redirect or error boundary — done.
|
|
763
|
+
if (result instanceof Response) return result;
|
|
764
|
+
actionContinuation = result;
|
|
765
|
+
} catch (error) {
|
|
766
|
+
callOnError(error, "action", {
|
|
767
|
+
request,
|
|
768
|
+
url,
|
|
769
|
+
env,
|
|
770
|
+
actionId,
|
|
771
|
+
handledByBoundary: false,
|
|
772
|
+
});
|
|
773
|
+
console.error(`[RSC] Action error:`, error);
|
|
774
|
+
throw error;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// --- Rendering (action revalidation or navigation) ---
|
|
779
|
+
// Route middleware wraps this — same code path for both cases.
|
|
780
|
+
const renderHandler = async () => {
|
|
781
|
+
const response = await coreRequestHandlerInner(
|
|
782
|
+
request,
|
|
783
|
+
env,
|
|
784
|
+
url,
|
|
785
|
+
variables,
|
|
786
|
+
nonce,
|
|
787
|
+
preview?.params,
|
|
788
|
+
preview?.routeKey,
|
|
789
|
+
handleStore,
|
|
790
|
+
actionContinuation,
|
|
791
|
+
);
|
|
792
|
+
if (preview?.negotiated) {
|
|
793
|
+
response.headers.append("Vary", "Accept");
|
|
794
|
+
}
|
|
795
|
+
return response;
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
// Wrap the render path (with or without route middleware) in a
|
|
799
|
+
// renderStartMs timeout so slow renders are caught before output.
|
|
800
|
+
const executeRender = async (): Promise<Response> => {
|
|
801
|
+
if (preview?.routeMiddleware && preview.routeMiddleware.length > 0) {
|
|
802
|
+
const mwResponse = await executeMiddleware(
|
|
803
|
+
buildRouteMiddlewareEntries<TEnv>(preview.routeMiddleware),
|
|
804
|
+
request,
|
|
805
|
+
env,
|
|
806
|
+
variables,
|
|
807
|
+
renderHandler,
|
|
808
|
+
routeReverse,
|
|
809
|
+
);
|
|
810
|
+
|
|
811
|
+
if (
|
|
812
|
+
url.searchParams.has("_rsc_partial") ||
|
|
813
|
+
url.searchParams.has("_rsc_action")
|
|
814
|
+
) {
|
|
815
|
+
const intercepted = interceptRedirectForPartial(
|
|
816
|
+
mwResponse,
|
|
817
|
+
createRedirectFlightResponse,
|
|
818
|
+
);
|
|
819
|
+
if (intercepted) return intercepted;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
return finalizeResponse(mwResponse);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// No route middleware, proceed directly
|
|
826
|
+
return renderHandler();
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
const renderOutcome = await withTimeout(
|
|
830
|
+
executeRender(),
|
|
831
|
+
router.timeouts.renderStartMs,
|
|
832
|
+
"render-start",
|
|
833
|
+
);
|
|
834
|
+
if (renderOutcome.timedOut) {
|
|
835
|
+
return handleTimeoutResponse(
|
|
836
|
+
request,
|
|
837
|
+
env,
|
|
838
|
+
url,
|
|
839
|
+
"render-start",
|
|
840
|
+
renderOutcome.durationMs,
|
|
841
|
+
preview?.routeKey,
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
return renderOutcome.result;
|
|
250
845
|
}
|
|
251
846
|
|
|
252
|
-
// Inner request handler
|
|
847
|
+
// Inner request handler: rendering logic wrapped by route middleware.
|
|
848
|
+
// Handles action revalidation (when actionContinuation is present),
|
|
849
|
+
// loader fetches, and regular RSC rendering.
|
|
253
850
|
async function coreRequestHandlerInner(
|
|
254
851
|
request: Request,
|
|
255
852
|
env: TEnv,
|
|
256
853
|
url: URL,
|
|
257
854
|
variables: Record<string, any>,
|
|
258
855
|
nonce: string | undefined,
|
|
856
|
+
routeParams?: Record<string, string>,
|
|
857
|
+
routeKey?: string,
|
|
858
|
+
handleStore?: ReturnType<typeof requireRequestContext>["_handleStore"],
|
|
859
|
+
actionContinuation?: ActionContinuation,
|
|
259
860
|
): Promise<Response> {
|
|
260
|
-
// Early return for static file requests that don't need RSC handling
|
|
261
|
-
if (url.pathname === "/favicon.ico" || url.pathname === "/robots.txt") {
|
|
262
|
-
return new Response(null, { status: 404 });
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Debug endpoint - only in development
|
|
266
|
-
if (url.pathname === "/__debug_manifest" && process.env.NODE_ENV !== "production") {
|
|
267
|
-
const manifest = await router.debugManifest();
|
|
268
|
-
return new Response(JSON.stringify(manifest, null, 2), {
|
|
269
|
-
headers: { "Content-Type": "application/json" },
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
861
|
const isPartial = url.searchParams.has("_rsc_partial");
|
|
274
862
|
const isAction =
|
|
275
863
|
request.headers.has("rsc-action") || url.searchParams.has("_rsc_action");
|
|
276
|
-
const actionId =
|
|
277
|
-
request.headers.get("rsc-action") || url.searchParams.get("_rsc_action");
|
|
278
864
|
|
|
279
865
|
// Version mismatch detection - client may have stale code after HMR/deployment
|
|
280
866
|
// If versions don't match, tell the client to reload
|
|
@@ -284,20 +870,23 @@ export function createRSCHandler<
|
|
|
284
870
|
`[RSC] Version mismatch: client=${clientVersion}, server=${version}. Forcing reload.`,
|
|
285
871
|
);
|
|
286
872
|
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
873
|
+
// For actions, reload current page (referer) if same origin.
|
|
874
|
+
// For navigation, load the target URL.
|
|
875
|
+
// Validate referer origin to prevent open redirect via crafted header.
|
|
876
|
+
let reloadUrl = stripInternalParams(url).toString();
|
|
877
|
+
if (isAction) {
|
|
878
|
+
const referer = request.headers.get("referer");
|
|
879
|
+
if (referer) {
|
|
880
|
+
try {
|
|
881
|
+
const refererUrl = new URL(referer);
|
|
882
|
+
if (refererUrl.origin === url.origin) {
|
|
883
|
+
reloadUrl = referer;
|
|
884
|
+
}
|
|
885
|
+
} catch {
|
|
886
|
+
// Malformed referer, fall back to cleanUrl
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
301
890
|
|
|
302
891
|
// Return special response that tells client to reload
|
|
303
892
|
return createResponseWithMergedHeaders(null, {
|
|
@@ -308,31 +897,56 @@ export function createRSCHandler<
|
|
|
308
897
|
},
|
|
309
898
|
});
|
|
310
899
|
}
|
|
900
|
+
// Debug manifest endpoint: ?__debug_manifest on any route.
|
|
901
|
+
// Always available in dev, requires allowDebugManifest option in production.
|
|
902
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
903
|
+
if (
|
|
904
|
+
url.searchParams.has("__debug_manifest") &&
|
|
905
|
+
(isDev || router.allowDebugManifest)
|
|
906
|
+
) {
|
|
907
|
+
const trie = getRouterTrie(router.id) ?? getRouteTrie();
|
|
908
|
+
const routeManifest = getRequiredRouteMap();
|
|
909
|
+
const { extractAncestryFromTrie } =
|
|
910
|
+
await import("../build/route-trie.js");
|
|
911
|
+
return new Response(
|
|
912
|
+
JSON.stringify(
|
|
913
|
+
{
|
|
914
|
+
routerId: router.id,
|
|
915
|
+
routeManifest,
|
|
916
|
+
routeAncestry: trie ? extractAncestryFromTrie(trie) : {},
|
|
917
|
+
routeTrie: trie,
|
|
918
|
+
precomputedEntries: getPrecomputedEntries(),
|
|
919
|
+
},
|
|
920
|
+
null,
|
|
921
|
+
2,
|
|
922
|
+
),
|
|
923
|
+
{
|
|
924
|
+
headers: { "Content-Type": "application/json" },
|
|
925
|
+
},
|
|
926
|
+
);
|
|
927
|
+
}
|
|
311
928
|
|
|
312
|
-
|
|
313
|
-
const handleStore = requireRequestContext()._handleStore;
|
|
929
|
+
const store = handleStore ?? requireRequestContext()._handleStore;
|
|
314
930
|
|
|
315
931
|
try {
|
|
316
|
-
//
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
request,
|
|
321
|
-
env,
|
|
322
|
-
url,
|
|
323
|
-
isAction,
|
|
324
|
-
handleStore,
|
|
325
|
-
nonce,
|
|
326
|
-
);
|
|
327
|
-
if (progressiveResult) {
|
|
328
|
-
return progressiveResult;
|
|
932
|
+
// Route params were already set in coreRequestHandler, but set again
|
|
933
|
+
// for callers that enter coreRequestHandlerInner directly.
|
|
934
|
+
if (routeParams) {
|
|
935
|
+
setRequestContextParams(routeParams, routeKey);
|
|
329
936
|
}
|
|
330
937
|
|
|
331
938
|
// ============================================================================
|
|
332
|
-
//
|
|
939
|
+
// ACTION REVALIDATION (action already executed, revalidate segments)
|
|
333
940
|
// ============================================================================
|
|
334
|
-
if (
|
|
335
|
-
return
|
|
941
|
+
if (actionContinuation) {
|
|
942
|
+
return await revalidateAfterAction(
|
|
943
|
+
handlerCtx,
|
|
944
|
+
request,
|
|
945
|
+
env,
|
|
946
|
+
url,
|
|
947
|
+
store,
|
|
948
|
+
actionContinuation,
|
|
949
|
+
);
|
|
336
950
|
}
|
|
337
951
|
|
|
338
952
|
// ============================================================================
|
|
@@ -340,7 +954,14 @@ export function createRSCHandler<
|
|
|
340
954
|
// ============================================================================
|
|
341
955
|
const isLoaderRequest = url.searchParams.has("_rsc_loader");
|
|
342
956
|
if (isLoaderRequest) {
|
|
343
|
-
return handleLoaderFetch(
|
|
957
|
+
return handleLoaderFetch(
|
|
958
|
+
handlerCtx,
|
|
959
|
+
request,
|
|
960
|
+
env,
|
|
961
|
+
url,
|
|
962
|
+
variables,
|
|
963
|
+
routeParams,
|
|
964
|
+
);
|
|
344
965
|
}
|
|
345
966
|
|
|
346
967
|
// ============================================================================
|
|
@@ -348,16 +969,44 @@ export function createRSCHandler<
|
|
|
348
969
|
// ============================================================================
|
|
349
970
|
// Note: Must use "return await" for try/catch to catch async rejections
|
|
350
971
|
return await handleRscRendering(
|
|
972
|
+
handlerCtx,
|
|
351
973
|
request,
|
|
352
974
|
env,
|
|
353
975
|
url,
|
|
354
976
|
isPartial,
|
|
355
|
-
|
|
977
|
+
store,
|
|
356
978
|
nonce,
|
|
357
979
|
);
|
|
358
980
|
} catch (error) {
|
|
359
981
|
// Check if middleware/handler returned Response
|
|
360
982
|
if (error instanceof Response) {
|
|
983
|
+
// During partial (client-side navigation), a 200 Response from a handler
|
|
984
|
+
// means the route serves raw content (JSON, text, etc.), not JSX.
|
|
985
|
+
// Signal the browser to hard-navigate so it renders the raw response.
|
|
986
|
+
// Only for 200 — redirects (3xx) work already because the browser follows
|
|
987
|
+
// them automatically to a URL that serves Flight data.
|
|
988
|
+
if (isPartial && error.status === 200) {
|
|
989
|
+
console.warn(
|
|
990
|
+
`[RSC] Route handler at ${url.pathname} returned a Response during client-side navigation. ` +
|
|
991
|
+
`Falling back to hard navigation. Use data-external on the <Link> to avoid the extra round-trip.`,
|
|
992
|
+
);
|
|
993
|
+
return createResponseWithMergedHeaders(null, {
|
|
994
|
+
status: 200,
|
|
995
|
+
headers: {
|
|
996
|
+
"X-RSC-Reload": stripInternalParams(url).toString(),
|
|
997
|
+
"content-type": "text/x-component;charset=utf-8",
|
|
998
|
+
},
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
if (isPartial) {
|
|
1003
|
+
const intercepted = interceptRedirectForPartial(
|
|
1004
|
+
error,
|
|
1005
|
+
createRedirectFlightResponse,
|
|
1006
|
+
);
|
|
1007
|
+
if (intercepted) return intercepted;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
361
1010
|
return error;
|
|
362
1011
|
}
|
|
363
1012
|
|
|
@@ -391,21 +1040,15 @@ export function createRSCHandler<
|
|
|
391
1040
|
params: {},
|
|
392
1041
|
};
|
|
393
1042
|
|
|
394
|
-
// Render with rootLayout to maintain app shell
|
|
395
|
-
const root = await renderSegments([notFoundSegment], {
|
|
396
|
-
rootLayout: router.rootLayout,
|
|
397
|
-
// No routeName for not-found routes
|
|
398
|
-
});
|
|
399
|
-
|
|
400
1043
|
const payload: RscPayload = {
|
|
401
|
-
root,
|
|
402
1044
|
metadata: {
|
|
403
1045
|
pathname: url.pathname,
|
|
404
1046
|
segments: [notFoundSegment],
|
|
405
1047
|
matched: [],
|
|
406
1048
|
diff: [],
|
|
407
1049
|
isPartial: false,
|
|
408
|
-
|
|
1050
|
+
rootLayout: router.rootLayout,
|
|
1051
|
+
handles: store.stream(),
|
|
409
1052
|
version,
|
|
410
1053
|
themeConfig: router.themeConfig,
|
|
411
1054
|
warmupEnabled: router.warmupEnabled,
|
|
@@ -414,10 +1057,15 @@ export function createRSCHandler<
|
|
|
414
1057
|
},
|
|
415
1058
|
};
|
|
416
1059
|
|
|
417
|
-
const
|
|
1060
|
+
const debugChannel = requireRequestContext()._debugChannel;
|
|
1061
|
+
const rscStream = renderToReadableStream(payload, {
|
|
1062
|
+
...(debugChannel && { debugChannel }),
|
|
1063
|
+
});
|
|
418
1064
|
|
|
419
|
-
// Determine if this is an RSC request or HTML request
|
|
1065
|
+
// Determine if this is an RSC request or HTML request.
|
|
1066
|
+
// Partial requests are always RSC (see main isRscRequest comment).
|
|
420
1067
|
const isRscRequest =
|
|
1068
|
+
isPartial ||
|
|
421
1069
|
(!request.headers.get("accept")?.includes("text/html") &&
|
|
422
1070
|
!url.searchParams.has("__html")) ||
|
|
423
1071
|
url.searchParams.has("__rsc");
|
|
@@ -429,9 +1077,18 @@ export function createRSCHandler<
|
|
|
429
1077
|
});
|
|
430
1078
|
}
|
|
431
1079
|
|
|
432
|
-
// Delegate to SSR for HTML response
|
|
433
|
-
const ssrModule = await
|
|
434
|
-
|
|
1080
|
+
// Delegate to SSR for HTML response (reuse early setup if available)
|
|
1081
|
+
const [ssrModule, streamMode] = await getSSRSetup(
|
|
1082
|
+
handlerCtx,
|
|
1083
|
+
request,
|
|
1084
|
+
env,
|
|
1085
|
+
url,
|
|
1086
|
+
requireRequestContext()._metricsStore,
|
|
1087
|
+
);
|
|
1088
|
+
const htmlStream = await ssrModule.renderHTML(rscStream, {
|
|
1089
|
+
nonce,
|
|
1090
|
+
streamMode,
|
|
1091
|
+
});
|
|
435
1092
|
|
|
436
1093
|
return createResponseWithMergedHeaders(htmlStream, {
|
|
437
1094
|
status: 404,
|
|
@@ -450,630 +1107,4 @@ export function createRSCHandler<
|
|
|
450
1107
|
throw error;
|
|
451
1108
|
}
|
|
452
1109
|
}
|
|
453
|
-
|
|
454
|
-
// ============================================================================
|
|
455
|
-
// PROGRESSIVE ENHANCEMENT HANDLER
|
|
456
|
-
// When JavaScript is disabled, React renders forms with hidden fields
|
|
457
|
-
// ($ACTION_REF_*, $ACTION_KEY) containing the action reference.
|
|
458
|
-
// We detect these and return HTML instead of RSC stream.
|
|
459
|
-
// ============================================================================
|
|
460
|
-
async function handleProgressiveEnhancement(
|
|
461
|
-
request: Request,
|
|
462
|
-
env: TEnv,
|
|
463
|
-
url: URL,
|
|
464
|
-
isAction: boolean,
|
|
465
|
-
handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
|
|
466
|
-
nonce: string | undefined,
|
|
467
|
-
): Promise<Response | null> {
|
|
468
|
-
const contentType = request.headers.get("content-type") || "";
|
|
469
|
-
const isFormSubmission =
|
|
470
|
-
contentType.includes("multipart/form-data") ||
|
|
471
|
-
contentType.includes("application/x-www-form-urlencoded");
|
|
472
|
-
|
|
473
|
-
if (request.method !== "POST" || isAction || !isFormSubmission) {
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// Clone the request to read FormData without consuming it
|
|
478
|
-
const formData = await request.clone().formData();
|
|
479
|
-
|
|
480
|
-
// Look for React's progressive enhancement hidden fields
|
|
481
|
-
let isDirectAction = false;
|
|
482
|
-
let isUseActionState = false;
|
|
483
|
-
let directActionId: string | null = null;
|
|
484
|
-
|
|
485
|
-
formData.forEach((_value, key) => {
|
|
486
|
-
if (key.startsWith("$ACTION_ID_")) {
|
|
487
|
-
isDirectAction = true;
|
|
488
|
-
directActionId = key.slice("$ACTION_ID_".length);
|
|
489
|
-
} else if (key.startsWith("$ACTION_REF_")) {
|
|
490
|
-
isUseActionState = true;
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
if (!isDirectAction && !isUseActionState) {
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Execute action and return HTML
|
|
499
|
-
let actionResult: unknown = undefined;
|
|
500
|
-
let reactFormState: ReactFormState | null = null;
|
|
501
|
-
|
|
502
|
-
if (isUseActionState) {
|
|
503
|
-
try {
|
|
504
|
-
const boundAction = await decodeAction(formData);
|
|
505
|
-
actionResult = await boundAction();
|
|
506
|
-
} catch (error) {
|
|
507
|
-
callOnError(error, "action", {
|
|
508
|
-
request,
|
|
509
|
-
url,
|
|
510
|
-
env,
|
|
511
|
-
handledByBoundary: false,
|
|
512
|
-
});
|
|
513
|
-
console.error("[RSC] Progressive enhancement action error:", error);
|
|
514
|
-
}
|
|
515
|
-
} else if (isDirectAction && directActionId) {
|
|
516
|
-
const temporaryReferences = createTemporaryReferenceSet();
|
|
517
|
-
|
|
518
|
-
let args: unknown[] = [];
|
|
519
|
-
try {
|
|
520
|
-
args = await decodeReply(formData, { temporaryReferences });
|
|
521
|
-
} catch {
|
|
522
|
-
args = [formData];
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
try {
|
|
526
|
-
const loadedAction = await loadServerAction(directActionId);
|
|
527
|
-
actionResult = await loadedAction.apply(null, args);
|
|
528
|
-
} catch (error) {
|
|
529
|
-
callOnError(error, "action", {
|
|
530
|
-
request,
|
|
531
|
-
url,
|
|
532
|
-
env,
|
|
533
|
-
actionId: directActionId,
|
|
534
|
-
handledByBoundary: false,
|
|
535
|
-
});
|
|
536
|
-
console.error("[RSC] Progressive enhancement action error:", error);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// Decode form state for useActionState progressive enhancement
|
|
541
|
-
try {
|
|
542
|
-
reactFormState = await decodeFormState(actionResult, formData);
|
|
543
|
-
} catch (error) {
|
|
544
|
-
callOnError(error, "action", {
|
|
545
|
-
request,
|
|
546
|
-
url,
|
|
547
|
-
env,
|
|
548
|
-
handledByBoundary: false,
|
|
549
|
-
});
|
|
550
|
-
console.error("[RSC] Failed to decode form state:", error);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
// Re-render the page and return HTML
|
|
554
|
-
const renderRequest = new Request(url.toString(), {
|
|
555
|
-
method: "GET",
|
|
556
|
-
headers: new Headers({ accept: "text/html" }),
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
const match = await router.match(renderRequest, env);
|
|
560
|
-
|
|
561
|
-
if (match.redirect) {
|
|
562
|
-
return new Response(null, {
|
|
563
|
-
status: 308,
|
|
564
|
-
headers: { Location: match.redirect },
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const root = renderSegments(match.segments, {
|
|
569
|
-
rootLayout: router.rootLayout,
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
const payload: RscPayload = {
|
|
573
|
-
root,
|
|
574
|
-
metadata: {
|
|
575
|
-
pathname: url.pathname,
|
|
576
|
-
segments: match.segments,
|
|
577
|
-
matched: match.matched,
|
|
578
|
-
diff: match.diff,
|
|
579
|
-
isPartial: false,
|
|
580
|
-
rootLayout: router.rootLayout,
|
|
581
|
-
handles: handleStore.stream(),
|
|
582
|
-
version,
|
|
583
|
-
themeConfig: router.themeConfig,
|
|
584
|
-
warmupEnabled: router.warmupEnabled,
|
|
585
|
-
initialTheme: requireRequestContext().theme,
|
|
586
|
-
},
|
|
587
|
-
formState: actionResult,
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
const rscStream = renderToReadableStream<RscPayload>(payload);
|
|
591
|
-
const ssrModule = await loadSSRModule();
|
|
592
|
-
const htmlStream = await ssrModule.renderHTML(rscStream, {
|
|
593
|
-
formState: reactFormState,
|
|
594
|
-
nonce,
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
return new Response(htmlStream, {
|
|
598
|
-
headers: { "content-type": "text/html;charset=utf-8" },
|
|
599
|
-
});
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// ============================================================================
|
|
603
|
-
// SERVER ACTION HANDLER
|
|
604
|
-
// ============================================================================
|
|
605
|
-
async function handleServerAction(
|
|
606
|
-
request: Request,
|
|
607
|
-
env: TEnv,
|
|
608
|
-
url: URL,
|
|
609
|
-
actionId: string,
|
|
610
|
-
handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
|
|
611
|
-
): Promise<Response> {
|
|
612
|
-
const temporaryReferences = createTemporaryReferenceSet();
|
|
613
|
-
|
|
614
|
-
// Decode action arguments from request body
|
|
615
|
-
const contentType = request.headers.get("content-type") || "";
|
|
616
|
-
let args: unknown[] = [];
|
|
617
|
-
let actionFormData: FormData | undefined;
|
|
618
|
-
|
|
619
|
-
try {
|
|
620
|
-
const body = contentType.includes("multipart/form-data")
|
|
621
|
-
? await request.formData()
|
|
622
|
-
: await request.text();
|
|
623
|
-
|
|
624
|
-
if (body instanceof FormData) {
|
|
625
|
-
actionFormData = body;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
if (hasBodyContent(body)) {
|
|
629
|
-
args = await decodeReply(body, { temporaryReferences });
|
|
630
|
-
}
|
|
631
|
-
} catch (error) {
|
|
632
|
-
callOnError(error, "action", {
|
|
633
|
-
request,
|
|
634
|
-
url,
|
|
635
|
-
env,
|
|
636
|
-
actionId,
|
|
637
|
-
handledByBoundary: false,
|
|
638
|
-
});
|
|
639
|
-
throw new Error(`Failed to decode action arguments: ${error}`, {
|
|
640
|
-
cause: error,
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// Execute the server action
|
|
645
|
-
let returnValue: { ok: boolean; data: unknown };
|
|
646
|
-
let actionStatus = 200;
|
|
647
|
-
let loadedAction: Function | undefined;
|
|
648
|
-
|
|
649
|
-
try {
|
|
650
|
-
loadedAction = await loadServerAction(actionId);
|
|
651
|
-
const data = await loadedAction!.apply(null, args);
|
|
652
|
-
returnValue = { ok: true, data };
|
|
653
|
-
} catch (error) {
|
|
654
|
-
returnValue = { ok: false, data: error };
|
|
655
|
-
actionStatus = 500;
|
|
656
|
-
|
|
657
|
-
// Try to render error boundary
|
|
658
|
-
const errorResult = await router.matchError(request, env, error, "route");
|
|
659
|
-
|
|
660
|
-
// Report the action error (handledByBoundary indicates if error boundary will render)
|
|
661
|
-
callOnError(error, "action", {
|
|
662
|
-
request,
|
|
663
|
-
url,
|
|
664
|
-
env,
|
|
665
|
-
actionId,
|
|
666
|
-
handledByBoundary: !!errorResult,
|
|
667
|
-
});
|
|
668
|
-
|
|
669
|
-
if (errorResult) {
|
|
670
|
-
setRequestContextParams(errorResult.params);
|
|
671
|
-
|
|
672
|
-
const payload: RscPayload = {
|
|
673
|
-
root: null,
|
|
674
|
-
metadata: {
|
|
675
|
-
pathname: url.pathname,
|
|
676
|
-
segments: errorResult.segments,
|
|
677
|
-
isPartial: true,
|
|
678
|
-
matched: errorResult.matched,
|
|
679
|
-
diff: errorResult.diff,
|
|
680
|
-
isError: true,
|
|
681
|
-
handles: handleStore.stream(),
|
|
682
|
-
version,
|
|
683
|
-
},
|
|
684
|
-
returnValue,
|
|
685
|
-
};
|
|
686
|
-
|
|
687
|
-
const rscStream = renderToReadableStream<RscPayload>(payload, {
|
|
688
|
-
temporaryReferences,
|
|
689
|
-
});
|
|
690
|
-
|
|
691
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
692
|
-
status: actionStatus,
|
|
693
|
-
headers: { "content-type": "text/x-component;charset=utf-8" },
|
|
694
|
-
});
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
// Revalidate after action
|
|
699
|
-
const resolvedActionId =
|
|
700
|
-
(loadedAction as { $id?: string; $$id?: string } | undefined)?.$id ??
|
|
701
|
-
(loadedAction as { $$id?: string } | undefined)?.$$id ??
|
|
702
|
-
actionId;
|
|
703
|
-
const actionContext = {
|
|
704
|
-
actionId: resolvedActionId,
|
|
705
|
-
actionUrl: new URL(request.url),
|
|
706
|
-
actionResult: returnValue.data,
|
|
707
|
-
formData: actionFormData,
|
|
708
|
-
};
|
|
709
|
-
|
|
710
|
-
const matchResult = await router.matchPartial(request, env, actionContext);
|
|
711
|
-
|
|
712
|
-
if (!matchResult) {
|
|
713
|
-
// Fall back to full render
|
|
714
|
-
const fullMatch = await router.match(request, env);
|
|
715
|
-
setRequestContextParams(fullMatch.params);
|
|
716
|
-
|
|
717
|
-
if (fullMatch.redirect) {
|
|
718
|
-
return createResponseWithMergedHeaders(null, {
|
|
719
|
-
status: 308,
|
|
720
|
-
headers: { Location: fullMatch.redirect },
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
const renderStart = performance.now();
|
|
725
|
-
const root = renderSegments(fullMatch.segments, {
|
|
726
|
-
rootLayout: router.rootLayout,
|
|
727
|
-
isAction: true,
|
|
728
|
-
});
|
|
729
|
-
const renderDuration = performance.now() - renderStart;
|
|
730
|
-
const serverTiming = fullMatch.serverTiming
|
|
731
|
-
? `${fullMatch.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
|
|
732
|
-
: `rendering;dur=${renderDuration.toFixed(2)}`;
|
|
733
|
-
|
|
734
|
-
const payload: RscPayload = {
|
|
735
|
-
root,
|
|
736
|
-
metadata: {
|
|
737
|
-
pathname: url.pathname,
|
|
738
|
-
segments: fullMatch.segments,
|
|
739
|
-
matched: fullMatch.matched,
|
|
740
|
-
diff: fullMatch.diff,
|
|
741
|
-
handles: handleStore.stream(),
|
|
742
|
-
version,
|
|
743
|
-
},
|
|
744
|
-
returnValue,
|
|
745
|
-
};
|
|
746
|
-
|
|
747
|
-
const rscStream = renderToReadableStream<RscPayload>(payload, {
|
|
748
|
-
temporaryReferences,
|
|
749
|
-
});
|
|
750
|
-
|
|
751
|
-
const headers: Record<string, string> = {
|
|
752
|
-
"content-type": "text/x-component;charset=utf-8",
|
|
753
|
-
};
|
|
754
|
-
if (serverTiming) {
|
|
755
|
-
headers["Server-Timing"] = serverTiming;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
759
|
-
status: actionStatus,
|
|
760
|
-
headers,
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
// Return updated segments
|
|
765
|
-
setRequestContextParams(matchResult.params);
|
|
766
|
-
|
|
767
|
-
const renderStart = performance.now();
|
|
768
|
-
|
|
769
|
-
const renderDuration = performance.now() - renderStart;
|
|
770
|
-
const serverTiming = matchResult.serverTiming
|
|
771
|
-
? `${matchResult.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
|
|
772
|
-
: `rendering;dur=${renderDuration.toFixed(2)}`;
|
|
773
|
-
|
|
774
|
-
const payload: RscPayload = {
|
|
775
|
-
root: null,
|
|
776
|
-
metadata: {
|
|
777
|
-
pathname: url.pathname,
|
|
778
|
-
segments: matchResult.segments,
|
|
779
|
-
isPartial: true,
|
|
780
|
-
matched: matchResult.matched,
|
|
781
|
-
diff: matchResult.diff,
|
|
782
|
-
slots: matchResult.slots,
|
|
783
|
-
handles: handleStore.stream(),
|
|
784
|
-
version,
|
|
785
|
-
},
|
|
786
|
-
returnValue,
|
|
787
|
-
};
|
|
788
|
-
|
|
789
|
-
const rscStream = renderToReadableStream<RscPayload>(payload, {
|
|
790
|
-
temporaryReferences,
|
|
791
|
-
});
|
|
792
|
-
|
|
793
|
-
const actionHeaders: Record<string, string> = {
|
|
794
|
-
"content-type": "text/x-component;charset=utf-8",
|
|
795
|
-
};
|
|
796
|
-
if (serverTiming) {
|
|
797
|
-
actionHeaders["Server-Timing"] = serverTiming;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
801
|
-
status: actionStatus,
|
|
802
|
-
headers: actionHeaders,
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
// ============================================================================
|
|
807
|
-
// LOADER FETCH HANDLER
|
|
808
|
-
// Supports GET (params in query string) and POST/PUT/PATCH/DELETE (JSON body)
|
|
809
|
-
// ============================================================================
|
|
810
|
-
async function handleLoaderFetch(
|
|
811
|
-
request: Request,
|
|
812
|
-
env: TEnv,
|
|
813
|
-
url: URL,
|
|
814
|
-
variables: Record<string, any>,
|
|
815
|
-
): Promise<Response> {
|
|
816
|
-
const loaderId = url.searchParams.get("_rsc_loader");
|
|
817
|
-
|
|
818
|
-
if (!loaderId) {
|
|
819
|
-
return createResponseWithMergedHeaders("Missing _rsc_loader parameter", {
|
|
820
|
-
status: 400,
|
|
821
|
-
});
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
// Look up loader lazily
|
|
825
|
-
const registeredLoader = await getLoaderLazy(loaderId);
|
|
826
|
-
if (!registeredLoader) {
|
|
827
|
-
return createResponseWithMergedHeaders(
|
|
828
|
-
`Loader "${loaderId}" not found in registry`,
|
|
829
|
-
{ status: 404 },
|
|
830
|
-
);
|
|
831
|
-
}
|
|
832
|
-
|
|
833
|
-
// Parse params and body based on request method
|
|
834
|
-
let loaderParams: Record<string, string> = {};
|
|
835
|
-
let loaderBody: unknown = undefined;
|
|
836
|
-
const isBodyMethod = request.method !== "GET" && request.method !== "HEAD";
|
|
837
|
-
|
|
838
|
-
if (isBodyMethod) {
|
|
839
|
-
try {
|
|
840
|
-
const contentType = request.headers.get("content-type") || "";
|
|
841
|
-
if (contentType.includes("application/json")) {
|
|
842
|
-
const jsonBody = (await request.json()) as {
|
|
843
|
-
params?: Record<string, string>;
|
|
844
|
-
body?: unknown;
|
|
845
|
-
};
|
|
846
|
-
loaderParams = jsonBody.params ?? {};
|
|
847
|
-
loaderBody = jsonBody.body;
|
|
848
|
-
}
|
|
849
|
-
} catch {
|
|
850
|
-
return createResponseWithMergedHeaders("Invalid JSON body", {
|
|
851
|
-
status: 400,
|
|
852
|
-
});
|
|
853
|
-
}
|
|
854
|
-
} else {
|
|
855
|
-
const loaderParamsJson = url.searchParams.get("_rsc_loader_params");
|
|
856
|
-
if (loaderParamsJson) {
|
|
857
|
-
try {
|
|
858
|
-
loaderParams = JSON.parse(loaderParamsJson);
|
|
859
|
-
} catch {
|
|
860
|
-
return createResponseWithMergedHeaders(
|
|
861
|
-
"Invalid _rsc_loader_params JSON",
|
|
862
|
-
{ status: 400 },
|
|
863
|
-
);
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
// Execute the loader with middleware
|
|
869
|
-
try {
|
|
870
|
-
const { fn, middleware } = registeredLoader;
|
|
871
|
-
|
|
872
|
-
return await executeLoaderMiddleware(
|
|
873
|
-
middleware,
|
|
874
|
-
request,
|
|
875
|
-
env,
|
|
876
|
-
loaderParams,
|
|
877
|
-
variables,
|
|
878
|
-
async () => {
|
|
879
|
-
const ctx = requireRequestContext();
|
|
880
|
-
const loaderCtx: any = {
|
|
881
|
-
...ctx,
|
|
882
|
-
params: loaderParams,
|
|
883
|
-
body: loaderBody,
|
|
884
|
-
};
|
|
885
|
-
|
|
886
|
-
const result = await fn(loaderCtx);
|
|
887
|
-
|
|
888
|
-
interface LoaderPayload {
|
|
889
|
-
loaderResult: unknown;
|
|
890
|
-
}
|
|
891
|
-
const loaderPayload: LoaderPayload = { loaderResult: result };
|
|
892
|
-
const rscStream =
|
|
893
|
-
renderToReadableStream<LoaderPayload>(loaderPayload);
|
|
894
|
-
|
|
895
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
896
|
-
headers: { "content-type": "text/x-component;charset=utf-8" },
|
|
897
|
-
});
|
|
898
|
-
},
|
|
899
|
-
);
|
|
900
|
-
} catch (error) {
|
|
901
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
902
|
-
const isDev = process.env.NODE_ENV !== "production";
|
|
903
|
-
|
|
904
|
-
console.error("[RSC] Loader error:", error);
|
|
905
|
-
|
|
906
|
-
callOnError(error, "loader", {
|
|
907
|
-
request,
|
|
908
|
-
url,
|
|
909
|
-
env,
|
|
910
|
-
loaderName: loaderId,
|
|
911
|
-
handledByBoundary: false,
|
|
912
|
-
});
|
|
913
|
-
|
|
914
|
-
const errorPayload = {
|
|
915
|
-
loaderResult: null,
|
|
916
|
-
loaderError: {
|
|
917
|
-
message: isDev ? err.message : "An error occurred",
|
|
918
|
-
name: err.name,
|
|
919
|
-
},
|
|
920
|
-
};
|
|
921
|
-
const rscStream = renderToReadableStream(errorPayload);
|
|
922
|
-
|
|
923
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
924
|
-
status: 500,
|
|
925
|
-
headers: { "content-type": "text/x-component;charset=utf-8" },
|
|
926
|
-
});
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
// ============================================================================
|
|
931
|
-
// RSC RENDERING HANDLER (Navigation)
|
|
932
|
-
// ============================================================================
|
|
933
|
-
async function handleRscRendering(
|
|
934
|
-
request: Request,
|
|
935
|
-
env: TEnv,
|
|
936
|
-
url: URL,
|
|
937
|
-
isPartial: boolean,
|
|
938
|
-
handleStore: ReturnType<typeof requireRequestContext>["_handleStore"],
|
|
939
|
-
nonce: string | undefined,
|
|
940
|
-
): Promise<Response> {
|
|
941
|
-
let payload: RscPayload;
|
|
942
|
-
let serverTiming: string | undefined;
|
|
943
|
-
|
|
944
|
-
if (isPartial) {
|
|
945
|
-
// Partial render (navigation)
|
|
946
|
-
const result = await router.matchPartial(request, env);
|
|
947
|
-
|
|
948
|
-
if (!result) {
|
|
949
|
-
// Fall back to full render
|
|
950
|
-
const match = await router.match(request, env);
|
|
951
|
-
setRequestContextParams(match.params);
|
|
952
|
-
|
|
953
|
-
if (match.redirect) {
|
|
954
|
-
return createResponseWithMergedHeaders(null, {
|
|
955
|
-
status: 308,
|
|
956
|
-
headers: { Location: match.redirect },
|
|
957
|
-
});
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
const renderStart = performance.now();
|
|
961
|
-
const root = renderSegments(match.segments, {
|
|
962
|
-
rootLayout: router.rootLayout,
|
|
963
|
-
});
|
|
964
|
-
const renderDuration = performance.now() - renderStart;
|
|
965
|
-
serverTiming = match.serverTiming
|
|
966
|
-
? `${match.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
|
|
967
|
-
: `rendering;dur=${renderDuration.toFixed(2)}`;
|
|
968
|
-
|
|
969
|
-
payload = {
|
|
970
|
-
root,
|
|
971
|
-
metadata: {
|
|
972
|
-
pathname: url.pathname,
|
|
973
|
-
segments: match.segments,
|
|
974
|
-
matched: match.matched,
|
|
975
|
-
diff: match.diff,
|
|
976
|
-
isPartial: false,
|
|
977
|
-
handles: handleStore.stream(),
|
|
978
|
-
version,
|
|
979
|
-
themeConfig: router.themeConfig,
|
|
980
|
-
initialTheme: requireRequestContext().theme,
|
|
981
|
-
},
|
|
982
|
-
};
|
|
983
|
-
} else {
|
|
984
|
-
setRequestContextParams(result.params);
|
|
985
|
-
serverTiming = result.serverTiming;
|
|
986
|
-
|
|
987
|
-
payload = {
|
|
988
|
-
root: null,
|
|
989
|
-
metadata: {
|
|
990
|
-
pathname: url.pathname,
|
|
991
|
-
segments: result.segments,
|
|
992
|
-
matched: result.matched,
|
|
993
|
-
diff: result.diff,
|
|
994
|
-
isPartial: true,
|
|
995
|
-
slots: result.slots,
|
|
996
|
-
handles: handleStore.stream(),
|
|
997
|
-
version,
|
|
998
|
-
},
|
|
999
|
-
};
|
|
1000
|
-
}
|
|
1001
|
-
} else {
|
|
1002
|
-
// Full render (initial page load)
|
|
1003
|
-
const match = await router.match(request, env);
|
|
1004
|
-
setRequestContextParams(match.params);
|
|
1005
|
-
|
|
1006
|
-
if (match.redirect) {
|
|
1007
|
-
return createResponseWithMergedHeaders(null, {
|
|
1008
|
-
status: 308,
|
|
1009
|
-
headers: { Location: match.redirect },
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
// Caching is now handled in router.match() via cache provider in request context
|
|
1014
|
-
// match.segments already contains cached or fresh segments as appropriate
|
|
1015
|
-
|
|
1016
|
-
const renderStart = performance.now();
|
|
1017
|
-
const root = renderSegments(match.segments, {
|
|
1018
|
-
rootLayout: router.rootLayout,
|
|
1019
|
-
});
|
|
1020
|
-
const renderDuration = performance.now() - renderStart;
|
|
1021
|
-
serverTiming = match.serverTiming
|
|
1022
|
-
? `${match.serverTiming}, rendering;dur=${renderDuration.toFixed(2)}`
|
|
1023
|
-
: `rendering;dur=${renderDuration.toFixed(2)}`;
|
|
1024
|
-
|
|
1025
|
-
payload = {
|
|
1026
|
-
root,
|
|
1027
|
-
metadata: {
|
|
1028
|
-
pathname: url.pathname,
|
|
1029
|
-
segments: match.segments,
|
|
1030
|
-
matched: match.matched,
|
|
1031
|
-
diff: match.diff,
|
|
1032
|
-
isPartial: false,
|
|
1033
|
-
rootLayout: router.rootLayout,
|
|
1034
|
-
handles: handleStore.stream(),
|
|
1035
|
-
version,
|
|
1036
|
-
themeConfig: router.themeConfig,
|
|
1037
|
-
initialTheme: requireRequestContext().theme,
|
|
1038
|
-
},
|
|
1039
|
-
};
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
// Serialize to RSC stream
|
|
1043
|
-
const rscStream = renderToReadableStream<RscPayload>(payload);
|
|
1044
|
-
|
|
1045
|
-
// Determine if this is an RSC request or HTML request
|
|
1046
|
-
const isRscRequest =
|
|
1047
|
-
(!request.headers.get("accept")?.includes("text/html") &&
|
|
1048
|
-
!url.searchParams.has("__html")) ||
|
|
1049
|
-
url.searchParams.has("__rsc");
|
|
1050
|
-
|
|
1051
|
-
if (isRscRequest) {
|
|
1052
|
-
const rscHeaders: Record<string, string> = {
|
|
1053
|
-
"content-type": "text/x-component;charset=utf-8",
|
|
1054
|
-
vary: "accept",
|
|
1055
|
-
};
|
|
1056
|
-
if (serverTiming) {
|
|
1057
|
-
rscHeaders["Server-Timing"] = serverTiming;
|
|
1058
|
-
}
|
|
1059
|
-
return createResponseWithMergedHeaders(rscStream, {
|
|
1060
|
-
headers: rscHeaders,
|
|
1061
|
-
});
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
// Delegate to SSR for HTML response
|
|
1065
|
-
const ssrModule = await loadSSRModule();
|
|
1066
|
-
const htmlStream = await ssrModule.renderHTML(rscStream, { nonce });
|
|
1067
|
-
|
|
1068
|
-
const htmlHeaders: Record<string, string> = {
|
|
1069
|
-
"content-type": "text/html;charset=utf-8",
|
|
1070
|
-
};
|
|
1071
|
-
if (serverTiming) {
|
|
1072
|
-
htmlHeaders["Server-Timing"] = serverTiming;
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
return createResponseWithMergedHeaders(htmlStream, {
|
|
1076
|
-
headers: htmlHeaders,
|
|
1077
|
-
});
|
|
1078
|
-
}
|
|
1079
1110
|
}
|