@rangojs/router 0.0.0-experimental.125 → 0.0.0-experimental.127
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/README.md +6 -4
- package/dist/__internal.d.ts +83 -0
- package/dist/__internal.d.ts.map +1 -0
- package/dist/__internal.js +19 -0
- package/dist/__internal.js.map +1 -0
- package/dist/__mocks__/version.d.ts +7 -0
- package/dist/__mocks__/version.d.ts.map +1 -0
- package/dist/__mocks__/version.js +7 -0
- package/dist/__mocks__/version.js.map +1 -0
- package/dist/__tests__/client-href.test.d.ts +2 -0
- package/dist/__tests__/client-href.test.d.ts.map +1 -0
- package/dist/__tests__/client-href.test.js +74 -0
- package/dist/__tests__/client-href.test.js.map +1 -0
- package/dist/__tests__/component-utils.test.d.ts +2 -0
- package/dist/__tests__/component-utils.test.d.ts.map +1 -0
- package/dist/__tests__/component-utils.test.js +51 -0
- package/dist/__tests__/component-utils.test.js.map +1 -0
- package/dist/__tests__/event-controller.test.d.ts +2 -0
- package/dist/__tests__/event-controller.test.d.ts.map +1 -0
- package/dist/__tests__/event-controller.test.js +538 -0
- package/dist/__tests__/event-controller.test.js.map +1 -0
- package/dist/__tests__/helpers/route-tree.d.ts +118 -0
- package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
- package/dist/__tests__/helpers/route-tree.js +374 -0
- package/dist/__tests__/helpers/route-tree.js.map +1 -0
- package/dist/__tests__/match-result.test.d.ts +2 -0
- package/dist/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/__tests__/match-result.test.js +154 -0
- package/dist/__tests__/match-result.test.js.map +1 -0
- package/dist/__tests__/navigation-store.test.d.ts +2 -0
- package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
- package/dist/__tests__/navigation-store.test.js +440 -0
- package/dist/__tests__/navigation-store.test.js.map +1 -0
- package/dist/__tests__/partial-update.test.d.ts +2 -0
- package/dist/__tests__/partial-update.test.d.ts.map +1 -0
- package/dist/__tests__/partial-update.test.js +1009 -0
- package/dist/__tests__/partial-update.test.js.map +1 -0
- package/dist/__tests__/reverse-types.test.d.ts +8 -0
- package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-types.test.js +656 -0
- package/dist/__tests__/reverse-types.test.js.map +1 -0
- package/dist/__tests__/route-definition.test.d.ts +2 -0
- package/dist/__tests__/route-definition.test.d.ts.map +1 -0
- package/dist/__tests__/route-definition.test.js +55 -0
- package/dist/__tests__/route-definition.test.js.map +1 -0
- package/dist/__tests__/router-helpers.test.d.ts +2 -0
- package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/router-helpers.test.js +377 -0
- package/dist/__tests__/router-helpers.test.js.map +1 -0
- package/dist/__tests__/router-integration-2.test.d.ts +2 -0
- package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration-2.test.js +426 -0
- package/dist/__tests__/router-integration-2.test.js.map +1 -0
- package/dist/__tests__/router-integration.test.d.ts +2 -0
- package/dist/__tests__/router-integration.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration.test.js +1051 -0
- package/dist/__tests__/router-integration.test.js.map +1 -0
- package/dist/__tests__/search-params.test.d.ts +5 -0
- package/dist/__tests__/search-params.test.d.ts.map +1 -0
- package/dist/__tests__/search-params.test.js +306 -0
- package/dist/__tests__/search-params.test.js.map +1 -0
- package/dist/__tests__/segment-system.test.d.ts +2 -0
- package/dist/__tests__/segment-system.test.d.ts.map +1 -0
- package/dist/__tests__/segment-system.test.js +627 -0
- package/dist/__tests__/segment-system.test.js.map +1 -0
- package/dist/__tests__/static-handler-types.test.d.ts +8 -0
- package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
- package/dist/__tests__/static-handler-types.test.js +63 -0
- package/dist/__tests__/static-handler-types.test.js.map +1 -0
- package/dist/__tests__/urls.test.d.ts +2 -0
- package/dist/__tests__/urls.test.d.ts.map +1 -0
- package/dist/__tests__/urls.test.js +421 -0
- package/dist/__tests__/urls.test.js.map +1 -0
- package/dist/__tests__/use-mount.test.d.ts +2 -0
- package/dist/__tests__/use-mount.test.d.ts.map +1 -0
- package/dist/__tests__/use-mount.test.js +35 -0
- package/dist/__tests__/use-mount.test.js.map +1 -0
- package/dist/bin/rango.d.ts +2 -0
- package/dist/bin/rango.d.ts.map +1 -0
- package/dist/bin/rango.js +5 -1
- package/dist/bin/rango.js.map +1 -0
- package/dist/browser/event-controller.d.ts +191 -0
- package/dist/browser/event-controller.d.ts.map +1 -0
- package/dist/browser/event-controller.js +559 -0
- package/dist/browser/event-controller.js.map +1 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/link-interceptor.d.ts +38 -0
- package/dist/browser/link-interceptor.d.ts.map +1 -0
- package/dist/browser/link-interceptor.js +99 -0
- package/dist/browser/link-interceptor.js.map +1 -0
- package/dist/browser/logging.d.ts +10 -0
- package/dist/browser/logging.d.ts.map +1 -0
- package/dist/browser/logging.js +29 -0
- package/dist/browser/logging.js.map +1 -0
- package/dist/browser/lru-cache.d.ts +17 -0
- package/dist/browser/lru-cache.d.ts.map +1 -0
- package/dist/browser/lru-cache.js +50 -0
- package/dist/browser/lru-cache.js.map +1 -0
- package/dist/browser/merge-segment-loaders.d.ts +39 -0
- package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
- package/dist/browser/merge-segment-loaders.js +102 -0
- package/dist/browser/merge-segment-loaders.js.map +1 -0
- package/dist/browser/navigation-bridge.d.ts +102 -0
- package/dist/browser/navigation-bridge.d.ts.map +1 -0
- package/dist/browser/navigation-bridge.js +708 -0
- package/dist/browser/navigation-bridge.js.map +1 -0
- package/dist/browser/navigation-client.d.ts +25 -0
- package/dist/browser/navigation-client.d.ts.map +1 -0
- package/dist/browser/navigation-client.js +157 -0
- package/dist/browser/navigation-client.js.map +1 -0
- package/dist/browser/navigation-store.d.ts +101 -0
- package/dist/browser/navigation-store.d.ts.map +1 -0
- package/dist/browser/navigation-store.js +625 -0
- package/dist/browser/navigation-store.js.map +1 -0
- package/dist/browser/partial-update.d.ts +75 -0
- package/dist/browser/partial-update.d.ts.map +1 -0
- package/dist/browser/partial-update.js +426 -0
- package/dist/browser/partial-update.js.map +1 -0
- package/dist/browser/react/Link.d.ts +86 -0
- package/dist/browser/react/Link.d.ts.map +1 -0
- package/dist/browser/react/Link.js +128 -0
- package/dist/browser/react/Link.js.map +1 -0
- package/dist/browser/react/NavigationProvider.d.ts +63 -0
- package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
- package/dist/browser/react/NavigationProvider.js +216 -0
- package/dist/browser/react/NavigationProvider.js.map +1 -0
- package/dist/browser/react/ScrollRestoration.d.ts +75 -0
- package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
- package/dist/browser/react/ScrollRestoration.js +57 -0
- package/dist/browser/react/ScrollRestoration.js.map +1 -0
- package/dist/browser/react/context.d.ts +46 -0
- package/dist/browser/react/context.d.ts.map +1 -0
- package/dist/browser/react/context.js +10 -0
- package/dist/browser/react/context.js.map +1 -0
- package/dist/browser/react/index.d.ts +11 -0
- package/dist/browser/react/index.d.ts.map +1 -0
- package/dist/browser/react/index.js +22 -0
- package/dist/browser/react/index.js.map +1 -0
- package/dist/browser/react/location-state-shared.d.ts +63 -0
- package/dist/browser/react/location-state-shared.d.ts.map +1 -0
- package/dist/browser/react/location-state-shared.js +81 -0
- package/dist/browser/react/location-state-shared.js.map +1 -0
- package/dist/browser/react/location-state.d.ts +23 -0
- package/dist/browser/react/location-state.d.ts.map +1 -0
- package/dist/browser/react/location-state.js +29 -0
- package/dist/browser/react/location-state.js.map +1 -0
- package/dist/browser/react/mount-context.d.ts +24 -0
- package/dist/browser/react/mount-context.d.ts.map +1 -0
- package/dist/browser/react/mount-context.js +24 -0
- package/dist/browser/react/mount-context.js.map +1 -0
- package/dist/browser/react/use-action.d.ts +64 -0
- package/dist/browser/react/use-action.d.ts.map +1 -0
- package/dist/browser/react/use-action.js +134 -0
- package/dist/browser/react/use-action.js.map +1 -0
- package/dist/browser/react/use-client-cache.d.ts +41 -0
- package/dist/browser/react/use-client-cache.d.ts.map +1 -0
- package/dist/browser/react/use-client-cache.js +39 -0
- package/dist/browser/react/use-client-cache.js.map +1 -0
- package/dist/browser/react/use-handle.d.ts +31 -0
- package/dist/browser/react/use-handle.d.ts.map +1 -0
- package/dist/browser/react/use-handle.js +144 -0
- package/dist/browser/react/use-handle.js.map +1 -0
- package/dist/browser/react/use-href.d.ts +33 -0
- package/dist/browser/react/use-href.d.ts.map +1 -0
- package/dist/browser/react/use-href.js +39 -0
- package/dist/browser/react/use-href.js.map +1 -0
- package/dist/browser/react/use-link-status.d.ts +37 -0
- package/dist/browser/react/use-link-status.d.ts.map +1 -0
- package/dist/browser/react/use-link-status.js +99 -0
- package/dist/browser/react/use-link-status.js.map +1 -0
- package/dist/browser/react/use-mount.d.ts +25 -0
- package/dist/browser/react/use-mount.d.ts.map +1 -0
- package/dist/browser/react/use-mount.js +30 -0
- package/dist/browser/react/use-mount.js.map +1 -0
- package/dist/browser/react/use-navigation.d.ts +27 -0
- package/dist/browser/react/use-navigation.d.ts.map +1 -0
- package/dist/browser/react/use-navigation.js +87 -0
- package/dist/browser/react/use-navigation.js.map +1 -0
- package/dist/browser/react/use-segments.d.ts +38 -0
- package/dist/browser/react/use-segments.d.ts.map +1 -0
- package/dist/browser/react/use-segments.js +130 -0
- package/dist/browser/react/use-segments.js.map +1 -0
- package/dist/browser/request-controller.d.ts +26 -0
- package/dist/browser/request-controller.d.ts.map +1 -0
- package/dist/browser/request-controller.js +147 -0
- package/dist/browser/request-controller.js.map +1 -0
- package/dist/browser/rsc-router.d.ts +129 -0
- package/dist/browser/rsc-router.d.ts.map +1 -0
- package/dist/browser/rsc-router.js +195 -0
- package/dist/browser/rsc-router.js.map +1 -0
- package/dist/browser/scroll-restoration.d.ts +93 -0
- package/dist/browser/scroll-restoration.d.ts.map +1 -0
- package/dist/browser/scroll-restoration.js +321 -0
- package/dist/browser/scroll-restoration.js.map +1 -0
- package/dist/browser/segment-structure-assert.d.ts +17 -0
- package/dist/browser/segment-structure-assert.d.ts.map +1 -0
- package/dist/browser/segment-structure-assert.js +59 -0
- package/dist/browser/segment-structure-assert.js.map +1 -0
- package/dist/browser/server-action-bridge.d.ts +26 -0
- package/dist/browser/server-action-bridge.d.ts.map +1 -0
- package/dist/browser/server-action-bridge.js +668 -0
- package/dist/browser/server-action-bridge.js.map +1 -0
- package/dist/browser/shallow.d.ts +12 -0
- package/dist/browser/shallow.d.ts.map +1 -0
- package/dist/browser/shallow.js +34 -0
- package/dist/browser/shallow.js.map +1 -0
- package/dist/browser/types.d.ts +369 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
- package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-cli.test.js +237 -0
- package/dist/build/__tests__/generate-cli.test.js.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.js +119 -0
- package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.js +620 -0
- package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.js +308 -0
- package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +81 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +276 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/build/generate-route-types.d.ts +115 -0
- package/dist/build/generate-route-types.d.ts.map +1 -0
- package/dist/build/generate-route-types.js +740 -0
- package/dist/build/generate-route-types.js.map +1 -0
- package/dist/build/index.d.ts +21 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +21 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/route-trie.d.ts +71 -0
- package/dist/build/route-trie.d.ts.map +1 -0
- package/dist/build/route-trie.js +175 -0
- package/dist/build/route-trie.js.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.js +208 -0
- package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
- package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
- package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
- package/dist/cache/__tests__/document-cache.test.js +345 -0
- package/dist/cache/__tests__/document-cache.test.js.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
- package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
- package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-store.test.js +367 -0
- package/dist/cache/__tests__/memory-store.test.js.map +1 -0
- package/dist/cache/cache-scope.d.ts +102 -0
- package/dist/cache/cache-scope.d.ts.map +1 -0
- package/dist/cache/cache-scope.js +440 -0
- package/dist/cache/cache-scope.js.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
- package/dist/cache/cf/cf-cache-store.d.ts +165 -0
- package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
- package/dist/cache/cf/cf-cache-store.js +242 -0
- package/dist/cache/cf/cf-cache-store.js.map +1 -0
- package/dist/cache/cf/index.d.ts +14 -0
- package/dist/cache/cf/index.d.ts.map +1 -0
- package/dist/cache/cf/index.js +17 -0
- package/dist/cache/cf/index.js.map +1 -0
- package/dist/cache/document-cache.d.ts +64 -0
- package/dist/cache/document-cache.d.ts.map +1 -0
- package/dist/cache/document-cache.js +228 -0
- package/dist/cache/document-cache.js.map +1 -0
- package/dist/cache/index.d.ts +19 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +21 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory-segment-store.d.ts +110 -0
- package/dist/cache/memory-segment-store.d.ts.map +1 -0
- package/dist/cache/memory-segment-store.js +117 -0
- package/dist/cache/memory-segment-store.js.map +1 -0
- package/dist/cache/memory-store.d.ts +41 -0
- package/dist/cache/memory-store.d.ts.map +1 -0
- package/dist/cache/memory-store.js +191 -0
- package/dist/cache/memory-store.js.map +1 -0
- package/dist/cache/types.d.ts +317 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +12 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/client.d.ts +248 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/client.rsc.d.ts +26 -0
- package/dist/client.rsc.d.ts.map +1 -0
- package/dist/client.rsc.js +46 -0
- package/dist/client.rsc.js.map +1 -0
- package/dist/component-utils.d.ts +36 -0
- package/dist/component-utils.d.ts.map +1 -0
- package/dist/component-utils.js +61 -0
- package/dist/component-utils.js.map +1 -0
- package/dist/components/DefaultDocument.d.ts +13 -0
- package/dist/components/DefaultDocument.d.ts.map +1 -0
- package/dist/components/DefaultDocument.js +15 -0
- package/dist/components/DefaultDocument.js.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +157 -0
- package/dist/debug.js.map +1 -0
- package/dist/default-error-boundary.d.ts +11 -0
- package/dist/default-error-boundary.d.ts.map +1 -0
- package/dist/default-error-boundary.js +45 -0
- package/dist/default-error-boundary.js.map +1 -0
- package/dist/deps/browser.d.ts +2 -0
- package/dist/deps/browser.d.ts.map +1 -0
- package/dist/deps/browser.js +3 -0
- package/dist/deps/browser.js.map +1 -0
- package/dist/deps/html-stream-client.d.ts +2 -0
- package/dist/deps/html-stream-client.d.ts.map +1 -0
- package/dist/deps/html-stream-client.js +3 -0
- package/dist/deps/html-stream-client.js.map +1 -0
- package/dist/deps/html-stream-server.d.ts +2 -0
- package/dist/deps/html-stream-server.d.ts.map +1 -0
- package/dist/deps/html-stream-server.js +3 -0
- package/dist/deps/html-stream-server.js.map +1 -0
- package/dist/deps/rsc.d.ts +2 -0
- package/dist/deps/rsc.d.ts.map +1 -0
- package/dist/deps/rsc.js +4 -0
- package/dist/deps/rsc.js.map +1 -0
- package/dist/deps/ssr.d.ts +2 -0
- package/dist/deps/ssr.d.ts.map +1 -0
- package/dist/deps/ssr.js +3 -0
- package/dist/deps/ssr.js.map +1 -0
- package/dist/errors.d.ts +174 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/handle.d.ts +78 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +82 -0
- package/dist/handle.js.map +1 -0
- package/dist/handles/MetaTags.d.ts +14 -0
- package/dist/handles/MetaTags.d.ts.map +1 -0
- package/dist/handles/MetaTags.js +136 -0
- package/dist/handles/MetaTags.js.map +1 -0
- package/{src/handles/index.ts → dist/handles/index.d.ts} +1 -2
- package/dist/handles/index.d.ts.map +1 -0
- package/dist/handles/index.js +6 -0
- package/dist/handles/index.js.map +1 -0
- package/dist/handles/meta.d.ts +39 -0
- package/dist/handles/meta.d.ts.map +1 -0
- package/dist/handles/meta.js +202 -0
- package/dist/handles/meta.js.map +1 -0
- package/dist/host/__tests__/errors.test.d.ts +2 -0
- package/dist/host/__tests__/errors.test.d.ts.map +1 -0
- package/dist/host/__tests__/errors.test.js +76 -0
- package/dist/host/__tests__/errors.test.js.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.js +251 -0
- package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/host/__tests__/router.test.d.ts +2 -0
- package/dist/host/__tests__/router.test.d.ts.map +1 -0
- package/dist/host/__tests__/router.test.js +241 -0
- package/dist/host/__tests__/router.test.js.map +1 -0
- package/dist/host/__tests__/testing.test.d.ts +2 -0
- package/dist/host/__tests__/testing.test.d.ts.map +1 -0
- package/dist/host/__tests__/testing.test.js +64 -0
- package/dist/host/__tests__/testing.test.js.map +1 -0
- package/dist/host/__tests__/utils.test.d.ts +2 -0
- package/dist/host/__tests__/utils.test.d.ts.map +1 -0
- package/dist/host/__tests__/utils.test.js +29 -0
- package/dist/host/__tests__/utils.test.js.map +1 -0
- package/dist/host/cookie-handler.d.ts +34 -0
- package/dist/host/cookie-handler.d.ts.map +1 -0
- package/dist/host/cookie-handler.js +124 -0
- package/dist/host/cookie-handler.js.map +1 -0
- package/dist/host/errors.d.ts +56 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +79 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +32 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pattern-matcher.d.ts +36 -0
- package/dist/host/pattern-matcher.d.ts.map +1 -0
- package/dist/host/pattern-matcher.js +172 -0
- package/dist/host/pattern-matcher.js.map +1 -0
- package/dist/host/router.d.ts +26 -0
- package/dist/host/router.d.ts.map +1 -0
- package/dist/host/router.js +218 -0
- package/dist/host/router.js.map +1 -0
- package/dist/host/testing.d.ts +36 -0
- package/dist/host/testing.d.ts.map +1 -0
- package/dist/host/testing.js +55 -0
- package/dist/host/testing.js.map +1 -0
- package/dist/host/types.d.ts +115 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/host/utils.d.ts +21 -0
- package/dist/host/utils.d.ts.map +1 -0
- package/dist/host/utils.js +23 -0
- package/dist/host/utils.js.map +1 -0
- package/dist/href-client.d.ts +131 -0
- package/dist/href-client.d.ts.map +1 -0
- package/dist/href-client.js +64 -0
- package/dist/href-client.js.map +1 -0
- package/dist/href-context.d.ts +29 -0
- package/dist/href-context.d.ts.map +1 -0
- package/dist/href-context.js +21 -0
- package/dist/href-context.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/index.rsc.d.ts +32 -0
- package/dist/index.rsc.d.ts.map +1 -0
- package/dist/index.rsc.js +40 -0
- package/dist/index.rsc.js.map +1 -0
- package/dist/internal-debug.d.ts +2 -0
- package/dist/internal-debug.d.ts.map +1 -0
- package/dist/internal-debug.js +5 -0
- package/dist/internal-debug.js.map +1 -0
- package/dist/loader.d.ts +14 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +20 -0
- package/dist/loader.js.map +1 -0
- package/dist/loader.rsc.d.ts +19 -0
- package/dist/loader.rsc.d.ts.map +1 -0
- package/dist/loader.rsc.js +99 -0
- package/dist/loader.rsc.js.map +1 -0
- package/dist/network-error-thrower.d.ts +17 -0
- package/dist/network-error-thrower.d.ts.map +1 -0
- package/dist/network-error-thrower.js +14 -0
- package/dist/network-error-thrower.js.map +1 -0
- package/dist/outlet-context.d.ts +13 -0
- package/dist/outlet-context.d.ts.map +1 -0
- package/dist/outlet-context.js +3 -0
- package/dist/outlet-context.js.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.js +148 -0
- package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
- package/dist/prerender/param-hash.d.ts +16 -0
- package/dist/prerender/param-hash.d.ts.map +1 -0
- package/dist/prerender/param-hash.js +36 -0
- package/dist/prerender/param-hash.js.map +1 -0
- package/dist/prerender/store.d.ts +38 -0
- package/dist/prerender/store.d.ts.map +1 -0
- package/dist/prerender/store.js +61 -0
- package/dist/prerender/store.js.map +1 -0
- package/dist/prerender.d.ts +66 -0
- package/dist/prerender.d.ts.map +1 -0
- package/dist/prerender.js +57 -0
- package/dist/prerender.js.map +1 -0
- package/dist/reverse.d.ts +196 -0
- package/dist/reverse.d.ts.map +1 -0
- package/dist/reverse.js +78 -0
- package/dist/reverse.js.map +1 -0
- package/dist/root-error-boundary.d.ts +33 -0
- package/dist/root-error-boundary.d.ts.map +1 -0
- package/dist/root-error-boundary.js +165 -0
- package/dist/root-error-boundary.js.map +1 -0
- package/dist/route-content-wrapper.d.ts +46 -0
- package/dist/route-content-wrapper.d.ts.map +1 -0
- package/dist/route-content-wrapper.js +77 -0
- package/dist/route-content-wrapper.js.map +1 -0
- package/dist/route-definition.d.ts +421 -0
- package/dist/route-definition.d.ts.map +1 -0
- package/dist/route-definition.js +868 -0
- package/dist/route-definition.js.map +1 -0
- package/dist/route-map-builder.d.ts +155 -0
- package/dist/route-map-builder.d.ts.map +1 -0
- package/dist/route-map-builder.js +237 -0
- package/dist/route-map-builder.js.map +1 -0
- package/dist/route-types.d.ts +165 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +7 -0
- package/dist/route-types.js.map +1 -0
- package/dist/router/__tests__/handler-context.test.d.ts +2 -0
- package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/handler-context.test.js +65 -0
- package/dist/router/__tests__/handler-context.test.js.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
- package/dist/router/__tests__/match-context.test.d.ts +2 -0
- package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-context.test.js +92 -0
- package/dist/router/__tests__/match-context.test.js.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.js +417 -0
- package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
- package/dist/router/__tests__/match-result.test.d.ts +2 -0
- package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-result.test.js +457 -0
- package/dist/router/__tests__/match-result.test.js.map +1 -0
- package/dist/router/__tests__/on-error.test.d.ts +2 -0
- package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
- package/dist/router/__tests__/on-error.test.js +678 -0
- package/dist/router/__tests__/on-error.test.js.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.js +629 -0
- package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
- package/dist/router/error-handling.d.ts +77 -0
- package/dist/router/error-handling.d.ts.map +1 -0
- package/dist/router/error-handling.js +202 -0
- package/dist/router/error-handling.js.map +1 -0
- package/dist/router/handler-context.d.ts +20 -0
- package/dist/router/handler-context.d.ts.map +1 -0
- package/dist/router/handler-context.js +198 -0
- package/dist/router/handler-context.js.map +1 -0
- package/dist/router/intercept-resolution.d.ts +66 -0
- package/dist/router/intercept-resolution.d.ts.map +1 -0
- package/dist/router/intercept-resolution.js +246 -0
- package/dist/router/intercept-resolution.js.map +1 -0
- package/dist/router/loader-resolution.d.ts +64 -0
- package/dist/router/loader-resolution.d.ts.map +1 -0
- package/dist/router/loader-resolution.js +284 -0
- package/dist/router/loader-resolution.js.map +1 -0
- package/dist/router/logging.d.ts +15 -0
- package/dist/router/logging.d.ts.map +1 -0
- package/dist/router/logging.js +99 -0
- package/dist/router/logging.js.map +1 -0
- package/dist/router/manifest.d.ts +22 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +181 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/router/match-api.d.ts +35 -0
- package/dist/router/match-api.d.ts.map +1 -0
- package/dist/router/match-api.js +406 -0
- package/dist/router/match-api.js.map +1 -0
- package/dist/router/match-context.d.ts +206 -0
- package/dist/router/match-context.d.ts.map +1 -0
- package/dist/router/match-context.js +17 -0
- package/dist/router/match-context.js.map +1 -0
- package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
- package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
- package/dist/router/match-middleware/background-revalidation.js +75 -0
- package/dist/router/match-middleware/background-revalidation.js.map +1 -0
- package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
- package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-lookup.js +257 -0
- package/dist/router/match-middleware/cache-lookup.js.map +1 -0
- package/dist/router/match-middleware/cache-store.d.ts +113 -0
- package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-store.js +108 -0
- package/dist/router/match-middleware/cache-store.js.map +1 -0
- package/dist/router/match-middleware/index.d.ts +81 -0
- package/dist/router/match-middleware/index.d.ts.map +1 -0
- package/dist/router/match-middleware/index.js +80 -0
- package/dist/router/match-middleware/index.js.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.js +134 -0
- package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
- package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
- package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/segment-resolution.js +53 -0
- package/dist/router/match-middleware/segment-resolution.js.map +1 -0
- package/dist/router/match-pipelines.d.ts +147 -0
- package/dist/router/match-pipelines.d.ts.map +1 -0
- package/dist/router/match-pipelines.js +82 -0
- package/dist/router/match-pipelines.js.map +1 -0
- package/dist/router/match-result.d.ts +126 -0
- package/dist/router/match-result.d.ts.map +1 -0
- package/dist/router/match-result.js +93 -0
- package/dist/router/match-result.js.map +1 -0
- package/dist/router/metrics.d.ts +20 -0
- package/dist/router/metrics.d.ts.map +1 -0
- package/dist/router/metrics.js +47 -0
- package/dist/router/metrics.js.map +1 -0
- package/dist/router/middleware.d.ts +249 -0
- package/dist/router/middleware.d.ts.map +1 -0
- package/dist/router/middleware.js +434 -0
- package/dist/router/middleware.js.map +1 -0
- package/dist/router/middleware.test.d.ts +2 -0
- package/dist/router/middleware.test.d.ts.map +1 -0
- package/dist/router/middleware.test.js +816 -0
- package/dist/router/middleware.test.js.map +1 -0
- package/dist/router/pattern-matching.d.ts +149 -0
- package/dist/router/pattern-matching.d.ts.map +1 -0
- package/dist/router/pattern-matching.js +349 -0
- package/dist/router/pattern-matching.js.map +1 -0
- package/dist/router/revalidation.d.ts +44 -0
- package/dist/router/revalidation.d.ts.map +1 -0
- package/dist/router/revalidation.js +147 -0
- package/dist/router/revalidation.js.map +1 -0
- package/dist/router/router-context.d.ts +135 -0
- package/dist/router/router-context.d.ts.map +1 -0
- package/dist/router/router-context.js +36 -0
- package/dist/router/router-context.js.map +1 -0
- package/dist/router/segment-resolution.d.ts +127 -0
- package/dist/router/segment-resolution.d.ts.map +1 -0
- package/dist/router/segment-resolution.js +919 -0
- package/dist/router/segment-resolution.js.map +1 -0
- package/dist/router/trie-matching.d.ts +40 -0
- package/dist/router/trie-matching.d.ts.map +1 -0
- package/dist/router/trie-matching.js +127 -0
- package/dist/router/trie-matching.js.map +1 -0
- package/dist/router/types.d.ts +136 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +7 -0
- package/dist/router/types.js.map +1 -0
- package/dist/router.d.ts +753 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.gen.d.ts +6 -0
- package/dist/router.gen.d.ts.map +1 -0
- package/dist/router.gen.js +6 -0
- package/dist/router.gen.js.map +1 -0
- package/dist/router.js +1304 -0
- package/dist/router.js.map +1 -0
- package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
- package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
- package/dist/rsc/__tests__/helpers.test.js +140 -0
- package/dist/rsc/__tests__/helpers.test.js.map +1 -0
- package/dist/rsc/handler.d.ts +45 -0
- package/dist/rsc/handler.d.ts.map +1 -0
- package/dist/rsc/handler.js +1172 -0
- package/dist/rsc/handler.js.map +1 -0
- package/dist/rsc/helpers.d.ts +16 -0
- package/dist/rsc/helpers.d.ts.map +1 -0
- package/dist/rsc/helpers.js +55 -0
- package/dist/rsc/helpers.js.map +1 -0
- package/dist/rsc/index.d.ts +22 -0
- package/dist/rsc/index.d.ts.map +1 -0
- package/dist/rsc/index.js +23 -0
- package/dist/rsc/index.js.map +1 -0
- package/dist/rsc/nonce.d.ts +9 -0
- package/dist/rsc/nonce.d.ts.map +1 -0
- package/dist/rsc/nonce.js +18 -0
- package/dist/rsc/nonce.js.map +1 -0
- package/dist/rsc/types.d.ts +206 -0
- package/dist/rsc/types.d.ts.map +1 -0
- package/dist/rsc/types.js +8 -0
- package/dist/rsc/types.js.map +1 -0
- package/dist/search-params.d.ts +103 -0
- package/dist/search-params.d.ts.map +1 -0
- package/dist/search-params.js +74 -0
- package/dist/search-params.js.map +1 -0
- package/dist/segment-system.d.ts +75 -0
- package/dist/segment-system.d.ts.map +1 -0
- package/dist/segment-system.js +336 -0
- package/dist/segment-system.js.map +1 -0
- package/dist/server/context.d.ts +245 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +197 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/fetchable-loader-store.d.ts +18 -0
- package/dist/server/fetchable-loader-store.d.ts.map +1 -0
- package/dist/server/fetchable-loader-store.js +18 -0
- package/dist/server/fetchable-loader-store.js.map +1 -0
- package/dist/server/handle-store.d.ts +85 -0
- package/dist/server/handle-store.d.ts.map +1 -0
- package/dist/server/handle-store.js +142 -0
- package/dist/server/handle-store.js.map +1 -0
- package/dist/server/loader-registry.d.ts +55 -0
- package/dist/server/loader-registry.d.ts.map +1 -0
- package/dist/server/loader-registry.js +132 -0
- package/dist/server/loader-registry.js.map +1 -0
- package/dist/server/request-context.d.ts +226 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +290 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/root-layout.d.ts +4 -0
- package/dist/server/root-layout.d.ts.map +1 -0
- package/dist/server/root-layout.js +5 -0
- package/dist/server/root-layout.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +20 -0
- package/dist/server.js.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
- package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
- package/dist/ssr/index.d.ts +98 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +158 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/static-handler.d.ts +50 -0
- package/dist/static-handler.d.ts.map +1 -0
- package/dist/static-handler.gen.d.ts +5 -0
- package/dist/static-handler.gen.d.ts.map +1 -0
- package/dist/static-handler.gen.js +5 -0
- package/dist/static-handler.gen.js.map +1 -0
- package/dist/static-handler.js +29 -0
- package/dist/static-handler.js.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +20 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +240 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/ThemeScript.d.ts +48 -0
- package/dist/theme/ThemeScript.d.ts.map +1 -0
- package/dist/theme/ThemeScript.js +13 -0
- package/dist/theme/ThemeScript.js.map +1 -0
- package/dist/theme/__tests__/theme.test.d.ts +2 -0
- package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
- package/dist/theme/__tests__/theme.test.js +103 -0
- package/dist/theme/__tests__/theme.test.js.map +1 -0
- package/dist/theme/constants.d.ts +29 -0
- package/dist/theme/constants.d.ts.map +1 -0
- package/dist/theme/constants.js +48 -0
- package/dist/theme/constants.js.map +1 -0
- package/dist/theme/index.d.ts +31 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +36 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-context.d.ts +40 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +60 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-script.d.ts +27 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +147 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/dist/theme/types.d.ts +163 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +11 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme/use-theme.d.ts +12 -0
- package/dist/theme/use-theme.d.ts.map +1 -0
- package/dist/theme/use-theme.js +40 -0
- package/dist/theme/use-theme.js.map +1 -0
- package/dist/types.d.ts +1479 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/urls.d.ts +441 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.gen.d.ts +8 -0
- package/dist/urls.gen.d.ts.map +1 -0
- package/dist/urls.gen.js +8 -0
- package/dist/urls.gen.js.map +1 -0
- package/dist/urls.js +443 -0
- package/dist/urls.js.map +1 -0
- package/dist/use-loader.d.ts +127 -0
- package/dist/use-loader.d.ts.map +1 -0
- package/dist/use-loader.js +237 -0
- package/dist/use-loader.js.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
- package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.js +39 -0
- package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
- package/dist/vite/ast-handler-extract.d.ts +49 -0
- package/dist/vite/ast-handler-extract.d.ts.map +1 -0
- package/dist/vite/ast-handler-extract.js +249 -0
- package/dist/vite/ast-handler-extract.js.map +1 -0
- package/dist/vite/expose-action-id.d.ts +19 -0
- package/dist/vite/expose-action-id.d.ts.map +1 -0
- package/dist/vite/expose-action-id.js +250 -0
- package/dist/vite/expose-action-id.js.map +1 -0
- package/dist/vite/expose-id-utils.d.ts +69 -0
- package/dist/vite/expose-id-utils.d.ts.map +1 -0
- package/dist/vite/expose-id-utils.js +289 -0
- package/dist/vite/expose-id-utils.js.map +1 -0
- package/dist/vite/expose-internal-ids.d.ts +22 -0
- package/dist/vite/expose-internal-ids.d.ts.map +1 -0
- package/dist/vite/expose-internal-ids.js +886 -0
- package/dist/vite/expose-internal-ids.js.map +1 -0
- package/dist/vite/index.d.ts +149 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +361 -65
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/index.named-routes.gen.ts +103 -0
- package/dist/vite/package-resolution.d.ts +43 -0
- package/dist/vite/package-resolution.d.ts.map +1 -0
- package/dist/vite/package-resolution.js +112 -0
- package/dist/vite/package-resolution.js.map +1 -0
- package/dist/vite/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/dist/vite/virtual-entries.js +110 -0
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +6 -1
- package/skills/breadcrumbs/SKILL.md +60 -0
- package/skills/observability/SKILL.md +12 -3
- package/skills/prerender/SKILL.md +30 -11
- package/skills/router-setup/SKILL.md +11 -3
- package/skills/server-actions/SKILL.md +25 -1
- package/skills/testing/SKILL.md +17 -17
- package/skills/testing/cache-prerender.md +29 -3
- package/skills/testing/flight.md +13 -10
- package/skills/testing/render-handler.md +3 -0
- package/skills/testing/server-tree.md +1 -1
- package/skills/testing/setup.md +1 -1
- package/src/browser/partial-update.ts +22 -1
- package/src/browser/react/use-router.ts +2 -1
- package/src/browser/rsc-router.tsx +8 -1
- package/src/browser/server-action-bridge.ts +51 -3
- package/src/browser/types.ts +23 -4
- package/src/browser/validate-redirect-origin.ts +43 -15
- package/src/build/index.ts +8 -9
- package/src/build/route-trie.ts +43 -11
- package/src/build/route-types/codegen.ts +12 -1
- package/src/cache/cache-runtime.ts +21 -0
- package/src/cache/cache-scope.ts +20 -0
- package/src/cache/document-cache.ts +10 -0
- package/src/cache/profile-registry.ts +6 -34
- package/src/client.rsc.tsx +3 -0
- package/src/client.tsx +5 -0
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/context-var.ts +12 -0
- package/src/defer.ts +196 -0
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/index.rsc.ts +26 -2
- package/src/index.ts +23 -1
- package/src/redirect-origin.ts +100 -0
- package/src/route-definition/dsl-helpers.ts +19 -0
- package/src/route-definition/redirect.ts +32 -8
- package/src/route-definition/resolve-handler-use.ts +6 -0
- package/src/router/find-match.ts +0 -1
- package/src/router/instrument.ts +230 -0
- package/src/router/loader-resolution.ts +37 -31
- package/src/router/match-middleware/cache-lookup.ts +104 -139
- package/src/router/match-middleware/cache-store.ts +12 -0
- package/src/router/match-middleware/segment-resolution.ts +0 -1
- package/src/router/middleware-types.ts +0 -1
- package/src/router/middleware.ts +94 -33
- package/src/router/pattern-matching.ts +4 -23
- package/src/router/prerender-match.ts +32 -8
- package/src/router/revalidation.ts +9 -4
- package/src/router/route-snapshot.ts +0 -1
- package/src/router/router-context.ts +2 -2
- package/src/router/router-interfaces.ts +18 -0
- package/src/router/router-options.ts +58 -4
- package/src/router/segment-resolution/fresh.ts +15 -18
- package/src/router/segment-resolution/helpers.ts +6 -0
- package/src/router/segment-resolution/loader-cache.ts +30 -10
- package/src/router/segment-resolution/revalidation.ts +194 -261
- package/src/router/segment-wrappers.ts +3 -5
- package/src/router/telemetry-otel.ts +161 -179
- package/src/router/tracing.ts +198 -0
- package/src/router/trie-matching.ts +3 -5
- package/src/router.ts +13 -9
- package/src/rsc/handler-context.ts +1 -0
- package/src/rsc/handler.ts +135 -130
- package/src/rsc/helpers.ts +56 -3
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +7 -1
- package/src/rsc/origin-guard.ts +10 -4
- package/src/rsc/progressive-enhancement.ts +17 -2
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-route-handler.ts +23 -18
- package/src/rsc/rsc-rendering.ts +38 -14
- package/src/rsc/server-action.ts +32 -8
- package/src/rsc/types.ts +6 -2
- package/src/segment-system.tsx +4 -1
- package/src/server/request-context.ts +35 -18
- package/src/testing/cache-status.ts +44 -1
- package/src/testing/dispatch.ts +43 -6
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/flight.ts +48 -2
- package/src/testing/index.ts +1 -0
- package/src/testing/render-handler.ts +31 -12
- package/src/testing/render-route.tsx +75 -13
- package/src/types/handler-context.ts +28 -1
- package/src/vite/discovery/discover-routers.ts +22 -11
- package/src/vite/discovery/prerender-collection.ts +28 -41
- package/src/vite/discovery/state.ts +11 -0
- package/src/vite/plugin-types.ts +56 -7
- package/src/vite/plugins/expose-ids/router-transform.ts +10 -0
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +21 -10
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +16 -3
- package/src/vite/utils/prerender-utils.ts +36 -0
- package/src/router/middleware-cookies.ts +0 -42
package/src/defer.ts
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deferred handle values — "decide synchronously, resolve late".
|
|
3
|
+
*
|
|
4
|
+
* A handle is pushed from code that holds `ctx` (a route/layout handler), so the
|
|
5
|
+
* decision to push lands before the handles stream seals. But the value often
|
|
6
|
+
* isn't known there — it may come from a deep async component far from the
|
|
7
|
+
* handler. `ctx.use(Handle).defer()` reserves the handle's slot now (synchronous,
|
|
8
|
+
* so ordering and the pre-seal timing hold) and returns a resolver with the SAME
|
|
9
|
+
* signature as the push: you call it later, anywhere in the render, with the same
|
|
10
|
+
* value you would have passed to the push.
|
|
11
|
+
*
|
|
12
|
+
* const breadcrumb = ctx.use(Breadcrumbs); // (item) => void & .defer()
|
|
13
|
+
* const resolve = breadcrumb.defer({ timeoutMs: 5000, else: null });
|
|
14
|
+
* // deep async component, far from ctx:
|
|
15
|
+
* resolve({ label, href, content }); // identical call, just deferred
|
|
16
|
+
*
|
|
17
|
+
* Under the hood the reserved slot is a Promise the renderer `use()`s; RSC Flight
|
|
18
|
+
* streams it as a late row, so a deferred-aware consumer reading the handle
|
|
19
|
+
* (`useHandle`) sees that entry as a `Promise` until it resolves (see
|
|
20
|
+
* {@link DeferredHandleEntry}). The hazard that guards against bugs: a deferred
|
|
21
|
+
* slot whose resolver is never called would keep the Flight stream — and the HTTP
|
|
22
|
+
* response — open forever. So a deferred auto-resolves to `else` after `timeoutMs`
|
|
23
|
+
* (default {@link DEFAULT_DEFER_TIMEOUT_MS}) if the resolver is never called,
|
|
24
|
+
* degrading gracefully (and warning in dev) instead of hanging the request.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/** Default auto-resolve window. Long enough for genuine deep async work, short
|
|
28
|
+
* enough that a forgotten resolve does not hang the response indefinitely. */
|
|
29
|
+
export const DEFAULT_DEFER_TIMEOUT_MS = 10_000;
|
|
30
|
+
|
|
31
|
+
/** Options for `ctx.use(Handle).defer()`. */
|
|
32
|
+
export interface DeferOptions<TData> {
|
|
33
|
+
/**
|
|
34
|
+
* Auto-resolve to `else` after this many ms if the resolver is never called,
|
|
35
|
+
* so a forgotten resolve cannot hold the Flight stream — and thus the HTTP
|
|
36
|
+
* response — open. Defaults to {@link DEFAULT_DEFER_TIMEOUT_MS}. `0` or
|
|
37
|
+
* `Infinity` disable the timeout intentionally (not recommended on a request
|
|
38
|
+
* path). Any other non-finite or negative value is treated as a mistake and
|
|
39
|
+
* falls back to the default rather than silently disabling the safety net.
|
|
40
|
+
* Named `timeoutMs` to match the router's `*Ms` duration convention.
|
|
41
|
+
*/
|
|
42
|
+
timeoutMs?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Value the slot resolves to if the timeout fires before the resolver is
|
|
45
|
+
* called. Defaults to `undefined` (the deferred item is skipped/empty). For
|
|
46
|
+
* renderable handle content, `null` is the usual graceful fallback, so the
|
|
47
|
+
* type admits `null` even when `TData` does not.
|
|
48
|
+
*/
|
|
49
|
+
else?: TData | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The call signature shared by a handle push and the resolver returned by
|
|
54
|
+
* `.defer()`: a concrete value, a `Promise` of the value (Flight streams it as a
|
|
55
|
+
* late row), or a thunk returning a `Promise` (called immediately).
|
|
56
|
+
*/
|
|
57
|
+
export type HandlePushFn<TData> = (
|
|
58
|
+
data: TData | Promise<TData> | (() => Promise<TData>),
|
|
59
|
+
) => void;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The push function returned by `ctx.use(Handle)`. Call it to push a value now,
|
|
63
|
+
* or call `.defer()` to reserve the slot now and resolve the value later (e.g.
|
|
64
|
+
* from a deep async component) with a timeout safety net.
|
|
65
|
+
*/
|
|
66
|
+
export type HandlePush<TData> = HandlePushFn<TData> & {
|
|
67
|
+
/**
|
|
68
|
+
* Reserve this handle's slot synchronously and return a resolver that is
|
|
69
|
+
* push-equal: it takes the same argument shapes as the push (value, Promise, or
|
|
70
|
+
* thunk) and behaves identically. Two things the resolver adds over a direct
|
|
71
|
+
* push: a timeout (if the resolver is never called, the slot auto-resolves to
|
|
72
|
+
* `options.else` after `options.timeoutMs`; calling the resolver cancels it),
|
|
73
|
+
* and — on the action/revalidation path only — a thunk it runs does NOT
|
|
74
|
+
* re-enter the deadlock-guard push-callback scope a direct push thunk gets,
|
|
75
|
+
* because a deferred resolver fires after the handler phase has closed.
|
|
76
|
+
*
|
|
77
|
+
* The reserved slot appears in the accumulated handle data as a pending
|
|
78
|
+
* `Promise` until it resolves (see {@link DeferredHandleEntry}); a
|
|
79
|
+
* deferred-aware consumer narrows thenable entries (`use()`/`await` + null
|
|
80
|
+
* check) before dereferencing.
|
|
81
|
+
*/
|
|
82
|
+
defer(options?: DeferOptions<TData>): HandlePushFn<TData>;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A handle entry a deferred-aware consumer may read from `useHandle`: either a
|
|
87
|
+
* resolved value, or a pending `Promise` that resolves to the value, to `else`,
|
|
88
|
+
* or (when no `else` was given) `undefined` on timeout. Reading code should treat
|
|
89
|
+
* thenable entries as such and narrow before dereferencing.
|
|
90
|
+
*/
|
|
91
|
+
export type DeferredHandleEntry<TData> =
|
|
92
|
+
| TData
|
|
93
|
+
| Promise<TData | null | undefined>;
|
|
94
|
+
|
|
95
|
+
// Internal: a timeout-bounded { promise, resolve }. Not part of the public API
|
|
96
|
+
// (the public surface is `ctx.use(Handle).defer()`); exported for `withDefer`
|
|
97
|
+
// and unit tests only. Resolves to `T`, the `else` fallback, or `undefined`.
|
|
98
|
+
export function createDeferred<T>(options?: {
|
|
99
|
+
timeoutMs?: number;
|
|
100
|
+
fallback?: T | null;
|
|
101
|
+
}): {
|
|
102
|
+
promise: Promise<T | null | undefined>;
|
|
103
|
+
resolve: (value: T | null | undefined) => void;
|
|
104
|
+
} {
|
|
105
|
+
let resolveInner!: (value: T | null | undefined) => void;
|
|
106
|
+
let settled = false;
|
|
107
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
108
|
+
|
|
109
|
+
const promise = new Promise<T | null | undefined>((resolve) => {
|
|
110
|
+
resolveInner = resolve;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const finish = (value: T | null | undefined): void => {
|
|
114
|
+
if (settled) return;
|
|
115
|
+
settled = true;
|
|
116
|
+
if (timer !== undefined) {
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
timer = undefined;
|
|
119
|
+
}
|
|
120
|
+
resolveInner(value);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// 0 and Infinity are documented intentional disables. Any other non-finite or
|
|
124
|
+
// negative value (NaN, -1, a bad parsed config/env) is a mistake — fall back to
|
|
125
|
+
// the default rather than SILENTLY disabling the safety net, which would let a
|
|
126
|
+
// forgotten resolve hang the Flight stream and the response forever.
|
|
127
|
+
const requested = options?.timeoutMs ?? DEFAULT_DEFER_TIMEOUT_MS;
|
|
128
|
+
let ms: number;
|
|
129
|
+
if (requested === 0 || requested === Infinity) {
|
|
130
|
+
ms = requested;
|
|
131
|
+
} else if (Number.isFinite(requested) && requested > 0) {
|
|
132
|
+
ms = requested;
|
|
133
|
+
} else {
|
|
134
|
+
if (process.env.NODE_ENV !== "production") {
|
|
135
|
+
console.warn(
|
|
136
|
+
`[rango] defer(): invalid timeout ${String(requested)}; using the ` +
|
|
137
|
+
`${DEFAULT_DEFER_TIMEOUT_MS}ms default so the safety net stays on. ` +
|
|
138
|
+
`Use 0 or Infinity to disable the timeout intentionally.`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
ms = DEFAULT_DEFER_TIMEOUT_MS;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (ms > 0 && ms !== Infinity) {
|
|
145
|
+
timer = setTimeout(() => {
|
|
146
|
+
if (process.env.NODE_ENV !== "production") {
|
|
147
|
+
console.warn(
|
|
148
|
+
`[rango] A deferred handle value was not resolved within ${ms}ms; ` +
|
|
149
|
+
`resolving to the fallback so the response can flush. Call the ` +
|
|
150
|
+
`resolver from the component that produces the value, or raise timeoutMs.`,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
finish(options?.fallback);
|
|
154
|
+
}, ms);
|
|
155
|
+
// Don't let a pending timer alone keep a Node process alive (no-op on workerd).
|
|
156
|
+
(timer as { unref?: () => void }).unref?.();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return { promise, resolve: finish };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Attach `.defer()` to a handle push function. The deferred slot is reserved by
|
|
164
|
+
* pushing the deferred promise through the same push (so ordering, sealing, and
|
|
165
|
+
* Flight streaming all reuse the existing path); the returned resolver settles it.
|
|
166
|
+
*/
|
|
167
|
+
export function withDefer<TData>(push: HandlePushFn<TData>): HandlePush<TData> {
|
|
168
|
+
const handlePush = push as HandlePush<TData>;
|
|
169
|
+
// Safe to mutate push in place: each ctx.use(Handle) call (request-context.ts,
|
|
170
|
+
// loader-resolution.ts) builds a fresh closure, so .defer never leaks across
|
|
171
|
+
// handles or requests.
|
|
172
|
+
handlePush.defer = (options) => {
|
|
173
|
+
const deferred = createDeferred<TData>({
|
|
174
|
+
timeoutMs: options?.timeoutMs,
|
|
175
|
+
fallback: options?.else,
|
|
176
|
+
});
|
|
177
|
+
// Reserve the slot now by pushing the pending promise (the renderer use()s it).
|
|
178
|
+
push(deferred.promise as Promise<TData>);
|
|
179
|
+
// The resolver is push-equal: a thunk is invoked immediately (as push does)
|
|
180
|
+
// and a Promise is adopted by the reserved slot. Calling it settles the slot
|
|
181
|
+
// and cancels the timeout — the timeout only fires if it is never called.
|
|
182
|
+
const resolveSlot = deferred.resolve as (
|
|
183
|
+
value: TData | Promise<TData>,
|
|
184
|
+
) => void;
|
|
185
|
+
return (data) => {
|
|
186
|
+
// The thunk runs without re-entering the push-callback scope a direct push
|
|
187
|
+
// thunk gets on the action/revalidation path (loader-resolution.ts): a
|
|
188
|
+
// deferred resolver fires from a deep component after the handler phase has
|
|
189
|
+
// closed, so there is no live deadlock-guard window to exempt.
|
|
190
|
+
resolveSlot(
|
|
191
|
+
typeof data === "function" ? (data as () => Promise<TData>)() : data,
|
|
192
|
+
);
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
return handlePush;
|
|
196
|
+
}
|
|
@@ -39,18 +39,29 @@ export interface BreadcrumbItem {
|
|
|
39
39
|
/**
|
|
40
40
|
* Collect function for Breadcrumbs handle.
|
|
41
41
|
* Flattens segments in parent-to-child order with deduplication by href
|
|
42
|
-
* (last item for each href wins).
|
|
42
|
+
* (last item for each href wins). Deferred slots (`ctx.use(Breadcrumbs).defer()`)
|
|
43
|
+
* arrive as pending Promise entries with no href yet; they are passed through by
|
|
44
|
+
* identity and excluded from the href dedup so concurrent deferred crumbs do not
|
|
45
|
+
* all collapse under a single `undefined` href.
|
|
43
46
|
*/
|
|
44
47
|
function collectBreadcrumbs(segments: BreadcrumbItem[][]): BreadcrumbItem[] {
|
|
45
48
|
const all = segments.flat();
|
|
46
|
-
const seen = new Map<string, number>();
|
|
47
49
|
|
|
50
|
+
const isResolvedItem = (item: unknown): item is BreadcrumbItem =>
|
|
51
|
+
item != null &&
|
|
52
|
+
typeof item === "object" &&
|
|
53
|
+
typeof (item as { then?: unknown }).then !== "function" &&
|
|
54
|
+
typeof (item as { href?: unknown }).href === "string";
|
|
55
|
+
|
|
56
|
+
const seen = new Map<string, number>();
|
|
48
57
|
for (let i = 0; i < all.length; i++) {
|
|
49
|
-
seen.set(all[i].href, i);
|
|
58
|
+
if (isResolvedItem(all[i])) seen.set(all[i].href, i);
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
//
|
|
53
|
-
return all.filter(
|
|
61
|
+
// Deferred items bypass dedup (excluded via !isResolvedItem check).
|
|
62
|
+
return all.filter(
|
|
63
|
+
(item, index) => !isResolvedItem(item) || seen.get(item.href) === index,
|
|
64
|
+
);
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
/**
|
package/src/index.rsc.ts
CHANGED
|
@@ -114,6 +114,13 @@ export type {
|
|
|
114
114
|
|
|
115
115
|
// Handle API
|
|
116
116
|
export { createHandle, isHandle, type Handle } from "./handle.js";
|
|
117
|
+
export {
|
|
118
|
+
DEFAULT_DEFER_TIMEOUT_MS,
|
|
119
|
+
type DeferOptions,
|
|
120
|
+
type DeferredHandleEntry,
|
|
121
|
+
type HandlePush,
|
|
122
|
+
type HandlePushFn,
|
|
123
|
+
} from "./defer.js";
|
|
117
124
|
|
|
118
125
|
// Context variable API (typed ctx.set/ctx.get tokens)
|
|
119
126
|
export { createVar, type ContextVar } from "./context-var.js";
|
|
@@ -251,10 +258,17 @@ export {
|
|
|
251
258
|
// Path and response types are ambient on the `Rango` namespace (`Rango.Path`,
|
|
252
259
|
// `Rango.PathResponse`, declared in href-client.ts) — no import needed.
|
|
253
260
|
|
|
254
|
-
// Telemetry sink
|
|
261
|
+
// Telemetry sink (event-shaped facts)
|
|
255
262
|
export { createConsoleSink } from "./router/telemetry.js";
|
|
256
263
|
export { createOTelSink } from "./router/telemetry-otel.js";
|
|
257
|
-
|
|
264
|
+
// OTel phase-span adapter for the `tracing` slot (the canonical span layer).
|
|
265
|
+
export { createOTelTracing } from "./router/telemetry-otel.js";
|
|
266
|
+
export type {
|
|
267
|
+
OTelTracer,
|
|
268
|
+
OTelActiveSpanTracer,
|
|
269
|
+
OTelSpan,
|
|
270
|
+
OTelTracingOptions,
|
|
271
|
+
} from "./router/telemetry-otel.js";
|
|
258
272
|
// The full TelemetryEvent union PLUS its member types, so a consumer writing a
|
|
259
273
|
// TelemetrySink can annotate a per-`type` handler (or construct an event literal
|
|
260
274
|
// in a test) instead of only narrowing the opaque union.
|
|
@@ -276,6 +290,16 @@ export type {
|
|
|
276
290
|
OriginCheckRejectedEvent,
|
|
277
291
|
} from "./router/telemetry.js";
|
|
278
292
|
|
|
293
|
+
// Span tracing config types a consumer annotates. SpanRunner/TraceSpan are the
|
|
294
|
+
// internal runner contract (consumers go through createOTelTracing /
|
|
295
|
+
// createCloudflareTracing, which return a ready RouterTracingConfig) and are not
|
|
296
|
+
// exported.
|
|
297
|
+
export type {
|
|
298
|
+
RouterTracingConfig,
|
|
299
|
+
TracePhase,
|
|
300
|
+
TracePhaseToggles,
|
|
301
|
+
} from "./router/tracing.js";
|
|
302
|
+
|
|
279
303
|
// Timeout types and error class
|
|
280
304
|
export { RouterTimeoutError } from "./router/timeout.js";
|
|
281
305
|
export type {
|
package/src/index.ts
CHANGED
|
@@ -140,6 +140,13 @@ export function redirect(): never {
|
|
|
140
140
|
|
|
141
141
|
// Handle API (universal - works on both server and client)
|
|
142
142
|
export { createHandle, isHandle, type Handle } from "./handle.js";
|
|
143
|
+
export {
|
|
144
|
+
DEFAULT_DEFER_TIMEOUT_MS,
|
|
145
|
+
type DeferOptions,
|
|
146
|
+
type DeferredHandleEntry,
|
|
147
|
+
type HandlePush,
|
|
148
|
+
type HandlePushFn,
|
|
149
|
+
} from "./defer.js";
|
|
143
150
|
|
|
144
151
|
// Context variable API (typed ctx.set/ctx.get tokens)
|
|
145
152
|
export { createVar, type ContextVar } from "./context-var.js";
|
|
@@ -337,7 +344,12 @@ export {
|
|
|
337
344
|
// bundle analysis output and slow build-time module resolution. Consumers
|
|
338
345
|
// who need the values in non-RSC contexts can import from
|
|
339
346
|
// `@rangojs/router/server`.
|
|
340
|
-
export type {
|
|
347
|
+
export type {
|
|
348
|
+
OTelTracer,
|
|
349
|
+
OTelActiveSpanTracer,
|
|
350
|
+
OTelSpan,
|
|
351
|
+
OTelTracingOptions,
|
|
352
|
+
} from "./router/telemetry-otel.js";
|
|
341
353
|
// The full TelemetryEvent union PLUS its member types, so a consumer writing a
|
|
342
354
|
// TelemetrySink can annotate a per-`type` handler (or construct an event literal
|
|
343
355
|
// in a test) instead of only narrowing the opaque union.
|
|
@@ -359,6 +371,16 @@ export type {
|
|
|
359
371
|
OriginCheckRejectedEvent,
|
|
360
372
|
} from "./router/telemetry.js";
|
|
361
373
|
|
|
374
|
+
// Span tracing config types a consumer annotates. SpanRunner/TraceSpan are the
|
|
375
|
+
// internal runner contract (consumers go through createOTelTracing /
|
|
376
|
+
// createCloudflareTracing, which return a ready RouterTracingConfig) and are not
|
|
377
|
+
// exported.
|
|
378
|
+
export type {
|
|
379
|
+
RouterTracingConfig,
|
|
380
|
+
TracePhase,
|
|
381
|
+
TracePhaseToggles,
|
|
382
|
+
} from "./router/tracing.js";
|
|
383
|
+
|
|
362
384
|
// Timeout types and error class
|
|
363
385
|
export { RouterTimeoutError } from "./router/timeout.js";
|
|
364
386
|
export type {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-neutral same-origin redirect rule.
|
|
3
|
+
*
|
|
4
|
+
* Shared by the client redirect guard (`browser/validate-redirect-origin.ts`,
|
|
5
|
+
* which validates redirect targets the client JS is about to navigate to) and
|
|
6
|
+
* the server outgoing-redirect guard (`rsc/redirect-guard.ts`, which validates
|
|
7
|
+
* every browser-followed `Location` header before it leaves the handler). Kept
|
|
8
|
+
* at the `src/` root so both layers import the ONE rule and cannot drift -- a
|
|
9
|
+
* cross-origin target blocked on the JS/fetch path is blocked identically on the
|
|
10
|
+
* no-JS (PE) and full-page document paths.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a redirect target against the current origin.
|
|
15
|
+
*
|
|
16
|
+
* Returns the canonical (normalized) same-origin href -- which also collapses
|
|
17
|
+
* protocol-relative (`//evil.com`) and other ambiguous forms -- or `null` when
|
|
18
|
+
* the target resolves to a different origin or is unparseable. Pure: no logging,
|
|
19
|
+
* no side effects.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveSameOriginRedirect(
|
|
22
|
+
url: string,
|
|
23
|
+
currentOrigin: string,
|
|
24
|
+
): string | null {
|
|
25
|
+
try {
|
|
26
|
+
const target = new URL(url, currentOrigin);
|
|
27
|
+
if (target.origin !== currentOrigin) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return target.href;
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Validate an explicit off-origin redirect target (`redirect(url, { external:
|
|
38
|
+
* true })`).
|
|
39
|
+
*
|
|
40
|
+
* `external` opts out of the same-origin rule, but NOT out of scheme safety:
|
|
41
|
+
* only `http:`/`https:` targets are allowed. A redirect ultimately reaches the
|
|
42
|
+
* browser via `window.location.assign()` on the SPA/action client paths, so a
|
|
43
|
+
* forged or mistaken `redirect("javascript:...", { external: true })` would be a
|
|
44
|
+
* scriptable navigation if the scheme were not checked here. Returns the
|
|
45
|
+
* normalized href for an http(s) target (same- or cross-origin), or `null`
|
|
46
|
+
* otherwise. Pure: no logging, no side effects.
|
|
47
|
+
*/
|
|
48
|
+
export function resolveExternalRedirect(
|
|
49
|
+
url: string,
|
|
50
|
+
currentOrigin: string,
|
|
51
|
+
): string | null {
|
|
52
|
+
try {
|
|
53
|
+
const target = new URL(url, currentOrigin);
|
|
54
|
+
if (target.protocol !== "http:" && target.protocol !== "https:") {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return target.href;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Out-of-band brand for `redirect(url, { external: true })`.
|
|
65
|
+
*
|
|
66
|
+
* The external opt-in MUST be settable only by app code calling `redirect(...,
|
|
67
|
+
* { external: true })`, never by an attacker. An earlier design carried the
|
|
68
|
+
* opt-in as a wire header (`x-rango-redirect-external`), but a wire header is
|
|
69
|
+
* forgeable: a proxy-style response route that copies an attacker-controlled
|
|
70
|
+
* upstream response's headers would let `302 Location: https://evil` plus that
|
|
71
|
+
* header bypass the same-origin guard without app code ever opting in. So the
|
|
72
|
+
* opt-in is now an out-of-band brand on the Response object itself, tracked in a
|
|
73
|
+
* `WeakSet` that cannot cross the wire. `redirect()` brands the Response; the
|
|
74
|
+
* small set of internal redirect-rebuild paths (middleware `mergeResponse`,
|
|
75
|
+
* `carryOverRedirectHeaders`, the response-route rewrap) transfer the brand onto
|
|
76
|
+
* the rebuilt Response; the guard and the SPA intercept read it. An upstream
|
|
77
|
+
* Response an app proxies is never branded, so its forged header is inert.
|
|
78
|
+
*
|
|
79
|
+
* Fail-closed: if a rebuild path ever drops the brand, the redirect is
|
|
80
|
+
* neutralized to the app root rather than allowed off-host.
|
|
81
|
+
*/
|
|
82
|
+
const externalRedirects = new WeakSet<Response>();
|
|
83
|
+
|
|
84
|
+
/** Brand a Response as an explicit `{ external: true }` redirect (out-of-band). */
|
|
85
|
+
export function markExternalRedirect(response: Response): void {
|
|
86
|
+
externalRedirects.add(response);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Read the out-of-band `{ external: true }` brand off a Response. */
|
|
90
|
+
export function isExternalRedirect(response: Response): boolean {
|
|
91
|
+
return externalRedirects.has(response);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Reserved internal header name. No longer a trust signal -- the external
|
|
96
|
+
* opt-in is the out-of-band brand above. It is kept only so the redirect-rebuild
|
|
97
|
+
* paths and the guard can defensively strip any value (e.g. one forged by a
|
|
98
|
+
* proxied upstream) and guarantee it never reaches the browser.
|
|
99
|
+
*/
|
|
100
|
+
export const EXTERNAL_REDIRECT_MARKER: string = "x-rango-redirect-external";
|
|
@@ -524,6 +524,22 @@ const middleware: RouteHelpers<any, any>["middleware"] = (...args: any[]) => {
|
|
|
524
524
|
} as MiddlewareItem;
|
|
525
525
|
};
|
|
526
526
|
|
|
527
|
+
// Slot names become part of segment ids: a parallel/intercept slot is encoded
|
|
528
|
+
// as `${shortCode}.${slotName}`, and loader segments append `D${index}.${loaderId}`.
|
|
529
|
+
// A "." in the slot name collides with that separator -- loaderParentId
|
|
530
|
+
// (segment-system.tsx) strips from the FIRST `D<index>.`, so a name like
|
|
531
|
+
// "@D3.foo" is mis-cut to "@" and the loader's data is silently dropped. Reject
|
|
532
|
+
// the dot at definition time so the failure is loud, not a corrupted tree at
|
|
533
|
+
// runtime. (A bare "D" without a trailing dot -- e.g. "@Detail" -- is fine.)
|
|
534
|
+
function assertValidSlotName(slotName: string): void {
|
|
535
|
+
invariant(
|
|
536
|
+
!slotName.includes("."),
|
|
537
|
+
`Slot name "${slotName}" must not contain ".". The dot is a reserved ` +
|
|
538
|
+
`segment-id separator; a name like "@D3.foo" corrupts loader segment-id ` +
|
|
539
|
+
`parsing and silently drops the loader's data. Rename the slot.`,
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
|
|
527
543
|
const parallel: RouteHelpers<any, any>["parallel"] = (slots, use) => {
|
|
528
544
|
const { store, ctx } = requireDslContext(
|
|
529
545
|
"parallel() must be called inside urls()",
|
|
@@ -539,6 +555,7 @@ const parallel: RouteHelpers<any, any>["parallel"] = (slots, use) => {
|
|
|
539
555
|
);
|
|
540
556
|
|
|
541
557
|
const slotNames = Object.keys(slots as Record<string, any>) as `@${string}`[];
|
|
558
|
+
for (const slotName of slotNames) assertValidSlotName(slotName);
|
|
542
559
|
|
|
543
560
|
const namespace = `${ctx.namespace}.$${store.getNextIndex("parallel")}`;
|
|
544
561
|
|
|
@@ -698,6 +715,8 @@ const intercept = (
|
|
|
698
715
|
"intercept() cannot be used inside parallel()",
|
|
699
716
|
);
|
|
700
717
|
|
|
718
|
+
assertValidSlotName(slotName);
|
|
719
|
+
|
|
701
720
|
const namespace = `${ctx.namespace}.$${store.getNextIndex("intercept")}.${slotName}`;
|
|
702
721
|
|
|
703
722
|
// Dot-prefixed = local (add include prefix), unprefixed = global (use as-is)
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
getRequestContext,
|
|
5
5
|
_getRequestContext,
|
|
6
6
|
} from "../server/request-context.js";
|
|
7
|
+
import { markExternalRedirect } from "../redirect-origin.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Create a soft redirect Response for middleware short-circuit
|
|
@@ -39,6 +40,11 @@ import {
|
|
|
39
40
|
* status: 303,
|
|
40
41
|
* state: [Flash({ text: "Session expired" })],
|
|
41
42
|
* });
|
|
43
|
+
*
|
|
44
|
+
* // Off-host redirect (opt out of the same-origin guard). Without
|
|
45
|
+
* // `external: true`, a cross-origin target is blocked and replaced with the
|
|
46
|
+
* // app root, matching the client's open-redirect protection.
|
|
47
|
+
* return redirect('https://accounts.example.com/oauth', { external: true });
|
|
42
48
|
* ```
|
|
43
49
|
*/
|
|
44
50
|
export function redirect(url: string, status?: number): Response;
|
|
@@ -47,13 +53,18 @@ export function redirect(
|
|
|
47
53
|
options: {
|
|
48
54
|
status?: number;
|
|
49
55
|
state?: LocationStateEntry | LocationStateEntry[];
|
|
56
|
+
external?: boolean;
|
|
50
57
|
},
|
|
51
58
|
): Response;
|
|
52
59
|
export function redirect(
|
|
53
60
|
url: string,
|
|
54
61
|
statusOrOptions?:
|
|
55
62
|
| number
|
|
56
|
-
| {
|
|
63
|
+
| {
|
|
64
|
+
status?: number;
|
|
65
|
+
state?: LocationStateEntry | LocationStateEntry[];
|
|
66
|
+
external?: boolean;
|
|
67
|
+
},
|
|
57
68
|
): Response {
|
|
58
69
|
const status =
|
|
59
70
|
typeof statusOrOptions === "number"
|
|
@@ -61,6 +72,8 @@ export function redirect(
|
|
|
61
72
|
: (statusOrOptions?.status ?? 302);
|
|
62
73
|
const state =
|
|
63
74
|
typeof statusOrOptions === "object" ? statusOrOptions?.state : undefined;
|
|
75
|
+
const external =
|
|
76
|
+
typeof statusOrOptions === "object" ? statusOrOptions?.external : undefined;
|
|
64
77
|
|
|
65
78
|
if (state) {
|
|
66
79
|
const ctx = requireRequestContext();
|
|
@@ -101,11 +114,22 @@ export function redirect(
|
|
|
101
114
|
resolvedUrl = url === "/" ? bn : bn + url;
|
|
102
115
|
}
|
|
103
116
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
const headers: Record<string, string> = {
|
|
118
|
+
Location: resolvedUrl,
|
|
119
|
+
"X-RSC-Redirect": "soft",
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const response = new Response(null, { status, headers });
|
|
123
|
+
|
|
124
|
+
// Mark an explicit off-host redirect with an out-of-band brand so the
|
|
125
|
+
// same-origin guard (rsc/redirect-guard.ts) lets it through. The brand is a
|
|
126
|
+
// WeakSet membership on this Response object -- NOT a wire header -- so the
|
|
127
|
+
// opt-in cannot be forged by an attacker-controlled upstream response a
|
|
128
|
+
// proxy-style response route might copy. The internal redirect-rebuild paths
|
|
129
|
+
// transfer the brand; the guard reads and clears it (see markExternalRedirect).
|
|
130
|
+
if (external) {
|
|
131
|
+
markExternalRedirect(response);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return response;
|
|
111
135
|
}
|
|
@@ -139,6 +139,12 @@ export function mergeHandlerUse(
|
|
|
139
139
|
mountSite: string,
|
|
140
140
|
): (() => any[]) | undefined {
|
|
141
141
|
if (!handlerUse && !explicitUse) return undefined;
|
|
142
|
+
// Validation asymmetry (intentional, pre-1.0): only handler.use() items are
|
|
143
|
+
// checked against the mount-site allow-list (validateHandlerUseItems below).
|
|
144
|
+
// Explicit use() items pass through unvalidated on both the explicit-only
|
|
145
|
+
// branch here and the merged branch, so a structurally-valid-but-prohibited
|
|
146
|
+
// item (e.g. middleware() inside a parallel slot) is not rejected at this seam.
|
|
147
|
+
// Documented rather than enforced for now; revisit before 1.0 (#569).
|
|
142
148
|
if (!handlerUse) return explicitUse;
|
|
143
149
|
if (!explicitUse) {
|
|
144
150
|
return () => {
|
package/src/router/find-match.ts
CHANGED
|
@@ -110,7 +110,6 @@ export function createFindMatch<TEnv = any>(
|
|
|
110
110
|
entry,
|
|
111
111
|
routeKey: trieResult.routeKey,
|
|
112
112
|
params: trieResult.params,
|
|
113
|
-
optionalParams: new Set(trieResult.optionalParams || []),
|
|
114
113
|
redirectTo: trieResult.redirectTo,
|
|
115
114
|
...(trieResult.pr ? { pr: true } : {}),
|
|
116
115
|
...(trieResult.pt ? { pt: true } : {}),
|