@rangojs/router 0.0.0-experimental.15 → 0.0.0-experimental.151
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 +13 -0
- package/README.md +308 -451
- 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 +1844 -237
- 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/{src/browser/react/use-client-cache.ts → dist/browser/react/use-client-cache.js} +9 -26
- 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/{src/handles/index.ts → dist/handles/index.js} +1 -1
- 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/{src/network-error-thrower.tsx → dist/network-error-thrower.d.ts} +4 -8
- 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/testing/vitest.js +82 -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 +7554 -2070
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/package-resolution.d.ts +43 -0
- package/dist/vite/package-resolution.d.ts.map +1 -0
- package/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
- package/dist/vite/package-resolution.js.map +1 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/dist/vite/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +12 -16
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +142 -61
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +489 -0
- package/skills/caching/SKILL.md +413 -26
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +278 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -18
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +96 -63
- package/skills/fonts/SKILL.md +7 -5
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +76 -436
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +215 -16
- package/skills/layout/SKILL.md +147 -7
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +629 -55
- package/skills/middleware/SKILL.md +251 -38
- package/skills/migrate-nextjs/SKILL.md +745 -0
- package/skills/migrate-react-router/SKILL.md +153 -0
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +60 -21
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +296 -4
- package/skills/ppr/SKILL.md +658 -0
- package/skills/prerender/SKILL.md +487 -52
- package/skills/rango/SKILL.md +324 -29
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +264 -122
- package/skills/route/SKILL.md +359 -22
- package/skills/router-setup/SKILL.md +247 -34
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +126 -222
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +10 -9
- package/skills/typesafety/SKILL.md +45 -496
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +383 -0
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +275 -29
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +348 -212
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +39 -0
- package/src/browser/merge-segment-loaders.ts +23 -13
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +249 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +230 -124
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +432 -365
- package/src/browser/prefetch/cache.ts +381 -0
- package/src/browser/prefetch/fetch.ts +462 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +284 -67
- package/src/browser/react/NavigationProvider.tsx +267 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +355 -73
- package/src/browser/scroll-restoration.ts +140 -50
- package/src/browser/segment-reconciler.ts +253 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +235 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +243 -183
- package/src/build/generate-route-types.ts +41 -848
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +218 -80
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +88 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +695 -0
- package/src/cache/cache-scope.ts +324 -335
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2602 -156
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +226 -102
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +132 -0
- package/src/cache/index.ts +24 -35
- package/src/cache/memory-segment-store.ts +446 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +295 -0
- package/src/cache/shell-snapshot.ts +464 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +283 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1201 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +4 -2
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +180 -35
- package/src/index.ts +245 -73
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/build-shell-capture.ts +447 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/shell-manifest-key.ts +20 -0
- package/src/prerender/store.ts +131 -22
- package/src/prerender.ts +460 -26
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +506 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +120 -145
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +305 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +259 -0
- package/src/router/handler-context.ts +385 -125
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +88 -28
- package/src/router/lazy-includes.ts +260 -0
- package/src/router/loader-resolution.ts +449 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +144 -62
- package/src/router/match-api.ts +224 -256
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +499 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +308 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +143 -52
- package/src/router/metrics.ts +235 -29
- package/src/router/middleware-types.ts +110 -0
- package/src/router/middleware.ts +526 -441
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +575 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +291 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +256 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +564 -0
- package/src/router/router-options.ts +784 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +812 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +315 -0
- package/src/router/segment-resolution/loader-mask.ts +60 -0
- package/src/router/segment-resolution/loader-snapshot.ts +259 -0
- package/src/router/segment-resolution/mask-nested.ts +99 -0
- package/src/router/segment-resolution/revalidation.ts +1340 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +259 -0
- package/src/router/telemetry.ts +385 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +795 -2390
- package/src/rsc/capture-queue.ts +67 -0
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +956 -1164
- package/src/rsc/helpers.ts +736 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +23 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +541 -0
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +856 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +525 -0
- package/src/rsc/shell-build-manifest.ts +316 -0
- package/src/rsc/shell-capture-constants.ts +27 -0
- package/src/rsc/shell-capture.ts +1716 -0
- package/src/rsc/shell-serve.ts +226 -0
- package/src/rsc/ssr-setup.ts +176 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-fragments.ts +124 -0
- package/src/segment-loader-promise.ts +167 -0
- package/src/segment-system.tsx +464 -135
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +640 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +337 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +1069 -152
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +661 -140
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/preinit-client-references.ts +106 -0
- package/src/ssr/ssr-root.tsx +261 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +380 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +371 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +219 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +76 -98
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +850 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +44 -0
- package/src/urls/path-helper-types.ts +418 -0
- package/src/urls/path-helper.ts +280 -0
- package/src/urls/pattern-types.ts +189 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1352
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +408 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +483 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/shell-prerender-phase.ts +397 -0
- package/src/vite/discovery/state.ts +205 -0
- package/src/vite/discovery/virtual-module-codegen.ts +293 -0
- package/src/vite/index.ts +31 -2255
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +336 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +271 -0
- package/src/vite/plugins/virtual-entries.ts +267 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +600 -0
- package/src/vite/router-discovery.ts +2120 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +268 -0
- package/src/vite/utils/shared-utils.ts +271 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -11,16 +11,68 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
14
|
+
import { parseCookiesFromHeader } from "./cookie-parse.js";
|
|
15
|
+
import type { CacheErrorCategory } from "../cache/cache-error.js";
|
|
14
16
|
import type { CookieOptions } from "../router/middleware.js";
|
|
17
|
+
import {
|
|
18
|
+
KEEP_CACHE_HEADER,
|
|
19
|
+
getRawCookieValue,
|
|
20
|
+
mintStateValue,
|
|
21
|
+
serializeStateCookie,
|
|
22
|
+
} from "../browser/cookie-name.js";
|
|
15
23
|
import type { LoaderDefinition, LoaderContext } from "../types.js";
|
|
24
|
+
import type { ScopedReverseFunction } from "../reverse.js";
|
|
25
|
+
import type {
|
|
26
|
+
DefaultEnv,
|
|
27
|
+
DefaultReverseRouteMap,
|
|
28
|
+
DefaultRouteName,
|
|
29
|
+
} from "../types/global-namespace.js";
|
|
16
30
|
import type { Handle } from "../handle.js";
|
|
17
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
type ContextVar,
|
|
33
|
+
contextGet,
|
|
34
|
+
contextSet,
|
|
35
|
+
isNonCacheable,
|
|
36
|
+
} from "../context-var.js";
|
|
37
|
+
import {
|
|
38
|
+
createHandleStore,
|
|
39
|
+
buildHandleSnapshot,
|
|
40
|
+
type HandleStore,
|
|
41
|
+
type HandleData,
|
|
42
|
+
} from "./handle-store.js";
|
|
18
43
|
import { isHandle } from "../handle.js";
|
|
19
|
-
import {
|
|
44
|
+
import { withDefer } from "../defer.js";
|
|
45
|
+
import { type MetricsStore } from "./context.js";
|
|
46
|
+
import { observePhase, PHASES } from "../router/instrument.js";
|
|
20
47
|
import { getFetchableLoader } from "./fetchable-loader-store.js";
|
|
21
48
|
import type { SegmentCacheStore } from "../cache/types.js";
|
|
22
49
|
import type { Theme, ResolvedThemeConfig } from "../theme/types.js";
|
|
23
|
-
import {
|
|
50
|
+
import type { ExecutionContext, RequestScope } from "../types/request-scope.js";
|
|
51
|
+
import type { TransitionWhenFn } from "../types/segments.js";
|
|
52
|
+
import type { ResolvedTracing } from "../router/tracing.js";
|
|
53
|
+
import {
|
|
54
|
+
THEME_COOKIE,
|
|
55
|
+
isValidTheme,
|
|
56
|
+
warnInvalidTheme,
|
|
57
|
+
} from "../theme/constants.js";
|
|
58
|
+
import type { LocationStateEntry } from "../browser/react/location-state-shared.js";
|
|
59
|
+
import { NOCACHE_SYMBOL, assertNotInsideCacheExec } from "../cache/taint.js";
|
|
60
|
+
import {
|
|
61
|
+
assertCachedHeaderWriteAllowed,
|
|
62
|
+
isInsideCacheScope,
|
|
63
|
+
} from "./context.js";
|
|
64
|
+
import {
|
|
65
|
+
createReverseFunction,
|
|
66
|
+
stripInternalParams,
|
|
67
|
+
} from "../router/handler-context.js";
|
|
68
|
+
import {
|
|
69
|
+
getGlobalRouteMap,
|
|
70
|
+
isRouteRootScoped,
|
|
71
|
+
getSearchSchema,
|
|
72
|
+
} from "../route-map-builder.js";
|
|
73
|
+
import { parseSearchParams } from "../search-params.js";
|
|
74
|
+
import { invariant } from "../errors.js";
|
|
75
|
+
import { isAutoGeneratedRouteName } from "../route-name.js";
|
|
24
76
|
|
|
25
77
|
/**
|
|
26
78
|
* Unified request context available via getRequestContext()
|
|
@@ -29,46 +81,75 @@ import { THEME_COOKIE } from "../theme/constants.js";
|
|
|
29
81
|
* Use this when you need access to request data outside of route handlers.
|
|
30
82
|
*/
|
|
31
83
|
export interface RequestContext<
|
|
32
|
-
TEnv =
|
|
84
|
+
TEnv = DefaultEnv,
|
|
33
85
|
TParams = Record<string, string>,
|
|
34
|
-
> {
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
/** Original HTTP request */
|
|
38
|
-
request: Request;
|
|
39
|
-
/** Parsed URL (system params like _rsc* are NOT filtered here) */
|
|
40
|
-
url: URL;
|
|
41
|
-
/** URL pathname */
|
|
42
|
-
pathname: string;
|
|
43
|
-
/** URL search params (system params like _rsc* are NOT filtered here) */
|
|
44
|
-
searchParams: URLSearchParams;
|
|
45
|
-
/** Variables set by middleware (same as ctx.var) */
|
|
46
|
-
var: Record<string, any>;
|
|
86
|
+
> extends RequestScope<TEnv> {
|
|
87
|
+
/** @internal Shared variable backing store for ctx.get()/ctx.set(). */
|
|
88
|
+
_variables: Record<string, any>;
|
|
47
89
|
/** Get a variable set by middleware */
|
|
48
|
-
get:
|
|
90
|
+
get: {
|
|
91
|
+
<T>(contextVar: ContextVar<T>): T | undefined;
|
|
92
|
+
<K extends string>(key: K): any;
|
|
93
|
+
};
|
|
49
94
|
/** Set a variable (shared with middleware and handlers) */
|
|
50
|
-
set:
|
|
95
|
+
set: {
|
|
96
|
+
<T>(
|
|
97
|
+
contextVar: ContextVar<T>,
|
|
98
|
+
value: T,
|
|
99
|
+
options?: { cache?: boolean },
|
|
100
|
+
): void;
|
|
101
|
+
<K extends string>(key: K, value: any, options?: { cache?: boolean }): void;
|
|
102
|
+
};
|
|
51
103
|
/**
|
|
52
104
|
* Route params (populated after route matching)
|
|
53
105
|
* Initially empty, then set to matched params
|
|
54
106
|
*/
|
|
55
107
|
params: TParams;
|
|
108
|
+
/** @internal Stub response for collecting headers/cookies. Use ctx.headers or ctx.header() instead. */
|
|
109
|
+
readonly res: Response;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* True for build-time render/capture requests. Live requests use false.
|
|
113
|
+
* Build-time shell capture sets this while replaying middleware so apps can
|
|
114
|
+
* skip side-effectful runtime work.
|
|
115
|
+
*/
|
|
116
|
+
readonly build: boolean;
|
|
117
|
+
|
|
56
118
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
119
|
+
* Opt this request out of PPR shell serving/capture.
|
|
120
|
+
* Runtime middleware can call this before the PPR commit point; handlers can
|
|
121
|
+
* call it on a MISS to prevent the follow-up capture.
|
|
122
|
+
*
|
|
123
|
+
* Scope: the PPR SHELL axis only. It does NOT disable prerender B-segment
|
|
124
|
+
* (Prerender/Static) serving, and it is inert in the prerender-collect /
|
|
125
|
+
* static-render contexts (no live shell decision to influence there).
|
|
59
126
|
*/
|
|
60
|
-
|
|
127
|
+
dynamic(): void;
|
|
128
|
+
|
|
129
|
+
/** @internal Request-local PPR opt-out marker set by ctx.dynamic(). */
|
|
130
|
+
_dynamic?: boolean;
|
|
61
131
|
|
|
62
|
-
/** Get a cookie value
|
|
132
|
+
/** @internal Get a cookie value (effective: request + response mutations). Use cookies().get() instead. */
|
|
63
133
|
cookie(name: string): string | undefined;
|
|
64
|
-
/** Get all cookies
|
|
134
|
+
/** @internal Get all cookies (effective merged view). Use cookies().getAll() instead. */
|
|
65
135
|
cookies(): Record<string, string>;
|
|
66
|
-
/** Set a cookie on the response */
|
|
136
|
+
/** @internal Set a cookie on the response. Use cookies().set() instead. */
|
|
67
137
|
setCookie(name: string, value: string, options?: CookieOptions): void;
|
|
68
|
-
/** Delete a cookie */
|
|
69
|
-
deleteCookie(
|
|
138
|
+
/** @internal Delete a cookie. Use cookies().delete() instead. */
|
|
139
|
+
deleteCookie(
|
|
140
|
+
name: string,
|
|
141
|
+
options?: Pick<CookieOptions, "domain" | "path">,
|
|
142
|
+
): void;
|
|
70
143
|
/** Set a response header */
|
|
71
144
|
header(name: string, value: string): void;
|
|
145
|
+
/** Set the response status code */
|
|
146
|
+
setStatus(status: number): void;
|
|
147
|
+
/** @internal Set status bypassing cache-exec guard (for framework error handling) */
|
|
148
|
+
_setStatus(status: number): void;
|
|
149
|
+
/** @internal Rotate the rango state cookie (server seat of invalidateClientCache). */
|
|
150
|
+
_rotateStateCookie(): void;
|
|
151
|
+
/** @internal Set the keepClientCache() directive header on the response. */
|
|
152
|
+
_setKeepCacheDirective(): void;
|
|
72
153
|
|
|
73
154
|
/**
|
|
74
155
|
* Access loader data or push handle data.
|
|
@@ -90,10 +171,12 @@ export interface RequestContext<
|
|
|
90
171
|
* ```
|
|
91
172
|
*/
|
|
92
173
|
use: {
|
|
93
|
-
<T, TLoaderParams = any>(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
174
|
+
<T, TLoaderParams = any>(
|
|
175
|
+
loader: LoaderDefinition<T, TLoaderParams>,
|
|
176
|
+
): Promise<T>;
|
|
177
|
+
<TData, TAccumulated = TData[]>(
|
|
178
|
+
handle: Handle<TData, TAccumulated>,
|
|
179
|
+
): (data: TData | Promise<TData> | (() => Promise<TData>)) => void;
|
|
97
180
|
};
|
|
98
181
|
|
|
99
182
|
/** HTTP method (GET, POST, PUT, PATCH, DELETE, etc.) */
|
|
@@ -102,22 +185,159 @@ export interface RequestContext<
|
|
|
102
185
|
/** @internal Handle store for tracking handle data across segments */
|
|
103
186
|
_handleStore: HandleStore;
|
|
104
187
|
|
|
188
|
+
/**
|
|
189
|
+
* @internal transition({ when }) predicates for segments matched this request,
|
|
190
|
+
* keyed by segment id. Collected during resolution (the function is stripped
|
|
191
|
+
* from the serialized segment config), then evaluated post-handler in
|
|
192
|
+
* rsc-rendering — outside any cache scope — to drop the transition of any
|
|
193
|
+
* segment whose predicate returns false.
|
|
194
|
+
*/
|
|
195
|
+
_transitionWhen?: Array<{ id: string; when: TransitionWhenFn }>;
|
|
196
|
+
|
|
105
197
|
/** @internal Cache store for segment caching (optional, used by CacheScope) */
|
|
106
198
|
_cacheStore?: SegmentCacheStore;
|
|
107
199
|
|
|
108
200
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
201
|
+
* @internal PPR shell-capture ACTIVE marker. True ONLY inside the background
|
|
202
|
+
* capture task's derived request context (built by shell-capture.ts). This is
|
|
203
|
+
* the switch every capture-specific behavior reads: loader masking
|
|
204
|
+
* (loader-mask.ts isShellCaptureActive / fresh.ts emitStreaming) and the
|
|
205
|
+
* cookies()/headers() capture guard (cookie-store.ts
|
|
206
|
+
* assertNotInsideShellCapture). The foreground render never sets it, so the
|
|
207
|
+
* served response is byte-identical to axis 1. The capture descriptor itself
|
|
208
|
+
* (key/ttl/swr/tags/store) is NOT threaded through the request context — the
|
|
209
|
+
* integrated PPR serve path (rsc/shell-serve.ts + rsc-rendering.ts) builds it
|
|
210
|
+
* locally and passes it to scheduleShellCapture directly.
|
|
211
|
+
*/
|
|
212
|
+
_shellCaptureRun?: boolean;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @internal Bake-lane loader containers collected DURING a shell capture:
|
|
216
|
+
* segment-key -> the loader's (pre-wrap) result promise. Populated by
|
|
217
|
+
* resolveLoaderData for loaders on entries with no renderable loading() (the
|
|
218
|
+
* bake lane — they execute at capture instead of being masked; see
|
|
219
|
+
* docs/design/loader-container-bake.md). Drained by captureAndStoreShell
|
|
220
|
+
* after the shell quiesces: settled containers are promise-elided,
|
|
221
|
+
* Flight-serialized, and pinned into the snapshot's loader family; a
|
|
222
|
+
* REJECTED container refuses the capture (error UI must never bake into the
|
|
223
|
+
* shared shell). Own property of the capture's derived context only.
|
|
224
|
+
*/
|
|
225
|
+
_shellCaptureLoaderRecords?: Map<string, Promise<unknown>>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @internal Loader-family snapshot seed for a shell HIT's tail render:
|
|
229
|
+
* segment-key -> the capture's elided container (already Flight-deserialized
|
|
230
|
+
* by serveShellHit). resolveLoaderData overlays it onto the fresh run's
|
|
231
|
+
* container (recorded paths pinned, hole-marker paths keep the fresh nested
|
|
232
|
+
* promises) so the payload's baked bytes match the frozen prelude. Own
|
|
233
|
+
* property of the HIT tail's derived context only.
|
|
234
|
+
*/
|
|
235
|
+
_shellLoaderSeed?: Map<string, unknown>;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* @internal Shell fast-path marker: makes the NEXT full match treat the whole
|
|
239
|
+
* matched route as an implicit doc-level cache() boundary (see
|
|
240
|
+
* resolveShellImplicitCacheScope in cache/cache-scope.ts). Set ONLY on
|
|
241
|
+
* (a) the capture's derived context — with a record-only store so the
|
|
242
|
+
* capture's cacheRoute write lands in the snapshot, never the real store —
|
|
243
|
+
* and (b) a HIT tail's seeded context when the entry is eligible
|
|
244
|
+
* (!handlerLiveHoles), where the SeededShellStore serves the recorded doc
|
|
245
|
+
* entry and the match skips handler execution entirely. Routes with their
|
|
246
|
+
* own cache() config (including cache(false)) are never overridden: the
|
|
247
|
+
* marker only applies when the route tree derived NO cache scope.
|
|
119
248
|
*/
|
|
120
|
-
|
|
249
|
+
_shellImplicitCache?: {
|
|
250
|
+
ttl?: number;
|
|
251
|
+
swr?: number;
|
|
252
|
+
store?: SegmentCacheStore;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @internal Shell-HIT tail marker: cache/prerender-store hits during THIS
|
|
257
|
+
* render emit stored segment fragments VERBATIM into the payload
|
|
258
|
+
* (segment-codec fragmentSegments) instead of deserialize -> re-serialize
|
|
259
|
+
* per request; the payload consumers (SSR resume + browser hydration)
|
|
260
|
+
* expand them (segment-fragments.ts, issue #700). Own property of
|
|
261
|
+
* serveShellHit's derived tail context ONLY — it must never be visible to a
|
|
262
|
+
* capture render: the capture SSR-prerenders the payload AND serializes
|
|
263
|
+
* segments into records (cacheRoute), and an envelope reaching
|
|
264
|
+
* serializeSegments would store a double-encoded fragment.
|
|
265
|
+
*/
|
|
266
|
+
_shellFragmentPayload?: boolean;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @internal Handler-layer liveness observed DURING a shell capture, from
|
|
270
|
+
* three sources: (a) the capture handle-store push wrapper (shell-capture.ts)
|
|
271
|
+
* when a push made OUTSIDE a DSL loader scope carries a nested thenable
|
|
272
|
+
* (masked to a never-filling hole); (b) still-pending top-level handler
|
|
273
|
+
* pushes (liveness unknowable at the barrier); (c) a handler-invoked loader
|
|
274
|
+
* executing during the capture (loader-resolution.ts — its consumption-lane
|
|
275
|
+
* value would freeze on a handler-free HIT). captureAndStoreShell folds it
|
|
276
|
+
* into ShellCacheEntry.handlerLiveHoles at the putShell barrier. Own
|
|
277
|
+
* property of the capture's derived context only.
|
|
278
|
+
*/
|
|
279
|
+
_shellCaptureHandleLiveness?: {
|
|
280
|
+
holes: boolean;
|
|
281
|
+
pendingPushes: number;
|
|
282
|
+
handlerInvokedLoader: boolean;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @internal Handle values pushed from a DSL loader scope DURING a shell
|
|
287
|
+
* capture (identity set; populated by the capture push wrapper in
|
|
288
|
+
* shell-capture.ts). cacheRoute threads it into captureHandles so those
|
|
289
|
+
* values stay out of cache-write handle records — loaders re-run fresh on
|
|
290
|
+
* every HIT, so replaying their captured (masked) values would duplicate
|
|
291
|
+
* the fresh push and stall the Flight handle encode. Own property of the
|
|
292
|
+
* capture's derived context only; render-time handle consumers are
|
|
293
|
+
* unaffected (the exclusion applies only at the captureHandles call site).
|
|
294
|
+
*/
|
|
295
|
+
_shellCaptureLoaderHandleValues?: WeakSet<object>;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* @internal Set (to the offending fn name) by the cookies()/headers()
|
|
299
|
+
* capture guard when it throws DURING a capture render. Load-bearing for the
|
|
300
|
+
* bake lane: a guard throw inside an executing loader is swallowed by
|
|
301
|
+
* wrapLoaderPromise into per-loader error UI, which would otherwise bake
|
|
302
|
+
* silently into the shared shell — the capture checks this flag after the
|
|
303
|
+
* render and refuses instead. Deterministic, so the capture does not retry.
|
|
304
|
+
*/
|
|
305
|
+
_shellCaptureGuardTripped?: string;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @internal The loader $$id whose BODY was executing when the capture guard
|
|
309
|
+
* tripped (read off the loader-body ALS scope at trip time), or undefined
|
|
310
|
+
* when the read came from handler/render code. Only used to make the
|
|
311
|
+
* once-per-key refusal warning name the real source — the old text
|
|
312
|
+
* hardcoded "a bake-lane loader", which misattributed handler-land reads
|
|
313
|
+
* and sent users debugging the wrong lane (issue #672, secondary).
|
|
314
|
+
*/
|
|
315
|
+
_shellCaptureGuardTrippedLoaderId?: string;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @internal Handler-owned registry of explicit per-scope stores from
|
|
319
|
+
* cache({ store }). Created once per createRSCHandler() and threaded into
|
|
320
|
+
* every request context, so it accumulates every explicit store the handler
|
|
321
|
+
* resolves. updateTag()/revalidateTag() iterate this set plus _cacheStore to
|
|
322
|
+
* reach every store that may hold tagged entries. The app-level store is not
|
|
323
|
+
* added here (it is always reachable via _cacheStore).
|
|
324
|
+
*/
|
|
325
|
+
_explicitTaggedStores?: Set<SegmentCacheStore>;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* @internal Union of every cache tag resolved while producing this request's
|
|
329
|
+
* response (from cache({ tags }), runtime cacheTag(), and loader cache tags).
|
|
330
|
+
* Populated at the tag-resolution sites via recordRequestTags(). Read by the
|
|
331
|
+
* document cache middleware so a full-page entry is tagged with everything its
|
|
332
|
+
* content used and can therefore be invalidated by updateTag()/revalidateTag().
|
|
333
|
+
*/
|
|
334
|
+
_requestTags: Set<string>;
|
|
335
|
+
|
|
336
|
+
/** @internal Cache profiles for "use cache" profile resolution (per-router) */
|
|
337
|
+
_cacheProfiles?: Record<
|
|
338
|
+
string,
|
|
339
|
+
import("../cache/profile-registry.js").CacheProfile
|
|
340
|
+
>;
|
|
121
341
|
|
|
122
342
|
/**
|
|
123
343
|
* Register a callback to run when the response is created.
|
|
@@ -141,6 +361,19 @@ export interface RequestContext<
|
|
|
141
361
|
/** @internal Registered onResponse callbacks */
|
|
142
362
|
_onResponseCallbacks: Array<(response: Response) => Response>;
|
|
143
363
|
|
|
364
|
+
/**
|
|
365
|
+
* @internal Promises of the background tasks scheduled via this context's
|
|
366
|
+
* waitUntil (deferred cache writes, revalidations, consumer tasks). The PPR
|
|
367
|
+
* shell capture drains this list BEFORE its match/render as an ORDERING EDGE:
|
|
368
|
+
* every foreground deferred cache write is scheduled here before the capture
|
|
369
|
+
* task is, so settling the list first guarantees the capture's cache reads
|
|
370
|
+
* observe the foreground's generation instead of racing it (see
|
|
371
|
+
* shell-capture.ts). Tasks whose scheduling fn carries
|
|
372
|
+
* UNTRACKED_BACKGROUND_TASK are not tracked (the capture task itself —
|
|
373
|
+
* tracking it would make that drain await its own promise).
|
|
374
|
+
*/
|
|
375
|
+
_pendingBackgroundTasks?: Array<Promise<unknown>>;
|
|
376
|
+
|
|
144
377
|
/**
|
|
145
378
|
* Current theme setting (only available when theme is enabled in router config)
|
|
146
379
|
*
|
|
@@ -178,8 +411,259 @@ export interface RequestContext<
|
|
|
178
411
|
|
|
179
412
|
/** @internal Theme configuration (null if theme not enabled) */
|
|
180
413
|
_themeConfig?: ResolvedThemeConfig | null;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Attach location state entries to the current response.
|
|
417
|
+
*
|
|
418
|
+
* For partial (SPA) requests, the state is included in the RSC payload
|
|
419
|
+
* metadata and merged into history.pushState on the client. For redirect
|
|
420
|
+
* responses, the state travels through the redirect payload so the target
|
|
421
|
+
* page can read it via useLocationState.
|
|
422
|
+
*
|
|
423
|
+
* Multiple calls accumulate entries.
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* ctx.setLocationState(Flash({ text: "Item saved!" }));
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void;
|
|
431
|
+
|
|
432
|
+
/** @internal Accumulated location state entries */
|
|
433
|
+
_locationState?: LocationStateEntry[];
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* The matched route name, if the route has an explicit name.
|
|
437
|
+
* Undefined before route matching or for unnamed routes.
|
|
438
|
+
* Includes the namespace prefix from include() (e.g., "blog.post").
|
|
439
|
+
*/
|
|
440
|
+
routeName?: DefaultRouteName;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Generate URLs from route names.
|
|
444
|
+
* Uses the global route map. After route matching, scoped (`.name`) resolution
|
|
445
|
+
* works within the matched include() scope.
|
|
446
|
+
*/
|
|
447
|
+
reverse: ScopedReverseFunction<
|
|
448
|
+
Record<string, string>,
|
|
449
|
+
DefaultReverseRouteMap
|
|
450
|
+
>;
|
|
451
|
+
|
|
452
|
+
/** @internal Route name from route matching, used for scoped reverse resolution */
|
|
453
|
+
_routeName?: string;
|
|
454
|
+
|
|
455
|
+
/** @internal Previous route key (from the navigation source), used for revalidation */
|
|
456
|
+
_prevRouteKey?: string;
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* @internal Navigation/action source data the transition({ when }) gate reads
|
|
460
|
+
* to build its ShouldRevalidateFn-shaped predicate context. currentUrl/Params
|
|
461
|
+
* come from the navigation snapshot (set at match time); action* are stashed
|
|
462
|
+
* at the action-bearing gate call sites. All undefined when there is no source
|
|
463
|
+
* (initial full load) or no action (plain navigation).
|
|
464
|
+
*/
|
|
465
|
+
_gateCurrentUrl?: URL;
|
|
466
|
+
_gateCurrentParams?: Record<string, string>;
|
|
467
|
+
_gateActionId?: string;
|
|
468
|
+
_gateActionUrl?: URL;
|
|
469
|
+
_gateActionResult?: unknown;
|
|
470
|
+
_gateFormData?: FormData;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* @internal True while the post-action revalidation render is running (set by
|
|
474
|
+
* revalidateAfterAction). The "use cache" runtime reads this to prefer
|
|
475
|
+
* freshness over a fast stale response during an action: a stale entry
|
|
476
|
+
* re-executes in the foreground (so the action response reflects the refreshed
|
|
477
|
+
* value) with only the store write deferred, instead of serving stale and
|
|
478
|
+
* revalidating in the background. A plain navigation (flag unset) keeps SWR.
|
|
479
|
+
*/
|
|
480
|
+
_inActionRevalidation?: boolean;
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* @internal Render barrier for experimental `rendered()` API.
|
|
484
|
+
* Resolves when all non-loader segments have settled and handle data
|
|
485
|
+
* is available. Used by DSL loaders that call `ctx.rendered()`.
|
|
486
|
+
*/
|
|
487
|
+
_renderBarrier: Promise<void>;
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* @internal Resolve the render barrier. Accepts resolved segments, filters
|
|
491
|
+
* out loaders, and captures non-loader segment IDs as the handle ordering.
|
|
492
|
+
* Called after segment resolution (fresh) or handle replay (cache/prerender).
|
|
493
|
+
*/
|
|
494
|
+
_resolveRenderBarrier: (
|
|
495
|
+
segments: Array<{ type: string; id: string }>,
|
|
496
|
+
) => void;
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @internal Segment order at barrier resolution time, used by loader
|
|
500
|
+
* ctx.use(handle) to collect handle data in correct order.
|
|
501
|
+
*/
|
|
502
|
+
_renderBarrierSegmentOrder?: string[];
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* @internal Set to true when the matched entry tree contains any `loading()`
|
|
506
|
+
* entries (streaming). On a streaming tree rendered() waits for the streaming
|
|
507
|
+
* handlers to settle (via handleStore.settled) before resolving, and the
|
|
508
|
+
* deadlock guard state is kept live until that wait completes.
|
|
509
|
+
*/
|
|
510
|
+
_treeHasStreaming?: boolean;
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* @internal Loader IDs that have called rendered() and are waiting for the
|
|
514
|
+
* barrier. Used to detect deadlocks when a handler tries to await the same
|
|
515
|
+
* loader via ctx.use(Loader).
|
|
516
|
+
*/
|
|
517
|
+
_renderBarrierWaiters?: Set<string>;
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* @internal Loader IDs that handlers have started awaiting via ctx.use().
|
|
521
|
+
* Used for bidirectional deadlock detection: if a loader later calls
|
|
522
|
+
* rendered() and a handler already awaits it, we can detect the deadlock.
|
|
523
|
+
*/
|
|
524
|
+
_handlerLoaderDeps?: Set<string>;
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @internal Cached HandleData snapshot built at barrier resolution time.
|
|
528
|
+
* Avoids rebuilding the snapshot on every loader ctx.use(handle) call.
|
|
529
|
+
*/
|
|
530
|
+
_renderBarrierHandleSnapshot?: HandleData;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* @internal The deadlock guard window is closed (no further handler-awaits-
|
|
534
|
+
* loader cycle is possible). For non-streaming trees this is set when the
|
|
535
|
+
* barrier resolves. For streaming trees the window stays open until
|
|
536
|
+
* handleStore.settled — rendered() keeps waiting past the barrier and a
|
|
537
|
+
* loading() handler can still resume and await a still-waiting loader — so it
|
|
538
|
+
* is set only after settled. The guard (loader-resolution `setupLoaderAccess`)
|
|
539
|
+
* reads this instead of `_renderBarrierSegmentOrder` so it does not go blind
|
|
540
|
+
* during the streaming settle wait.
|
|
541
|
+
*/
|
|
542
|
+
_renderBarrierGuardClosed?: boolean;
|
|
543
|
+
|
|
544
|
+
/** @internal Per-request error dedup set for onError reporting */
|
|
545
|
+
_reportedErrors: WeakSet<object>;
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* @internal Report a non-fatal background error through the router's
|
|
549
|
+
* onError callback. Wired by the RSC handler / router during request
|
|
550
|
+
* creation. Cache-runtime and other subsystems call this to surface
|
|
551
|
+
* errors without failing the response. `category` is surfaced to consumers as
|
|
552
|
+
* `metadata.category` on the onError context (phase `cache`).
|
|
553
|
+
*/
|
|
554
|
+
_reportBackgroundError?: (
|
|
555
|
+
error: unknown,
|
|
556
|
+
category: CacheErrorCategory,
|
|
557
|
+
) => void;
|
|
558
|
+
|
|
559
|
+
/** @internal Per-request debug performance override (set via ctx.debugPerformance()) */
|
|
560
|
+
_debugPerformance?: boolean;
|
|
561
|
+
|
|
562
|
+
/** @internal Request-scoped performance metrics store */
|
|
563
|
+
_metricsStore?: MetricsStore;
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* @internal True request entry timestamp (performance.now() at handler entry).
|
|
567
|
+
* Set once at request-context creation (rsc/handler.ts) so a metrics store
|
|
568
|
+
* created MID-request — ctx.debugPerformance() or the getMetricsStore wrapper —
|
|
569
|
+
* anchors its timeline to the real request start instead of the opt-in moment,
|
|
570
|
+
* keeping phases that began before the opt-in at their true (non-negative) offset.
|
|
571
|
+
*/
|
|
572
|
+
_handlerStart?: number;
|
|
573
|
+
|
|
574
|
+
/** @internal Resolved platform phase-span tracing for this request (Cloudflare or OTel) */
|
|
575
|
+
_tracing?: ResolvedTracing;
|
|
576
|
+
|
|
577
|
+
/** @internal Router basename for this request (used by redirect()) */
|
|
578
|
+
_basename?: string;
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* @internal RouteSnapshot from classifyRequest, reused by match/matchPartial
|
|
582
|
+
* to avoid a second resolveRoute call. Cleared on HMR invalidation.
|
|
583
|
+
*/
|
|
584
|
+
_classifiedRoute?: import("../router/route-snapshot.js").RouteSnapshot;
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* @internal Coarse route-level cache signal for the X-Rango-Cache debug
|
|
588
|
+
* header. Populated by match/matchPartial only when the debug cache signal
|
|
589
|
+
* gate is enabled (debugCacheSignal option or RANGO_TEST_SIGNALS=1). Read by
|
|
590
|
+
* the response-finalization path (createResponseWithMergedHeaders). Undefined
|
|
591
|
+
* when the gate is off, so no header is emitted.
|
|
592
|
+
*/
|
|
593
|
+
_cacheSignal?: import("../router/telemetry.js").CacheSegmentSignal[];
|
|
181
594
|
}
|
|
182
595
|
|
|
596
|
+
/**
|
|
597
|
+
* Public view of RequestContext, without internal methods and fields.
|
|
598
|
+
*
|
|
599
|
+
* This is the type exported to library consumers. Internal code should
|
|
600
|
+
* use the full RequestContext interface directly.
|
|
601
|
+
*/
|
|
602
|
+
export type PublicRequestContext<
|
|
603
|
+
TEnv = DefaultEnv,
|
|
604
|
+
TParams = Record<string, string>,
|
|
605
|
+
> = Omit<
|
|
606
|
+
RequestContext<TEnv, TParams>,
|
|
607
|
+
| "cookie"
|
|
608
|
+
| "cookies"
|
|
609
|
+
| "setCookie"
|
|
610
|
+
| "deleteCookie"
|
|
611
|
+
| "_handleStore"
|
|
612
|
+
| "_transitionWhen"
|
|
613
|
+
| "_cacheStore"
|
|
614
|
+
| "_shellCaptureRun"
|
|
615
|
+
| "_shellFragmentPayload"
|
|
616
|
+
| "_shellCaptureGuardTrippedLoaderId"
|
|
617
|
+
| "_explicitTaggedStores"
|
|
618
|
+
| "_requestTags"
|
|
619
|
+
| "_cacheProfiles"
|
|
620
|
+
| "_onResponseCallbacks"
|
|
621
|
+
| "_themeConfig"
|
|
622
|
+
| "_locationState"
|
|
623
|
+
| "_routeName"
|
|
624
|
+
| "_prevRouteKey"
|
|
625
|
+
| "_gateCurrentUrl"
|
|
626
|
+
| "_gateCurrentParams"
|
|
627
|
+
| "_gateActionId"
|
|
628
|
+
| "_gateActionUrl"
|
|
629
|
+
| "_gateActionResult"
|
|
630
|
+
| "_gateFormData"
|
|
631
|
+
| "_inActionRevalidation"
|
|
632
|
+
| "_reportedErrors"
|
|
633
|
+
| "_renderBarrier"
|
|
634
|
+
| "_resolveRenderBarrier"
|
|
635
|
+
| "_renderBarrierSegmentOrder"
|
|
636
|
+
| "_treeHasStreaming"
|
|
637
|
+
| "_renderBarrierWaiters"
|
|
638
|
+
| "_handlerLoaderDeps"
|
|
639
|
+
| "_renderBarrierHandleSnapshot"
|
|
640
|
+
| "_renderBarrierGuardClosed"
|
|
641
|
+
| "_reportBackgroundError"
|
|
642
|
+
| "_debugPerformance"
|
|
643
|
+
| "_metricsStore"
|
|
644
|
+
| "_handlerStart"
|
|
645
|
+
| "_basename"
|
|
646
|
+
| "_setStatus"
|
|
647
|
+
| "_rotateStateCookie"
|
|
648
|
+
| "_setKeepCacheDirective"
|
|
649
|
+
| "_variables"
|
|
650
|
+
| "_classifiedRoute"
|
|
651
|
+
| "_cacheSignal"
|
|
652
|
+
| "_dynamic"
|
|
653
|
+
| "res"
|
|
654
|
+
>;
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Marker for a waitUntil-scheduled fn whose task promise must NOT enter
|
|
658
|
+
* _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
|
|
659
|
+
* the capture's pre-render write barrier settles that list, so tracking the
|
|
660
|
+
* capture itself would make the drain wait on its own (still-running) promise.
|
|
661
|
+
* @internal
|
|
662
|
+
*/
|
|
663
|
+
export const UNTRACKED_BACKGROUND_TASK: unique symbol = Symbol.for(
|
|
664
|
+
"rango.untrackedBackgroundTask",
|
|
665
|
+
);
|
|
666
|
+
|
|
183
667
|
// AsyncLocalStorage instance for request context
|
|
184
668
|
const requestContextStorage = new AsyncLocalStorage<RequestContext<any>>();
|
|
185
669
|
|
|
@@ -189,16 +673,33 @@ const requestContextStorage = new AsyncLocalStorage<RequestContext<any>>();
|
|
|
189
673
|
*/
|
|
190
674
|
export function runWithRequestContext<TEnv, T>(
|
|
191
675
|
context: RequestContext<TEnv>,
|
|
192
|
-
fn: () => T
|
|
676
|
+
fn: () => T,
|
|
193
677
|
): T {
|
|
194
678
|
return requestContextStorage.run(context, fn);
|
|
195
679
|
}
|
|
196
680
|
|
|
197
681
|
/**
|
|
198
682
|
* Get the current request context
|
|
199
|
-
*
|
|
683
|
+
* Throws if called outside of a request context
|
|
684
|
+
*/
|
|
685
|
+
export function getRequestContext<TEnv = DefaultEnv>(): RequestContext<TEnv> {
|
|
686
|
+
const ctx = requestContextStorage.getStore() as
|
|
687
|
+
| RequestContext<TEnv>
|
|
688
|
+
| undefined;
|
|
689
|
+
invariant(
|
|
690
|
+
ctx,
|
|
691
|
+
"getRequestContext() called outside of a request context. " +
|
|
692
|
+
"This function must be called from within a route handler, loader, middleware, " +
|
|
693
|
+
"server action, or server component.",
|
|
694
|
+
);
|
|
695
|
+
return ctx;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* @internal Get the request context without throwing — for internal code that
|
|
700
|
+
* may run outside a request context (cache stores, optional handle lookups, etc.)
|
|
200
701
|
*/
|
|
201
|
-
export function
|
|
702
|
+
export function _getRequestContext<TEnv = DefaultEnv>():
|
|
202
703
|
| RequestContext<TEnv>
|
|
203
704
|
| undefined {
|
|
204
705
|
return requestContextStorage.getStore() as RequestContext<TEnv> | undefined;
|
|
@@ -206,38 +707,72 @@ export function getRequestContext<TEnv = unknown>():
|
|
|
206
707
|
|
|
207
708
|
/**
|
|
208
709
|
* Update params on the current request context
|
|
209
|
-
* Called after route matching to populate route params
|
|
710
|
+
* Called after route matching to populate route params and route name
|
|
210
711
|
*/
|
|
211
|
-
export function setRequestContextParams(
|
|
712
|
+
export function setRequestContextParams(
|
|
713
|
+
params: Record<string, string>,
|
|
714
|
+
routeName?: string,
|
|
715
|
+
routeMap?: Record<string, string>,
|
|
716
|
+
): void {
|
|
212
717
|
const ctx = requestContextStorage.getStore();
|
|
213
718
|
if (ctx) {
|
|
214
719
|
ctx.params = params;
|
|
720
|
+
if (routeName !== undefined) {
|
|
721
|
+
ctx._routeName = routeName;
|
|
722
|
+
ctx.routeName = (
|
|
723
|
+
routeName && !isAutoGeneratedRouteName(routeName)
|
|
724
|
+
? routeName
|
|
725
|
+
: undefined
|
|
726
|
+
) as DefaultRouteName | undefined;
|
|
727
|
+
}
|
|
728
|
+
// Update reverse with scoped resolution now that route is known. Production
|
|
729
|
+
// omits routeMap and uses the global map (routes are registered globally);
|
|
730
|
+
// the testing primitives (renderToFlightString/renderServerTree) pass a
|
|
731
|
+
// scoped routeMap so `ctx.reverse` is not order-dependent on whatever router
|
|
732
|
+
// registered last.
|
|
733
|
+
ctx.reverse = createReverseFunction(
|
|
734
|
+
routeMap ?? getGlobalRouteMap(),
|
|
735
|
+
routeName,
|
|
736
|
+
params,
|
|
737
|
+
routeName ? isRouteRootScoped(routeName) : undefined,
|
|
738
|
+
);
|
|
215
739
|
}
|
|
216
740
|
}
|
|
217
741
|
|
|
218
742
|
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
743
|
+
* Store the previous route key on the request context.
|
|
744
|
+
* Called during partial-match context creation to make the navigation source
|
|
745
|
+
* route key available for revalidation and intercept evaluation.
|
|
746
|
+
* @internal
|
|
221
747
|
*/
|
|
222
|
-
export function
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
748
|
+
export function setRequestContextPrevRouteKey(
|
|
749
|
+
prevRouteKey: string | undefined,
|
|
750
|
+
currentUrl?: URL,
|
|
751
|
+
currentParams?: Record<string, string>,
|
|
752
|
+
): void {
|
|
753
|
+
const ctx = requestContextStorage.getStore();
|
|
754
|
+
if (!ctx) return;
|
|
755
|
+
if (prevRouteKey !== undefined) ctx._prevRouteKey = prevRouteKey;
|
|
756
|
+
// Source URL/params for the transition({ when }) gate (effectiveFromUrl /
|
|
757
|
+
// effectiveFromMatch.params from the navigation snapshot). Same write point as
|
|
758
|
+
// _prevRouteKey, which doubles as fromRouteName.
|
|
759
|
+
if (currentUrl !== undefined) ctx._gateCurrentUrl = currentUrl;
|
|
760
|
+
if (currentParams !== undefined) ctx._gateCurrentParams = currentParams;
|
|
231
761
|
}
|
|
232
762
|
|
|
233
763
|
/**
|
|
234
|
-
*
|
|
764
|
+
* Get accumulated location state entries from the current request context.
|
|
765
|
+
* Returns undefined if no state has been set.
|
|
766
|
+
*
|
|
767
|
+
* @internal Used by the RSC handler to include state in payload metadata.
|
|
235
768
|
*/
|
|
236
|
-
export
|
|
237
|
-
|
|
238
|
-
|
|
769
|
+
export function getLocationState(): LocationStateEntry[] | undefined {
|
|
770
|
+
const ctx = getRequestContext();
|
|
771
|
+
return ctx?._locationState;
|
|
239
772
|
}
|
|
240
773
|
|
|
774
|
+
export type { ExecutionContext };
|
|
775
|
+
|
|
241
776
|
/**
|
|
242
777
|
* Options for creating a request context
|
|
243
778
|
*/
|
|
@@ -246,12 +781,30 @@ export interface CreateRequestContextOptions<TEnv> {
|
|
|
246
781
|
request: Request;
|
|
247
782
|
url: URL;
|
|
248
783
|
variables: Record<string, any>;
|
|
784
|
+
/** Optional initial response stub headers/status to seed effective cookie reads */
|
|
785
|
+
initialResponse?: Response;
|
|
249
786
|
/** Optional cache store for segment caching (used by CacheScope) */
|
|
250
787
|
cacheStore?: SegmentCacheStore;
|
|
788
|
+
/**
|
|
789
|
+
* Handler-owned registry of explicit per-scope stores for cross-store tag
|
|
790
|
+
* invalidation. Created once per handler, reused across requests.
|
|
791
|
+
*/
|
|
792
|
+
explicitTaggedStores?: Set<SegmentCacheStore>;
|
|
793
|
+
/** Optional cache profiles for "use cache" resolution (per-router) */
|
|
794
|
+
cacheProfiles?: Record<
|
|
795
|
+
string,
|
|
796
|
+
import("../cache/profile-registry.js").CacheProfile
|
|
797
|
+
>;
|
|
251
798
|
/** Optional Cloudflare execution context for waitUntil support */
|
|
252
799
|
executionContext?: ExecutionContext;
|
|
800
|
+
/** Build-time render/capture request marker. Defaults to false. */
|
|
801
|
+
build?: boolean;
|
|
253
802
|
/** Optional theme configuration (enables ctx.theme and ctx.setTheme) */
|
|
254
803
|
themeConfig?: ResolvedThemeConfig | null;
|
|
804
|
+
/** Resolved rango state cookie name, for the server seat of invalidateClientCache(). */
|
|
805
|
+
stateCookieName?: string;
|
|
806
|
+
/** Build version, used as the prefix of a server-rotated rango state value. */
|
|
807
|
+
version?: string;
|
|
255
808
|
}
|
|
256
809
|
|
|
257
810
|
/**
|
|
@@ -263,20 +816,82 @@ export interface CreateRequestContextOptions<TEnv> {
|
|
|
263
816
|
* - Passed to handlers as ctx
|
|
264
817
|
*/
|
|
265
818
|
export function createRequestContext<TEnv>(
|
|
266
|
-
options: CreateRequestContextOptions<TEnv
|
|
819
|
+
options: CreateRequestContextOptions<TEnv>,
|
|
267
820
|
): RequestContext<TEnv> {
|
|
268
|
-
const {
|
|
821
|
+
const {
|
|
822
|
+
env,
|
|
823
|
+
request,
|
|
824
|
+
url,
|
|
825
|
+
variables,
|
|
826
|
+
initialResponse,
|
|
827
|
+
cacheStore,
|
|
828
|
+
explicitTaggedStores,
|
|
829
|
+
cacheProfiles,
|
|
830
|
+
executionContext,
|
|
831
|
+
build = false,
|
|
832
|
+
themeConfig,
|
|
833
|
+
stateCookieName,
|
|
834
|
+
version: stateVersion,
|
|
835
|
+
} = options;
|
|
269
836
|
const cookieHeader = request.headers.get("Cookie");
|
|
837
|
+
let rangoStateRotated = false;
|
|
270
838
|
let parsedCookies: Record<string, string> | null = null;
|
|
271
839
|
|
|
272
|
-
|
|
273
|
-
|
|
840
|
+
let stubResponse = initialResponse
|
|
841
|
+
? new Response(null, {
|
|
842
|
+
status: initialResponse.status,
|
|
843
|
+
statusText: initialResponse.statusText,
|
|
844
|
+
headers: new Headers(initialResponse.headers),
|
|
845
|
+
})
|
|
846
|
+
: new Response(null, { status: 200 });
|
|
847
|
+
|
|
848
|
+
// The #713 choke point: `rawStubHeaders` is the stub's REAL Headers; the
|
|
849
|
+
// proxy below is the only view reachable from consumer code, and its
|
|
850
|
+
// mutating methods consult the cached-scope guard first. shadowStubHeaders
|
|
851
|
+
// shadows `headers` on the stub Response INSTANCE (a real Response, not a
|
|
852
|
+
// facade — safe to hand to the platform), so every surface that ends in a
|
|
853
|
+
// stub-header mutation — ctx.header/setCookie/deleteCookie, ctx.setTheme,
|
|
854
|
+
// the handler ctx.headers proxy, and raw `ctx.res.headers.set(...)` — is
|
|
855
|
+
// guarded at the mutation itself, not per enumerated wrapper. Guard-exempt
|
|
856
|
+
// internal writers (_rotateStateCookie, _setKeepCacheDirective — serve
|
|
857
|
+
// machinery, documented callable from loaders/during capture) write to
|
|
858
|
+
// rawStubHeaders directly. The serve/commit path's stub reads and its
|
|
859
|
+
// Set-Cookie drain (rsc/helpers.ts) run outside any latched funnel scope,
|
|
860
|
+
// where assertCachedHeaderWriteAllowed is a no-op.
|
|
861
|
+
let rawStubHeaders = stubResponse.headers;
|
|
862
|
+
const guardedStubHeaders: Headers = new Proxy(new Headers(), {
|
|
863
|
+
get(_target, prop) {
|
|
864
|
+
const raw = rawStubHeaders;
|
|
865
|
+
const value = Reflect.get(raw, prop) as unknown;
|
|
866
|
+
if (typeof value !== "function") return value;
|
|
867
|
+
if (prop === "set" || prop === "append" || prop === "delete") {
|
|
868
|
+
return (...args: unknown[]) => {
|
|
869
|
+
assertCachedHeaderWriteAllowed("response headers", prop);
|
|
870
|
+
return (value as (...a: unknown[]) => unknown).apply(raw, args);
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
return (value as (...a: unknown[]) => unknown).bind(raw);
|
|
874
|
+
},
|
|
875
|
+
});
|
|
876
|
+
const shadowStubHeaders = (res: Response): void => {
|
|
877
|
+
Object.defineProperty(res, "headers", {
|
|
878
|
+
value: guardedStubHeaders,
|
|
879
|
+
enumerable: true,
|
|
880
|
+
configurable: true,
|
|
881
|
+
});
|
|
882
|
+
};
|
|
883
|
+
shadowStubHeaders(stubResponse);
|
|
884
|
+
// Rebuild the stub with a new status, re-shadowing the fresh instance
|
|
885
|
+
// (the Response constructor copies rawStubHeaders into new raw Headers).
|
|
886
|
+
const replaceStubStatus = (status: number): void => {
|
|
887
|
+
stubResponse = new Response(null, { status, headers: rawStubHeaders });
|
|
888
|
+
rawStubHeaders = stubResponse.headers;
|
|
889
|
+
shadowStubHeaders(stubResponse);
|
|
890
|
+
};
|
|
274
891
|
|
|
275
|
-
// Create handle store and loader memoization for this request
|
|
276
892
|
const handleStore = createHandleStore();
|
|
277
893
|
const loaderPromises = new Map<string, Promise<any>>();
|
|
278
894
|
|
|
279
|
-
// Lazy parse cookies
|
|
280
895
|
const getParsedCookies = (): Record<string, string> => {
|
|
281
896
|
if (!parsedCookies) {
|
|
282
897
|
parsedCookies = parseCookiesFromHeader(cookieHeader);
|
|
@@ -284,13 +899,40 @@ export function createRequestContext<TEnv>(
|
|
|
284
899
|
return parsedCookies;
|
|
285
900
|
};
|
|
286
901
|
|
|
287
|
-
|
|
902
|
+
let responseCookieCache: Map<string, string | null> | null = null;
|
|
903
|
+
const getResponseCookies = (): Map<string, string | null> => {
|
|
904
|
+
if (!responseCookieCache) {
|
|
905
|
+
responseCookieCache = parseResponseCookies(stubResponse);
|
|
906
|
+
}
|
|
907
|
+
return responseCookieCache;
|
|
908
|
+
};
|
|
909
|
+
const invalidateResponseCookieCache = () => {
|
|
910
|
+
responseCookieCache = null;
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
// Guard for the two response-write surfaces that are NOT Headers mutations
|
|
914
|
+
// (setStatus rebuilds the stub Response, onResponse registers a callback) —
|
|
915
|
+
// these can't ride the guarded-headers choke point above, so they stay
|
|
916
|
+
// enumerated. Same unified #713 guard, same message family.
|
|
917
|
+
function assertResponseWriteAllowed(methodName: string): void {
|
|
918
|
+
assertCachedHeaderWriteAllowed("ctx", methodName);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// Response stub Set-Cookie wins, then original header (source of truth for mutations).
|
|
922
|
+
const effectiveCookie = (name: string): string | undefined => {
|
|
923
|
+
const mutations = getResponseCookies();
|
|
924
|
+
if (mutations.has(name)) {
|
|
925
|
+
const v = mutations.get(name);
|
|
926
|
+
return v === null ? undefined : v;
|
|
927
|
+
}
|
|
928
|
+
return getParsedCookies()[name];
|
|
929
|
+
};
|
|
930
|
+
|
|
288
931
|
const getTheme = (): Theme | undefined => {
|
|
289
932
|
if (!themeConfig) return undefined;
|
|
290
933
|
|
|
291
|
-
const stored =
|
|
934
|
+
const stored = effectiveCookie(themeConfig.storageKey);
|
|
292
935
|
if (stored) {
|
|
293
|
-
// Validate stored value
|
|
294
936
|
if (stored === "system" && themeConfig.enableSystem) {
|
|
295
937
|
return "system";
|
|
296
938
|
}
|
|
@@ -304,135 +946,394 @@ export function createRequestContext<TEnv>(
|
|
|
304
946
|
const setTheme = (theme: Theme): void => {
|
|
305
947
|
if (!themeConfig) return;
|
|
306
948
|
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
949
|
+
// Shared guard (isValidTheme): reject any value not in the configured theme
|
|
950
|
+
// set, AND reject "system" when system detection is off — a cookie of
|
|
951
|
+
// theme=system with enableSystem:false would re-apply a bogus class="system"
|
|
952
|
+
// on the next SSR.
|
|
953
|
+
if (!isValidTheme(theme, themeConfig)) {
|
|
954
|
+
warnInvalidTheme(theme, themeConfig);
|
|
310
955
|
return;
|
|
311
956
|
}
|
|
312
957
|
|
|
313
|
-
// Set cookie
|
|
314
958
|
stubResponse.headers.append(
|
|
315
959
|
"Set-Cookie",
|
|
316
960
|
serializeCookieValue(themeConfig.storageKey, theme, {
|
|
317
961
|
path: THEME_COOKIE.path,
|
|
318
962
|
maxAge: THEME_COOKIE.maxAge,
|
|
319
963
|
sameSite: THEME_COOKIE.sameSite,
|
|
320
|
-
})
|
|
964
|
+
}),
|
|
321
965
|
);
|
|
966
|
+
invalidateResponseCookieCache();
|
|
322
967
|
};
|
|
323
968
|
|
|
324
|
-
|
|
969
|
+
const cleanUrl = stripInternalParams(url);
|
|
970
|
+
|
|
325
971
|
const ctx: RequestContext<TEnv> = {
|
|
326
972
|
env,
|
|
327
973
|
request,
|
|
328
|
-
url,
|
|
974
|
+
url: cleanUrl,
|
|
975
|
+
originalUrl: new URL(request.url),
|
|
329
976
|
pathname: url.pathname,
|
|
330
|
-
searchParams:
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
977
|
+
searchParams: cleanUrl.searchParams,
|
|
978
|
+
_variables: variables,
|
|
979
|
+
build,
|
|
980
|
+
dynamic(): void {
|
|
981
|
+
ctx._dynamic = true;
|
|
335
982
|
},
|
|
983
|
+
_dynamic: false,
|
|
984
|
+
get: ((keyOrVar: any) => {
|
|
985
|
+
if (isNonCacheable(variables, keyOrVar) && isInsideCacheScope()) {
|
|
986
|
+
throw new Error(
|
|
987
|
+
`ctx.get() for a non-cacheable variable cannot be called inside a cache() boundary. ` +
|
|
988
|
+
`The variable was created with { cache: false } or set with { cache: false }, ` +
|
|
989
|
+
`and its value would be stale on cache hit. Move the read outside the cached scope.`,
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
return contextGet(variables, keyOrVar);
|
|
993
|
+
}) as RequestContext<TEnv>["get"],
|
|
994
|
+
set: ((keyOrVar: any, value: any, options?: any) => {
|
|
995
|
+
assertNotInsideCacheExec(ctx, "set");
|
|
996
|
+
contextSet(variables, keyOrVar, value, options);
|
|
997
|
+
}) as RequestContext<TEnv>["set"],
|
|
336
998
|
params: {} as Record<string, string>,
|
|
337
|
-
|
|
999
|
+
|
|
1000
|
+
get res(): Response {
|
|
1001
|
+
return stubResponse;
|
|
1002
|
+
},
|
|
1003
|
+
set res(_: Response) {
|
|
1004
|
+
throw new Error(
|
|
1005
|
+
"ctx.res is read-only. Use ctx.header() to set response headers, or cookies() for cookie mutations.",
|
|
1006
|
+
);
|
|
1007
|
+
},
|
|
338
1008
|
|
|
339
1009
|
cookie(name: string): string | undefined {
|
|
340
|
-
return
|
|
1010
|
+
return effectiveCookie(name);
|
|
341
1011
|
},
|
|
342
1012
|
|
|
343
1013
|
cookies(): Record<string, string> {
|
|
344
|
-
|
|
1014
|
+
const parsed = getParsedCookies();
|
|
1015
|
+
const mutations = getResponseCookies();
|
|
1016
|
+
if (mutations.size === 0) return { ...parsed };
|
|
1017
|
+
// Build result without delete (avoids V8 dictionary-mode de-opt)
|
|
1018
|
+
const deleted = new Set<string>();
|
|
1019
|
+
for (const [k, v] of mutations) {
|
|
1020
|
+
if (v === null) deleted.add(k);
|
|
1021
|
+
}
|
|
1022
|
+
const result: Record<string, string> = {};
|
|
1023
|
+
for (const key of Object.keys(parsed)) {
|
|
1024
|
+
if (!deleted.has(key)) result[key] = parsed[key];
|
|
1025
|
+
}
|
|
1026
|
+
for (const [k, v] of mutations) {
|
|
1027
|
+
if (v !== null) result[k] = v;
|
|
1028
|
+
}
|
|
1029
|
+
return result;
|
|
345
1030
|
},
|
|
346
1031
|
|
|
347
1032
|
setCookie(name: string, value: string, options?: CookieOptions): void {
|
|
1033
|
+
assertNotInsideCacheExec(ctx, "setCookie");
|
|
348
1034
|
stubResponse.headers.append(
|
|
349
1035
|
"Set-Cookie",
|
|
350
|
-
serializeCookieValue(name, value, options)
|
|
1036
|
+
serializeCookieValue(name, value, options),
|
|
351
1037
|
);
|
|
1038
|
+
invalidateResponseCookieCache();
|
|
352
1039
|
},
|
|
353
1040
|
|
|
354
1041
|
deleteCookie(
|
|
355
1042
|
name: string,
|
|
356
|
-
options?: Pick<CookieOptions, "domain" | "path"
|
|
1043
|
+
options?: Pick<CookieOptions, "domain" | "path">,
|
|
357
1044
|
): void {
|
|
1045
|
+
assertNotInsideCacheExec(ctx, "deleteCookie");
|
|
358
1046
|
stubResponse.headers.append(
|
|
359
1047
|
"Set-Cookie",
|
|
360
|
-
serializeCookieValue(name, "", { ...options, maxAge: 0 })
|
|
1048
|
+
serializeCookieValue(name, "", { ...options, maxAge: 0 }),
|
|
361
1049
|
);
|
|
1050
|
+
invalidateResponseCookieCache();
|
|
362
1051
|
},
|
|
363
1052
|
|
|
364
1053
|
header(name: string, value: string): void {
|
|
1054
|
+
assertNotInsideCacheExec(ctx, "header");
|
|
365
1055
|
stubResponse.headers.set(name, value);
|
|
366
1056
|
},
|
|
367
1057
|
|
|
368
|
-
//
|
|
1058
|
+
// Rotate the rango state cookie for the responding client (the server seat
|
|
1059
|
+
// of invalidateClientCache). Writes ONE Set-Cookie per request with the
|
|
1060
|
+
// value {version}:{timestamp}; the `:` stays raw (the cookie-name.ts
|
|
1061
|
+
// serializer), not the URL-encoded form serializeCookieValue would produce.
|
|
1062
|
+
// The timestamp is strictly greater than the client's current one (inbound
|
|
1063
|
+
// X-Rango-State), so a same-millisecond server rotation still differs from
|
|
1064
|
+
// the client value and the divergence observer fires.
|
|
1065
|
+
_rotateStateCookie(): void {
|
|
1066
|
+
if (rangoStateRotated) return;
|
|
1067
|
+
rangoStateRotated = true;
|
|
1068
|
+
if (!stateCookieName) return;
|
|
1069
|
+
// The client's current value, for the monotonic guard: prefer the
|
|
1070
|
+
// X-Rango-State header (router navigation/prefetch fetches send it), but
|
|
1071
|
+
// fall back to the request's rango state cookie — action POSTs / plain
|
|
1072
|
+
// app fetch()s carry no router header yet DO send the cookie. Without the
|
|
1073
|
+
// fallback, prevTs stays 0 and a same-ms mint can equal the client value,
|
|
1074
|
+
// leaving the divergence observer silent. `|| null` so an empty header
|
|
1075
|
+
// ('' from proxy normalization) falls through instead of short-circuiting.
|
|
1076
|
+
// getRawCookieValue reads the cookie undecoded (the wire value
|
|
1077
|
+
// decodeStateValue decodes exactly once) AND is the same parser the client
|
|
1078
|
+
// mirror uses, so both seats read the same jar entry.
|
|
1079
|
+
const prevRaw =
|
|
1080
|
+
(request.headers.get("x-rango-state") || null) ??
|
|
1081
|
+
getRawCookieValue(cookieHeader, stateCookieName);
|
|
1082
|
+
const value = mintStateValue(stateVersion ?? "0", prevRaw);
|
|
1083
|
+
// rawStubHeaders: guard-exempt internal writer — invalidateClientCache()
|
|
1084
|
+
// is documented callable from loaders and during shell capture.
|
|
1085
|
+
rawStubHeaders.append(
|
|
1086
|
+
"Set-Cookie",
|
|
1087
|
+
serializeStateCookie(stateCookieName, value, url.protocol === "https:"),
|
|
1088
|
+
);
|
|
1089
|
+
invalidateResponseCookieCache();
|
|
1090
|
+
},
|
|
1091
|
+
|
|
1092
|
+
// Set the keepClientCache() directive header. The action bridge reads it on
|
|
1093
|
+
// the response and suppresses its automatic invalidation. `.set` makes this
|
|
1094
|
+
// idempotent (one header regardless of call count). rawStubHeaders:
|
|
1095
|
+
// guard-exempt internal writer.
|
|
1096
|
+
_setKeepCacheDirective(): void {
|
|
1097
|
+
rawStubHeaders.set(KEEP_CACHE_HEADER, "1");
|
|
1098
|
+
},
|
|
1099
|
+
|
|
1100
|
+
setStatus(status: number): void {
|
|
1101
|
+
assertNotInsideCacheExec(ctx, "setStatus");
|
|
1102
|
+
assertResponseWriteAllowed("setStatus");
|
|
1103
|
+
replaceStubStatus(status);
|
|
1104
|
+
},
|
|
1105
|
+
|
|
1106
|
+
_setStatus(status: number): void {
|
|
1107
|
+
replaceStubStatus(status);
|
|
1108
|
+
},
|
|
1109
|
+
|
|
369
1110
|
use: null as any,
|
|
370
1111
|
|
|
371
1112
|
method: request.method,
|
|
372
1113
|
|
|
373
1114
|
_handleStore: handleStore,
|
|
1115
|
+
_transitionWhen: [],
|
|
374
1116
|
_cacheStore: cacheStore,
|
|
1117
|
+
_explicitTaggedStores: explicitTaggedStores,
|
|
1118
|
+
_requestTags: new Set<string>(),
|
|
1119
|
+
_cacheProfiles: cacheProfiles,
|
|
375
1120
|
|
|
376
1121
|
waitUntil(fn: () => Promise<void>): void {
|
|
1122
|
+
if (ctx.build) return;
|
|
1123
|
+
// Wrap in Promise.resolve().then(fn) so a SYNCHRONOUS throw in a
|
|
1124
|
+
// non-async callback becomes a rejected promise handed to the host's
|
|
1125
|
+
// waitUntil (logged as a background failure), instead of escaping into
|
|
1126
|
+
// the request flow. Mirrors fireAndForgetWaitUntil's deferral.
|
|
1127
|
+
const task = Promise.resolve().then(fn);
|
|
1128
|
+
// Track the task promise so the PPR shell capture can settle the
|
|
1129
|
+
// foreground's deferred cache writes before its own match/render (the
|
|
1130
|
+
// ordering edge; see _pendingBackgroundTasks). The capture task itself
|
|
1131
|
+
// opts out via the marker — the drain must never await its own promise.
|
|
1132
|
+
if (
|
|
1133
|
+
!(fn as { [UNTRACKED_BACKGROUND_TASK]?: boolean })[
|
|
1134
|
+
UNTRACKED_BACKGROUND_TASK
|
|
1135
|
+
]
|
|
1136
|
+
) {
|
|
1137
|
+
ctx._pendingBackgroundTasks?.push(task);
|
|
1138
|
+
}
|
|
377
1139
|
if (executionContext?.waitUntil) {
|
|
378
|
-
|
|
379
|
-
executionContext.waitUntil(fn());
|
|
1140
|
+
executionContext.waitUntil(task);
|
|
380
1141
|
} else {
|
|
381
|
-
// Node
|
|
382
|
-
|
|
1142
|
+
// Node/dev fallback: fire-and-forget with error logging (the same
|
|
1143
|
+
// policy fireAndForgetWaitUntil applies).
|
|
1144
|
+
task.catch((err) =>
|
|
1145
|
+
console.error("[waitUntil] Background task failed:", err),
|
|
1146
|
+
);
|
|
383
1147
|
}
|
|
384
1148
|
},
|
|
385
1149
|
|
|
1150
|
+
executionContext,
|
|
1151
|
+
|
|
386
1152
|
_onResponseCallbacks: [],
|
|
1153
|
+
_pendingBackgroundTasks: [],
|
|
387
1154
|
|
|
388
1155
|
onResponse(callback: (response: Response) => Response): void {
|
|
1156
|
+
assertNotInsideCacheExec(ctx, "onResponse");
|
|
1157
|
+
assertResponseWriteAllowed("onResponse");
|
|
389
1158
|
this._onResponseCallbacks.push(callback);
|
|
390
1159
|
},
|
|
391
1160
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
1161
|
+
get theme() {
|
|
1162
|
+
return themeConfig ? getTheme() : undefined;
|
|
1163
|
+
},
|
|
1164
|
+
setTheme: themeConfig
|
|
1165
|
+
? (theme: Theme) => {
|
|
1166
|
+
assertNotInsideCacheExec(ctx, "setTheme");
|
|
1167
|
+
setTheme(theme);
|
|
1168
|
+
}
|
|
1169
|
+
: undefined,
|
|
395
1170
|
_themeConfig: themeConfig,
|
|
1171
|
+
|
|
1172
|
+
setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void {
|
|
1173
|
+
assertNotInsideCacheExec(ctx, "setLocationState");
|
|
1174
|
+
const arr = Array.isArray(entries) ? entries : [entries];
|
|
1175
|
+
this._locationState = this._locationState
|
|
1176
|
+
? [...this._locationState, ...arr]
|
|
1177
|
+
: arr;
|
|
1178
|
+
},
|
|
1179
|
+
_locationState: undefined,
|
|
1180
|
+
|
|
1181
|
+
_reportedErrors: new WeakSet<object>(),
|
|
1182
|
+
_metricsStore: undefined,
|
|
1183
|
+
_handlerStart: undefined,
|
|
1184
|
+
|
|
1185
|
+
_renderBarrier: null as any,
|
|
1186
|
+
_resolveRenderBarrier: null as any,
|
|
1187
|
+
_renderBarrierSegmentOrder: undefined,
|
|
1188
|
+
|
|
1189
|
+
reverse: createReverseFunction(getGlobalRouteMap(), undefined, {}),
|
|
396
1190
|
};
|
|
397
1191
|
|
|
398
|
-
|
|
1192
|
+
wireRenderBarrier(ctx, handleStore);
|
|
1193
|
+
|
|
399
1194
|
ctx.use = createUseFunction({
|
|
400
1195
|
handleStore,
|
|
401
1196
|
loaderPromises,
|
|
402
1197
|
getContext: () => ctx,
|
|
403
1198
|
});
|
|
404
1199
|
|
|
1200
|
+
(ctx as any)[NOCACHE_SYMBOL] = true;
|
|
405
1201
|
return ctx;
|
|
406
1202
|
}
|
|
407
1203
|
|
|
408
1204
|
/**
|
|
409
|
-
*
|
|
1205
|
+
* Wire a fresh render barrier onto `ctx`, closure-bound to THIS ctx and THIS
|
|
1206
|
+
* handle store. Called by createRequestContext for every fresh context, and by
|
|
1207
|
+
* deriveShellCaptureContext (rsc/shell-capture.ts) for the PPR capture's
|
|
1208
|
+
* derived context.
|
|
1209
|
+
*
|
|
1210
|
+
* The derived-context call is load-bearing (issue #684, plan 009): the capture
|
|
1211
|
+
* context is `Object.create(reqCtx)`, so without its own wiring every
|
|
1212
|
+
* `_renderBarrier*` read fell through the prototype to the FOREGROUND
|
|
1213
|
+
* request's barrier — whose getter and resolver are closure-bound to the
|
|
1214
|
+
* foreground ctx and its handle store, and whose resolver no-ops once
|
|
1215
|
+
* resolved. A bake-lane loader's `await ctx.rendered()` during capture then
|
|
1216
|
+
* resolved instantly against the foreground's barrier and `ctx.use(handle)`
|
|
1217
|
+
* read the foreground's handle snapshot; the capture's fresh `_handleStore`
|
|
1218
|
+
* was invisible, so foreground per-request handle data could bake into the
|
|
1219
|
+
* shared shell.
|
|
410
1220
|
*/
|
|
411
|
-
function
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
1221
|
+
export function wireRenderBarrier(
|
|
1222
|
+
ctx: RequestContext<any, any>,
|
|
1223
|
+
handleStore: HandleStore,
|
|
1224
|
+
): void {
|
|
1225
|
+
// Reset the whole barrier family as OWN properties. No-op for a fresh
|
|
1226
|
+
// context; for the derived capture context this shadows the foreground's
|
|
1227
|
+
// resolved state so the capture runs its own barrier lifecycle. In
|
|
1228
|
+
// particular _treeHasStreaming must be recomputed for the CAPTURE's tree
|
|
1229
|
+
// (cache-lookup/segment-resolution only set it when undefined): an
|
|
1230
|
+
// inherited `true` made a capture-lane rendered() seal the capture's fresh
|
|
1231
|
+
// store at loader start and pair it with the foreground's segment order.
|
|
1232
|
+
ctx._renderBarrierSegmentOrder = undefined;
|
|
1233
|
+
ctx._renderBarrierWaiters = undefined;
|
|
1234
|
+
ctx._renderBarrierHandleSnapshot = undefined;
|
|
1235
|
+
ctx._renderBarrierGuardClosed = undefined;
|
|
1236
|
+
ctx._handlerLoaderDeps = undefined;
|
|
1237
|
+
ctx._treeHasStreaming = undefined;
|
|
1238
|
+
|
|
1239
|
+
// Lazy allocation: only create the Promise when a loader calls rendered().
|
|
1240
|
+
let barrierResolved = false;
|
|
1241
|
+
let resolveBarrier: (() => void) | undefined;
|
|
1242
|
+
ctx._resolveRenderBarrier = (
|
|
1243
|
+
segments: Array<{ type: string; id: string }>,
|
|
1244
|
+
) => {
|
|
1245
|
+
if (barrierResolved) return;
|
|
1246
|
+
barrierResolved = true;
|
|
1247
|
+
const segOrder = segments
|
|
1248
|
+
.filter((s) => s.type !== "loader")
|
|
1249
|
+
.map((s) => s.id);
|
|
1250
|
+
ctx._renderBarrierSegmentOrder = segOrder;
|
|
1251
|
+
|
|
1252
|
+
const closeGuard = () => {
|
|
1253
|
+
ctx._renderBarrierWaiters = undefined;
|
|
1254
|
+
ctx._handlerLoaderDeps = undefined;
|
|
1255
|
+
ctx._renderBarrierGuardClosed = true;
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
if (ctx._treeHasStreaming) {
|
|
1259
|
+
handleStore.settled.then(closeGuard);
|
|
1260
|
+
} else {
|
|
1261
|
+
ctx._renderBarrierHandleSnapshot = buildHandleSnapshot(
|
|
1262
|
+
handleStore,
|
|
1263
|
+
segOrder,
|
|
1264
|
+
);
|
|
1265
|
+
closeGuard();
|
|
1266
|
+
}
|
|
1267
|
+
if (resolveBarrier) resolveBarrier();
|
|
1268
|
+
};
|
|
1269
|
+
// defineProperty, not assignment: on a derived context the prototype's
|
|
1270
|
+
// _renderBarrier may already be a non-writable data property (the getter
|
|
1271
|
+
// pins it after first access), which would reject a plain assignment.
|
|
1272
|
+
Object.defineProperty(ctx, "_renderBarrier", {
|
|
1273
|
+
get() {
|
|
1274
|
+
const p = barrierResolved
|
|
1275
|
+
? Promise.resolve()
|
|
1276
|
+
: new Promise<void>((resolve) => {
|
|
1277
|
+
resolveBarrier = resolve;
|
|
1278
|
+
});
|
|
1279
|
+
Object.defineProperty(ctx, "_renderBarrier", {
|
|
1280
|
+
value: p,
|
|
1281
|
+
writable: false,
|
|
1282
|
+
configurable: false,
|
|
1283
|
+
});
|
|
1284
|
+
return p;
|
|
1285
|
+
},
|
|
1286
|
+
configurable: true,
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
// Capture the Max-Age value so it can be parsed numerically. A leading zero
|
|
1291
|
+
// (Max-Age=05) is a non-zero lifetime, not a deletion; only a value that parses
|
|
1292
|
+
// to <= 0 marks a cookie for deletion. Pattern-matching a leading "0" misread
|
|
1293
|
+
// zero-prefixed values like 05 / 010 as deletions.
|
|
1294
|
+
const MAX_AGE_RE = /;\s*Max-Age\s*=\s*(-?\d+)/i;
|
|
1295
|
+
|
|
1296
|
+
function isCookieDeletion(header: string): boolean {
|
|
1297
|
+
const m = MAX_AGE_RE.exec(header);
|
|
1298
|
+
if (!m) return false;
|
|
1299
|
+
return Number(m[1]) <= 0;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
function parseResponseCookies(response: Response): Map<string, string | null> {
|
|
1303
|
+
const result = new Map<string, string | null>();
|
|
1304
|
+
const setCookies = response.headers.getSetCookie();
|
|
1305
|
+
|
|
1306
|
+
for (const header of setCookies) {
|
|
1307
|
+
const semiIdx = header.indexOf(";");
|
|
1308
|
+
const pair = semiIdx === -1 ? header : header.substring(0, semiIdx);
|
|
1309
|
+
const eqIdx = pair.indexOf("=");
|
|
1310
|
+
if (eqIdx === -1) continue;
|
|
1311
|
+
|
|
1312
|
+
let name: string;
|
|
1313
|
+
let value: string;
|
|
1314
|
+
try {
|
|
1315
|
+
name = decodeURIComponent(pair.substring(0, eqIdx).trim());
|
|
1316
|
+
value = decodeURIComponent(pair.substring(eqIdx + 1).trim());
|
|
1317
|
+
} catch {
|
|
1318
|
+
continue;
|
|
423
1319
|
}
|
|
1320
|
+
|
|
1321
|
+
const isDeleted = isCookieDeletion(header);
|
|
1322
|
+
result.set(name, isDeleted ? null : value);
|
|
424
1323
|
}
|
|
425
1324
|
|
|
426
|
-
return
|
|
1325
|
+
return result;
|
|
427
1326
|
}
|
|
428
1327
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
1328
|
+
// Re-exported for unit tests and the existing import path. The implementation
|
|
1329
|
+
// lives in the dependency-free ./cookie-parse leaf so consumers (e.g. the host
|
|
1330
|
+
// dispatcher) can share it without pulling this module's request-context graph.
|
|
1331
|
+
export { parseCookiesFromHeader };
|
|
1332
|
+
|
|
1333
|
+
export function serializeCookieValue(
|
|
433
1334
|
name: string,
|
|
434
1335
|
value: string,
|
|
435
|
-
options: CookieOptions = {}
|
|
1336
|
+
options: CookieOptions = {},
|
|
436
1337
|
): string {
|
|
437
1338
|
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
438
1339
|
|
|
@@ -456,20 +1357,12 @@ export interface CreateUseFunctionOptions<TEnv> {
|
|
|
456
1357
|
getContext: () => RequestContext<TEnv>;
|
|
457
1358
|
}
|
|
458
1359
|
|
|
459
|
-
/**
|
|
460
|
-
* Create the use() function for loader and handle composition.
|
|
461
|
-
*
|
|
462
|
-
* This is the unified implementation used by both RequestContext and HandlerContext.
|
|
463
|
-
* - For loaders: executes and memoizes loader functions
|
|
464
|
-
* - For handles: returns a push function to add handle data
|
|
465
|
-
*/
|
|
466
1360
|
export function createUseFunction<TEnv>(
|
|
467
|
-
options: CreateUseFunctionOptions<TEnv
|
|
1361
|
+
options: CreateUseFunctionOptions<TEnv>,
|
|
468
1362
|
): RequestContext["use"] {
|
|
469
1363
|
const { handleStore, loaderPromises, getContext } = options;
|
|
470
1364
|
|
|
471
1365
|
return ((item: LoaderDefinition<any, any> | Handle<any, any>) => {
|
|
472
|
-
// Handle case: return a push function
|
|
473
1366
|
if (isHandle(item)) {
|
|
474
1367
|
const handle = item;
|
|
475
1368
|
const ctx = getContext();
|
|
@@ -478,31 +1371,28 @@ export function createUseFunction<TEnv>(
|
|
|
478
1371
|
if (!segmentId) {
|
|
479
1372
|
throw new Error(
|
|
480
1373
|
`Handle "${handle.$$id}" used outside of handler context. ` +
|
|
481
|
-
`Handles must be used within route/layout handlers
|
|
1374
|
+
`Handles must be used within route/layout handlers.`,
|
|
482
1375
|
);
|
|
483
1376
|
}
|
|
484
1377
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
1378
|
+
return withDefer(
|
|
1379
|
+
(dataOrFn: unknown | Promise<unknown> | (() => Promise<unknown>)) => {
|
|
1380
|
+
const valueOrPromise =
|
|
1381
|
+
typeof dataOrFn === "function"
|
|
1382
|
+
? (dataOrFn as () => Promise<unknown>)()
|
|
1383
|
+
: dataOrFn;
|
|
491
1384
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
1385
|
+
handleStore.push(handle.$$id, segmentId, valueOrPromise);
|
|
1386
|
+
},
|
|
1387
|
+
);
|
|
495
1388
|
}
|
|
496
1389
|
|
|
497
|
-
// Loader case
|
|
498
1390
|
const loader = item as LoaderDefinition<any, any>;
|
|
499
1391
|
|
|
500
|
-
// Return cached promise if already started
|
|
501
1392
|
if (loaderPromises.has(loader.$$id)) {
|
|
502
1393
|
return loaderPromises.get(loader.$$id);
|
|
503
1394
|
}
|
|
504
1395
|
|
|
505
|
-
// Get loader function - either from loader object or fetchable registry
|
|
506
1396
|
let loaderFn = loader.fn;
|
|
507
1397
|
if (!loaderFn) {
|
|
508
1398
|
const fetchable = getFetchableLoader(loader.$$id);
|
|
@@ -513,39 +1403,66 @@ export function createUseFunction<TEnv>(
|
|
|
513
1403
|
|
|
514
1404
|
if (!loaderFn) {
|
|
515
1405
|
throw new Error(
|
|
516
|
-
`Loader "${loader.$$id}" has no function. This usually means the loader was defined without "use server" and the function was not included in the build
|
|
1406
|
+
`Loader "${loader.$$id}" has no function. This usually means the loader was defined without "use server" and the function was not included in the build.`,
|
|
517
1407
|
);
|
|
518
1408
|
}
|
|
519
1409
|
|
|
520
1410
|
const ctx = getContext();
|
|
521
1411
|
|
|
522
|
-
//
|
|
1412
|
+
// Build the typed ctx.search the same way the render path
|
|
1413
|
+
// (createHandlerContext) and the fetchable-loader path (loader-fetch.ts) do:
|
|
1414
|
+
// parse the route's search schema over the cleaned searchParams. The base
|
|
1415
|
+
// RequestContext carries no `search` field, so reading `(ctx as any).search`
|
|
1416
|
+
// here always yielded {} — dropping typed search for action/dispatch loaders.
|
|
1417
|
+
const searchSchema = ctx._routeName
|
|
1418
|
+
? getSearchSchema(ctx._routeName)
|
|
1419
|
+
: undefined;
|
|
1420
|
+
const loaderSearch = searchSchema
|
|
1421
|
+
? parseSearchParams(ctx.searchParams, searchSchema)
|
|
1422
|
+
: {};
|
|
1423
|
+
|
|
523
1424
|
const loaderCtx: LoaderContext<Record<string, string | undefined>, TEnv> = {
|
|
524
1425
|
params: ctx.params,
|
|
1426
|
+
routeParams: (ctx.params ?? {}) as Record<string, string>,
|
|
525
1427
|
request: ctx.request,
|
|
526
1428
|
searchParams: ctx.searchParams,
|
|
1429
|
+
search: loaderSearch,
|
|
527
1430
|
pathname: ctx.pathname,
|
|
528
1431
|
url: ctx.url,
|
|
1432
|
+
originalUrl: ctx.originalUrl,
|
|
529
1433
|
env: ctx.env as any,
|
|
530
|
-
|
|
1434
|
+
waitUntil: ctx.waitUntil.bind(ctx),
|
|
1435
|
+
executionContext: ctx.executionContext,
|
|
531
1436
|
get: ctx.get as any,
|
|
532
|
-
use: <TDep, TDepParams = any>(
|
|
533
|
-
dep: LoaderDefinition<TDep, TDepParams
|
|
1437
|
+
use: (<TDep, TDepParams = any>(
|
|
1438
|
+
dep: LoaderDefinition<TDep, TDepParams>,
|
|
534
1439
|
): Promise<TDep> => {
|
|
535
|
-
// Recursive call - will start dep loader if not already started
|
|
536
1440
|
return ctx.use(dep);
|
|
537
|
-
},
|
|
1441
|
+
}) as LoaderContext["use"],
|
|
538
1442
|
method: "GET",
|
|
539
1443
|
body: undefined,
|
|
1444
|
+
reverse: createReverseFunction(
|
|
1445
|
+
getGlobalRouteMap(),
|
|
1446
|
+
ctx._routeName,
|
|
1447
|
+
ctx.params as Record<string, string>,
|
|
1448
|
+
ctx._routeName ? isRouteRootScoped(ctx._routeName) : undefined,
|
|
1449
|
+
),
|
|
1450
|
+
rendered: () => {
|
|
1451
|
+
throw new Error(
|
|
1452
|
+
`ctx.rendered() is only available in DSL loaders (registered via loader() in urls()). ` +
|
|
1453
|
+
`It cannot be used from request-context loaders or server actions.`,
|
|
1454
|
+
);
|
|
1455
|
+
},
|
|
540
1456
|
};
|
|
541
1457
|
|
|
542
|
-
//
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
1458
|
+
// Meter through the same unified phase API as the loader-resolution funnel
|
|
1459
|
+
// (observePhase), so a loader resolved via this base request-context ctx.use
|
|
1460
|
+
// co-emits the "loader:<id>" perf metric AND the "rango.loader" span — no
|
|
1461
|
+
// drift between the two ctx.use implementations.
|
|
1462
|
+
const promise = observePhase(PHASES.loader(loader.$$id), () =>
|
|
1463
|
+
Promise.resolve(loaderFn(loaderCtx)),
|
|
1464
|
+
);
|
|
547
1465
|
|
|
548
|
-
// Memoize for subsequent calls
|
|
549
1466
|
loaderPromises.set(loader.$$id, promise);
|
|
550
1467
|
|
|
551
1468
|
return promise;
|