@rangojs/router 0.0.0-experimental.140 → 0.0.0-experimental.142
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 +6 -10
- package/README.md +17 -0
- 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.map +1 -0
- package/dist/browser/event-controller.d.ts +191 -0
- package/dist/browser/event-controller.d.ts.map +1 -0
- package/dist/browser/event-controller.js +559 -0
- package/dist/browser/event-controller.js.map +1 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/link-interceptor.d.ts +38 -0
- package/dist/browser/link-interceptor.d.ts.map +1 -0
- package/dist/browser/link-interceptor.js +99 -0
- package/dist/browser/link-interceptor.js.map +1 -0
- package/dist/browser/logging.d.ts +10 -0
- package/dist/browser/logging.d.ts.map +1 -0
- package/dist/browser/logging.js +29 -0
- package/dist/browser/logging.js.map +1 -0
- package/dist/browser/lru-cache.d.ts +17 -0
- package/dist/browser/lru-cache.d.ts.map +1 -0
- package/dist/browser/lru-cache.js +50 -0
- package/dist/browser/lru-cache.js.map +1 -0
- package/dist/browser/merge-segment-loaders.d.ts +39 -0
- package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
- package/dist/browser/merge-segment-loaders.js +102 -0
- package/dist/browser/merge-segment-loaders.js.map +1 -0
- package/dist/browser/navigation-bridge.d.ts +102 -0
- package/dist/browser/navigation-bridge.d.ts.map +1 -0
- package/dist/browser/navigation-bridge.js +708 -0
- package/dist/browser/navigation-bridge.js.map +1 -0
- package/dist/browser/navigation-client.d.ts +25 -0
- package/dist/browser/navigation-client.d.ts.map +1 -0
- package/dist/browser/navigation-client.js +157 -0
- package/dist/browser/navigation-client.js.map +1 -0
- package/dist/browser/navigation-store.d.ts +101 -0
- package/dist/browser/navigation-store.d.ts.map +1 -0
- package/dist/browser/navigation-store.js +625 -0
- package/dist/browser/navigation-store.js.map +1 -0
- package/dist/browser/partial-update.d.ts +75 -0
- package/dist/browser/partial-update.d.ts.map +1 -0
- package/dist/browser/partial-update.js +426 -0
- package/dist/browser/partial-update.js.map +1 -0
- package/dist/browser/react/Link.d.ts +86 -0
- package/dist/browser/react/Link.d.ts.map +1 -0
- package/dist/browser/react/Link.js +128 -0
- package/dist/browser/react/Link.js.map +1 -0
- package/dist/browser/react/NavigationProvider.d.ts +63 -0
- package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
- package/dist/browser/react/NavigationProvider.js +216 -0
- package/dist/browser/react/NavigationProvider.js.map +1 -0
- package/dist/browser/react/ScrollRestoration.d.ts +75 -0
- package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
- package/dist/browser/react/ScrollRestoration.js +57 -0
- package/dist/browser/react/ScrollRestoration.js.map +1 -0
- package/dist/browser/react/context.d.ts +46 -0
- package/dist/browser/react/context.d.ts.map +1 -0
- package/dist/browser/react/context.js +10 -0
- package/dist/browser/react/context.js.map +1 -0
- package/dist/browser/react/index.d.ts +11 -0
- package/dist/browser/react/index.d.ts.map +1 -0
- package/dist/browser/react/index.js +22 -0
- package/dist/browser/react/index.js.map +1 -0
- package/dist/browser/react/location-state-shared.d.ts +63 -0
- package/dist/browser/react/location-state-shared.d.ts.map +1 -0
- package/dist/browser/react/location-state-shared.js +81 -0
- package/dist/browser/react/location-state-shared.js.map +1 -0
- package/dist/browser/react/location-state.d.ts +23 -0
- package/dist/browser/react/location-state.d.ts.map +1 -0
- package/dist/browser/react/location-state.js +29 -0
- package/dist/browser/react/location-state.js.map +1 -0
- package/dist/browser/react/mount-context.d.ts +24 -0
- package/dist/browser/react/mount-context.d.ts.map +1 -0
- package/dist/browser/react/mount-context.js +24 -0
- package/dist/browser/react/mount-context.js.map +1 -0
- package/dist/browser/react/use-action.d.ts +64 -0
- package/dist/browser/react/use-action.d.ts.map +1 -0
- package/dist/browser/react/use-action.js +134 -0
- package/dist/browser/react/use-action.js.map +1 -0
- package/dist/browser/react/use-client-cache.d.ts +41 -0
- package/dist/browser/react/use-client-cache.d.ts.map +1 -0
- package/dist/browser/react/use-client-cache.js +39 -0
- package/dist/browser/react/use-client-cache.js.map +1 -0
- package/dist/browser/react/use-handle.d.ts +31 -0
- package/dist/browser/react/use-handle.d.ts.map +1 -0
- package/dist/browser/react/use-handle.js +144 -0
- package/dist/browser/react/use-handle.js.map +1 -0
- package/dist/browser/react/use-href.d.ts +33 -0
- package/dist/browser/react/use-href.d.ts.map +1 -0
- package/dist/browser/react/use-href.js +39 -0
- package/dist/browser/react/use-href.js.map +1 -0
- package/dist/browser/react/use-link-status.d.ts +37 -0
- package/dist/browser/react/use-link-status.d.ts.map +1 -0
- package/dist/browser/react/use-link-status.js +99 -0
- package/dist/browser/react/use-link-status.js.map +1 -0
- package/dist/browser/react/use-mount.d.ts +25 -0
- package/dist/browser/react/use-mount.d.ts.map +1 -0
- package/dist/browser/react/use-mount.js +30 -0
- package/dist/browser/react/use-mount.js.map +1 -0
- package/dist/browser/react/use-navigation.d.ts +27 -0
- package/dist/browser/react/use-navigation.d.ts.map +1 -0
- package/dist/browser/react/use-navigation.js +87 -0
- package/dist/browser/react/use-navigation.js.map +1 -0
- package/dist/browser/react/use-segments.d.ts +38 -0
- package/dist/browser/react/use-segments.d.ts.map +1 -0
- package/dist/browser/react/use-segments.js +130 -0
- package/dist/browser/react/use-segments.js.map +1 -0
- package/dist/browser/request-controller.d.ts +26 -0
- package/dist/browser/request-controller.d.ts.map +1 -0
- package/dist/browser/request-controller.js +147 -0
- package/dist/browser/request-controller.js.map +1 -0
- package/dist/browser/rsc-router.d.ts +129 -0
- package/dist/browser/rsc-router.d.ts.map +1 -0
- package/dist/browser/rsc-router.js +195 -0
- package/dist/browser/rsc-router.js.map +1 -0
- package/dist/browser/scroll-restoration.d.ts +93 -0
- package/dist/browser/scroll-restoration.d.ts.map +1 -0
- package/dist/browser/scroll-restoration.js +321 -0
- package/dist/browser/scroll-restoration.js.map +1 -0
- package/dist/browser/segment-structure-assert.d.ts +17 -0
- package/dist/browser/segment-structure-assert.d.ts.map +1 -0
- package/dist/browser/segment-structure-assert.js +59 -0
- package/dist/browser/segment-structure-assert.js.map +1 -0
- package/dist/browser/server-action-bridge.d.ts +26 -0
- package/dist/browser/server-action-bridge.d.ts.map +1 -0
- package/dist/browser/server-action-bridge.js +668 -0
- package/dist/browser/server-action-bridge.js.map +1 -0
- package/dist/browser/shallow.d.ts +12 -0
- package/dist/browser/shallow.d.ts.map +1 -0
- package/dist/browser/shallow.js +34 -0
- package/dist/browser/shallow.js.map +1 -0
- package/dist/browser/types.d.ts +369 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
- package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-cli.test.js +237 -0
- package/dist/build/__tests__/generate-cli.test.js.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.js +119 -0
- package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.js +620 -0
- package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.js +308 -0
- package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +81 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +276 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/build/generate-route-types.d.ts +115 -0
- package/dist/build/generate-route-types.d.ts.map +1 -0
- package/dist/build/generate-route-types.js +740 -0
- package/dist/build/generate-route-types.js.map +1 -0
- package/dist/build/index.d.ts +21 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +21 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/route-trie.d.ts +71 -0
- package/dist/build/route-trie.d.ts.map +1 -0
- package/dist/build/route-trie.js +175 -0
- package/dist/build/route-trie.js.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.js +208 -0
- package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
- package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
- package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
- package/dist/cache/__tests__/document-cache.test.js +345 -0
- package/dist/cache/__tests__/document-cache.test.js.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
- package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
- package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-store.test.js +367 -0
- package/dist/cache/__tests__/memory-store.test.js.map +1 -0
- package/dist/cache/cache-scope.d.ts +102 -0
- package/dist/cache/cache-scope.d.ts.map +1 -0
- package/dist/cache/cache-scope.js +440 -0
- package/dist/cache/cache-scope.js.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
- package/dist/cache/cf/cf-cache-store.d.ts +165 -0
- package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
- package/dist/cache/cf/cf-cache-store.js +242 -0
- package/dist/cache/cf/cf-cache-store.js.map +1 -0
- package/dist/cache/cf/index.d.ts +14 -0
- package/dist/cache/cf/index.d.ts.map +1 -0
- package/dist/cache/cf/index.js +17 -0
- package/dist/cache/cf/index.js.map +1 -0
- package/dist/cache/document-cache.d.ts +64 -0
- package/dist/cache/document-cache.d.ts.map +1 -0
- package/dist/cache/document-cache.js +228 -0
- package/dist/cache/document-cache.js.map +1 -0
- package/dist/cache/index.d.ts +19 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +21 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory-segment-store.d.ts +110 -0
- package/dist/cache/memory-segment-store.d.ts.map +1 -0
- package/dist/cache/memory-segment-store.js +117 -0
- package/dist/cache/memory-segment-store.js.map +1 -0
- package/dist/cache/memory-store.d.ts +41 -0
- package/dist/cache/memory-store.d.ts.map +1 -0
- package/dist/cache/memory-store.js +191 -0
- package/dist/cache/memory-store.js.map +1 -0
- package/dist/cache/types.d.ts +317 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +12 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/client.d.ts +248 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/client.rsc.d.ts +26 -0
- package/dist/client.rsc.d.ts.map +1 -0
- package/dist/client.rsc.js +46 -0
- package/dist/client.rsc.js.map +1 -0
- package/dist/component-utils.d.ts +36 -0
- package/dist/component-utils.d.ts.map +1 -0
- package/dist/component-utils.js +61 -0
- package/dist/component-utils.js.map +1 -0
- package/dist/components/DefaultDocument.d.ts +13 -0
- package/dist/components/DefaultDocument.d.ts.map +1 -0
- package/dist/components/DefaultDocument.js +15 -0
- package/dist/components/DefaultDocument.js.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +157 -0
- package/dist/debug.js.map +1 -0
- package/dist/default-error-boundary.d.ts +11 -0
- package/dist/default-error-boundary.d.ts.map +1 -0
- package/dist/default-error-boundary.js +45 -0
- package/dist/default-error-boundary.js.map +1 -0
- package/dist/deps/browser.d.ts +2 -0
- package/dist/deps/browser.d.ts.map +1 -0
- package/dist/deps/browser.js +3 -0
- package/dist/deps/browser.js.map +1 -0
- package/dist/deps/html-stream-client.d.ts +2 -0
- package/dist/deps/html-stream-client.d.ts.map +1 -0
- package/dist/deps/html-stream-client.js +3 -0
- package/dist/deps/html-stream-client.js.map +1 -0
- package/dist/deps/html-stream-server.d.ts +2 -0
- package/dist/deps/html-stream-server.d.ts.map +1 -0
- package/dist/deps/html-stream-server.js +3 -0
- package/dist/deps/html-stream-server.js.map +1 -0
- package/dist/deps/rsc.d.ts +2 -0
- package/dist/deps/rsc.d.ts.map +1 -0
- package/dist/deps/rsc.js +4 -0
- package/dist/deps/rsc.js.map +1 -0
- package/dist/deps/ssr.d.ts +2 -0
- package/dist/deps/ssr.d.ts.map +1 -0
- package/dist/deps/ssr.js +3 -0
- package/dist/deps/ssr.js.map +1 -0
- package/dist/errors.d.ts +174 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/handle.d.ts +78 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +82 -0
- package/dist/handle.js.map +1 -0
- package/dist/handles/MetaTags.d.ts +14 -0
- package/dist/handles/MetaTags.d.ts.map +1 -0
- package/dist/handles/MetaTags.js +136 -0
- package/dist/handles/MetaTags.js.map +1 -0
- package/dist/handles/index.d.ts +6 -0
- package/dist/handles/index.d.ts.map +1 -0
- package/dist/handles/index.js +6 -0
- package/dist/handles/index.js.map +1 -0
- package/dist/handles/meta.d.ts +39 -0
- package/dist/handles/meta.d.ts.map +1 -0
- package/dist/handles/meta.js +202 -0
- package/dist/handles/meta.js.map +1 -0
- package/dist/host/__tests__/errors.test.d.ts +2 -0
- package/dist/host/__tests__/errors.test.d.ts.map +1 -0
- package/dist/host/__tests__/errors.test.js +76 -0
- package/dist/host/__tests__/errors.test.js.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.js +251 -0
- package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/host/__tests__/router.test.d.ts +2 -0
- package/dist/host/__tests__/router.test.d.ts.map +1 -0
- package/dist/host/__tests__/router.test.js +241 -0
- package/dist/host/__tests__/router.test.js.map +1 -0
- package/dist/host/__tests__/testing.test.d.ts +2 -0
- package/dist/host/__tests__/testing.test.d.ts.map +1 -0
- package/dist/host/__tests__/testing.test.js +64 -0
- package/dist/host/__tests__/testing.test.js.map +1 -0
- package/dist/host/__tests__/utils.test.d.ts +2 -0
- package/dist/host/__tests__/utils.test.d.ts.map +1 -0
- package/dist/host/__tests__/utils.test.js +29 -0
- package/dist/host/__tests__/utils.test.js.map +1 -0
- package/dist/host/cookie-handler.d.ts +34 -0
- package/dist/host/cookie-handler.d.ts.map +1 -0
- package/dist/host/cookie-handler.js +124 -0
- package/dist/host/cookie-handler.js.map +1 -0
- package/dist/host/errors.d.ts +56 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +79 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +32 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pattern-matcher.d.ts +36 -0
- package/dist/host/pattern-matcher.d.ts.map +1 -0
- package/dist/host/pattern-matcher.js +172 -0
- package/dist/host/pattern-matcher.js.map +1 -0
- package/dist/host/router.d.ts +26 -0
- package/dist/host/router.d.ts.map +1 -0
- package/dist/host/router.js +218 -0
- package/dist/host/router.js.map +1 -0
- package/dist/host/testing.d.ts +36 -0
- package/dist/host/testing.d.ts.map +1 -0
- package/dist/host/testing.js +55 -0
- package/dist/host/testing.js.map +1 -0
- package/dist/host/types.d.ts +115 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/host/utils.d.ts +21 -0
- package/dist/host/utils.d.ts.map +1 -0
- package/dist/host/utils.js +23 -0
- package/dist/host/utils.js.map +1 -0
- package/dist/href-client.d.ts +131 -0
- package/dist/href-client.d.ts.map +1 -0
- package/dist/href-client.js +64 -0
- package/dist/href-client.js.map +1 -0
- package/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 +82 -15
- 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 +19 -18
- package/skills/api-client/SKILL.md +1 -1
- package/skills/breadcrumbs/SKILL.md +1 -1
- package/skills/cache-guide/SKILL.md +1 -1
- package/skills/caching/SKILL.md +17 -1
- package/skills/catalog.json +265 -0
- package/skills/comparison/references/framework-comparison.md +1 -1
- package/skills/composability/SKILL.md +1 -1
- package/skills/debug-manifest/SKILL.md +1 -1
- package/skills/document-cache/SKILL.md +9 -1
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +1 -1
- package/skills/hooks/SKILL.md +54 -892
- 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 +1 -1
- package/skills/i18n/SKILL.md +1 -1
- package/skills/intercept/SKILL.md +8 -1
- package/skills/layout/SKILL.md +1 -1
- package/skills/links/SKILL.md +1 -1
- package/skills/loader/SKILL.md +8 -1
- package/skills/middleware/SKILL.md +1 -1
- package/skills/migrate-nextjs/SKILL.md +133 -1
- package/skills/migrate-react-router/SKILL.md +42 -816
- 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 +1 -1
- package/skills/observability/SKILL.md +1 -1
- package/skills/parallel/SKILL.md +8 -1
- package/skills/ppr/SKILL.md +448 -348
- package/skills/prerender/SKILL.md +8 -1
- package/skills/rango/SKILL.md +14 -14
- package/skills/response-routes/SKILL.md +1 -1
- package/skills/route/SKILL.md +1 -1
- package/skills/router-setup/SKILL.md +1 -1
- package/skills/scripts/SKILL.md +1 -1
- package/skills/server-actions/SKILL.md +3 -2
- package/skills/shell-manifest/SKILL.md +1 -1
- package/skills/streams-and-websockets/SKILL.md +1 -1
- package/skills/tailwind/SKILL.md +1 -1
- package/skills/testing/SKILL.md +1 -1
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +44 -919
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +305 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +7 -1
- package/skills/vercel/SKILL.md +1 -1
- package/skills/view-transitions/SKILL.md +1 -1
- package/src/browser/event-controller.ts +41 -10
- package/src/browser/logging.ts +10 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-client.ts +5 -1
- package/src/browser/navigation-store.ts +46 -6
- package/src/browser/partial-update.ts +27 -15
- package/src/browser/prefetch/cache.ts +26 -4
- package/src/browser/prefetch/fetch.ts +27 -17
- package/src/browser/react/Link.tsx +13 -3
- package/src/browser/react/NavigationProvider.tsx +21 -19
- package/src/browser/scroll-restoration.ts +7 -5
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/types.ts +12 -0
- package/src/cache/cache-runtime.ts +203 -23
- package/src/cache/cf/cf-cache-store.ts +8 -0
- package/src/cache/document-cache.ts +20 -9
- package/src/cache/index.ts +0 -5
- package/src/cache/memory-segment-store.ts +53 -2
- package/src/cache/segment-codec.ts +4 -4
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/types.ts +86 -0
- package/src/cache/vercel/vercel-cache-store.ts +143 -108
- package/src/index.rsc.ts +1 -5
- package/src/index.ts +1 -17
- package/src/router/manifest.ts +13 -5
- package/src/router/match-api.ts +70 -30
- package/src/router/match-handlers.ts +6 -2
- package/src/router/match-result.ts +35 -15
- package/src/router/middleware.ts +10 -3
- package/src/router/request-classification.ts +20 -7
- package/src/router/route-snapshot.ts +10 -0
- package/src/router/segment-resolution/fresh.ts +25 -4
- package/src/router/segment-resolution/loader-cache.ts +57 -8
- package/src/router/segment-resolution/loader-mask.ts +26 -3
- package/src/router/segment-resolution/loader-snapshot.ts +170 -0
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/rsc-rendering.ts +310 -89
- package/src/rsc/shell-capture.ts +707 -66
- package/src/rsc/shell-serve.ts +150 -0
- package/src/server/context.ts +7 -0
- package/src/server/cookie-store.ts +6 -0
- package/src/server/request-context.ts +85 -46
- package/src/ssr/index.tsx +45 -6
- package/src/theme/ThemeProvider.tsx +36 -26
- package/src/urls/index.ts +1 -0
- package/src/urls/path-helper.ts +5 -0
- package/src/urls/pattern-types.ts +36 -0
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/router-discovery.ts +78 -15
- package/src/cache/shell-cache.ts +0 -386
- package/src/server/live.ts +0 -130
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev prerender result cache — memoizes /__rsc_prerender responses between
|
|
3
|
+
* HMR edits (issue #654).
|
|
4
|
+
*
|
|
5
|
+
* Freshness invariant (why identity keying is correct): the endpoint
|
|
6
|
+
* re-imports the user's entry module through a Vite module runner on every
|
|
7
|
+
* request. When ANY module in the entry → router → urls → handler chain was
|
|
8
|
+
* invalidated (file edit propagates up the importer graph), that import
|
|
9
|
+
* re-executes the entry, `createRouter()` re-runs, and `RouterRegistry.set`
|
|
10
|
+
* (router.ts) replaces the router instance with a NEW object. When nothing
|
|
11
|
+
* was invalidated, the import is a module-cache hit and the instance is the
|
|
12
|
+
* SAME object. Router-instance identity therefore IS the HMR generation:
|
|
13
|
+
* keying the cache on it gives "serve cached until an edit invalidates the
|
|
14
|
+
* chain" without any watcher bookkeeping, and the WeakMap lets every stale
|
|
15
|
+
* generation's bucket be garbage-collected the moment the registry drops
|
|
16
|
+
* the old instance.
|
|
17
|
+
*
|
|
18
|
+
* Staleness envelope: a cached body can only go stale through NON-module
|
|
19
|
+
* inputs (a getParams() reading a database, fs content outside the module
|
|
20
|
+
* graph). Production freezes those at build time, so serving them frozen
|
|
21
|
+
* between edits makes dev MORE faithful to production, not less — the
|
|
22
|
+
* pre-#654 behavior of re-rendering per request was the anomaly.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { SerializedSegmentData } from "../../cache/types.js";
|
|
26
|
+
|
|
27
|
+
/** Structural slice of `matchForPrerender`'s result the payload derivation needs. */
|
|
28
|
+
export interface DevPrerenderMatchPayloadSource {
|
|
29
|
+
segments: SerializedSegmentData[];
|
|
30
|
+
handles: string;
|
|
31
|
+
interceptSegments?: SerializedSegmentData[];
|
|
32
|
+
interceptHandles?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Serialized response bodies for the two endpoint variants of one render. */
|
|
36
|
+
export interface DevPrerenderPayloadBodies {
|
|
37
|
+
/** `intercept != 1` response: the route's own segments + handles. */
|
|
38
|
+
main: string;
|
|
39
|
+
/**
|
|
40
|
+
* `intercept=1` response: main + intercept segments with the MERGED handle
|
|
41
|
+
* string. Falls back to `main` byte-for-byte when the route has no
|
|
42
|
+
* intercept segments — mirroring the endpoint's historical behavior.
|
|
43
|
+
*/
|
|
44
|
+
intercept: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface DevPrerenderCache {
|
|
48
|
+
get(router: object, key: string): string | undefined;
|
|
49
|
+
set(router: object, key: string, body: string): void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Derive both variant bodies from one matchForPrerender result, so a single
|
|
54
|
+
* render warms the main AND intercept cache keys (matchForPrerender computes
|
|
55
|
+
* intercept segments unconditionally either way — see prerender-match.ts
|
|
56
|
+
* step 14).
|
|
57
|
+
*/
|
|
58
|
+
export function payloadBodiesFromResult(
|
|
59
|
+
result: DevPrerenderMatchPayloadSource,
|
|
60
|
+
): DevPrerenderPayloadBodies {
|
|
61
|
+
const main = JSON.stringify({
|
|
62
|
+
segments: result.segments,
|
|
63
|
+
handles: result.handles,
|
|
64
|
+
});
|
|
65
|
+
const intercept = result.interceptSegments?.length
|
|
66
|
+
? JSON.stringify({
|
|
67
|
+
segments: [...result.segments, ...result.interceptSegments],
|
|
68
|
+
handles: result.interceptHandles ?? "",
|
|
69
|
+
})
|
|
70
|
+
: main;
|
|
71
|
+
return { main, intercept };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Cache key for one endpoint request shape. `pathname` and `routeName` come
|
|
76
|
+
* straight from the query; `passthrough` selects the getParams-checked match
|
|
77
|
+
* path; `intercept` selects which variant body is served. All four dimensions
|
|
78
|
+
* change the response, so all four are in the key.
|
|
79
|
+
*/
|
|
80
|
+
export function devPrerenderCacheKey(
|
|
81
|
+
pathname: string,
|
|
82
|
+
opts: { intercept: boolean; passthrough: boolean; routeName: string | null },
|
|
83
|
+
): string {
|
|
84
|
+
return `${pathname}|i=${opts.intercept ? 1 : 0}|p=${opts.passthrough ? 1 : 0}|r=${opts.routeName ?? ""}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Per-router FIFO cap: a dev session that visits an unbounded set of
|
|
89
|
+
* prerendered pathnames (e.g. crawling param routes) must not grow one
|
|
90
|
+
* bucket without limit. 500 rendered payloads is far beyond any interactive
|
|
91
|
+
* session; eviction order does not matter for correctness (a miss just
|
|
92
|
+
* re-renders).
|
|
93
|
+
*/
|
|
94
|
+
const MAX_ENTRIES_PER_ROUTER = 500;
|
|
95
|
+
|
|
96
|
+
export function createDevPrerenderCache(
|
|
97
|
+
maxEntriesPerRouter: number = MAX_ENTRIES_PER_ROUTER,
|
|
98
|
+
): DevPrerenderCache {
|
|
99
|
+
const buckets = new WeakMap<object, Map<string, string>>();
|
|
100
|
+
return {
|
|
101
|
+
get(router: object, key: string): string | undefined {
|
|
102
|
+
return buckets.get(router)?.get(key);
|
|
103
|
+
},
|
|
104
|
+
set(router: object, key: string, body: string): void {
|
|
105
|
+
let bucket = buckets.get(router);
|
|
106
|
+
if (!bucket) {
|
|
107
|
+
bucket = new Map();
|
|
108
|
+
buckets.set(router, bucket);
|
|
109
|
+
}
|
|
110
|
+
if (!bucket.has(key) && bucket.size >= maxEntriesPerRouter) {
|
|
111
|
+
const oldest = bucket.keys().next().value;
|
|
112
|
+
if (oldest !== undefined) bucket.delete(oldest);
|
|
113
|
+
}
|
|
114
|
+
bucket.set(key, body);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -44,6 +44,11 @@ import {
|
|
|
44
44
|
} from "./discovery/self-gen-tracking.js";
|
|
45
45
|
import { discoverRouters } from "./discovery/discover-routers.js";
|
|
46
46
|
import { describeDiscoveryFailure } from "./discovery/discovery-errors.js";
|
|
47
|
+
import {
|
|
48
|
+
createDevPrerenderCache,
|
|
49
|
+
devPrerenderCacheKey,
|
|
50
|
+
payloadBodiesFromResult,
|
|
51
|
+
} from "./discovery/dev-prerender-cache.js";
|
|
47
52
|
import {
|
|
48
53
|
writeCombinedRouteTypesWithTracking,
|
|
49
54
|
writeRouteTypesFiles,
|
|
@@ -828,6 +833,15 @@ export function createRouterDiscoveryPlugin(
|
|
|
828
833
|
// Registry from the main server's RSC environment (populated by discoverRouters)
|
|
829
834
|
let mainRegistry: Map<string, any> | null = null;
|
|
830
835
|
|
|
836
|
+
// Memoized /__rsc_prerender render results, keyed by router-instance
|
|
837
|
+
// identity (#654). The per-request entry re-import below is what makes
|
|
838
|
+
// identity a valid freshness key: an HMR-invalidated chain re-runs
|
|
839
|
+
// createRouter() and replaces the registry instance, so cached bodies
|
|
840
|
+
// for the old instance become unreachable; an untouched chain returns
|
|
841
|
+
// the same instance and the cached body is byte-identical to a fresh
|
|
842
|
+
// render. See dev-prerender-cache.ts for the full invariant.
|
|
843
|
+
const devPrerenderCache = createDevPrerenderCache();
|
|
844
|
+
|
|
831
845
|
// Push discovery state (manifest, trie, precomputed entries) to the
|
|
832
846
|
// server module so runtime request handling uses the current routes.
|
|
833
847
|
// Shared by initial discovery and HMR-triggered re-discovery.
|
|
@@ -918,9 +932,28 @@ export function createRouterDiscoveryPlugin(
|
|
|
918
932
|
|
|
919
933
|
if (!registry) {
|
|
920
934
|
// No main registry: the RSC env has no module runner (Cloudflare dev).
|
|
921
|
-
// Lazily create a Node.js temp server for prerender evaluation
|
|
922
|
-
|
|
923
|
-
|
|
935
|
+
// Lazily create a Node.js temp server for prerender evaluation, and
|
|
936
|
+
// re-import the entry through it on EVERY request — the temp server
|
|
937
|
+
// has its own file watcher, so a handler-only edit (a file without
|
|
938
|
+
// urls()/createRouter() that the main watcher's route-file sniff
|
|
939
|
+
// ignores) invalidates its module graph; the re-import re-evaluates
|
|
940
|
+
// exactly the dirty subgraph and re-registers fresh router
|
|
941
|
+
// instances. Before #654 the cached registry was only refreshed on
|
|
942
|
+
// route-file edits, so handler-only edits served stale prerender
|
|
943
|
+
// content on this path. Warm-cache re-imports are module-cache hits.
|
|
944
|
+
const tempRscEnv = await getOrCreateTempServer();
|
|
945
|
+
if (tempRscEnv) {
|
|
946
|
+
try {
|
|
947
|
+
await importEntryAndRegistry(tempRscEnv);
|
|
948
|
+
} catch (err: any) {
|
|
949
|
+
console.warn(
|
|
950
|
+
`[rango] Dev prerender module refresh failed: ${err.message}`,
|
|
951
|
+
);
|
|
952
|
+
res.statusCode = 500;
|
|
953
|
+
res.end(`Prerender handler error: ${err.message}`);
|
|
954
|
+
logResult(500, "temp module refresh failed");
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
924
957
|
}
|
|
925
958
|
registry = prerenderNodeRegistry;
|
|
926
959
|
}
|
|
@@ -936,8 +969,38 @@ export function createRouterDiscoveryPlugin(
|
|
|
936
969
|
const wantRouteName = url.searchParams.get("routeName");
|
|
937
970
|
const wantPassthrough = url.searchParams.get("passthrough") === "1";
|
|
938
971
|
|
|
972
|
+
// One render warms BOTH variant keys (matchForPrerender computes the
|
|
973
|
+
// intercept segments unconditionally), so a route's main and modal
|
|
974
|
+
// variants cost a single render per HMR generation.
|
|
975
|
+
const variantDims = {
|
|
976
|
+
passthrough: wantPassthrough,
|
|
977
|
+
routeName: wantRouteName,
|
|
978
|
+
};
|
|
979
|
+
const keyMain = devPrerenderCacheKey(pathname, {
|
|
980
|
+
intercept: false,
|
|
981
|
+
...variantDims,
|
|
982
|
+
});
|
|
983
|
+
const keyIntercept = devPrerenderCacheKey(pathname, {
|
|
984
|
+
intercept: true,
|
|
985
|
+
...variantDims,
|
|
986
|
+
});
|
|
987
|
+
const requestedKey = wantIntercept ? keyIntercept : keyMain;
|
|
988
|
+
|
|
939
989
|
for (const [, routerInstance] of registry) {
|
|
940
990
|
if (!routerInstance.matchForPrerender) continue;
|
|
991
|
+
// Cache is consulted per router IN LOOP ORDER so multi-router
|
|
992
|
+
// fall-through semantics are identical to the uncached path: a
|
|
993
|
+
// router that never produced a payload for this key still runs
|
|
994
|
+
// its matchForPrerender (cheap trie miss / intentionally-uncached
|
|
995
|
+
// error retry) before the next router is considered.
|
|
996
|
+
const cached = devPrerenderCache.get(routerInstance, requestedKey);
|
|
997
|
+
if (cached !== undefined) {
|
|
998
|
+
res.setHeader("content-type", "application/json");
|
|
999
|
+
res.setHeader("x-rango-prerender-cache", "HIT");
|
|
1000
|
+
res.end(cached);
|
|
1001
|
+
logResult(200, "cache hit");
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
941
1004
|
try {
|
|
942
1005
|
const result = await routerInstance.matchForPrerender(
|
|
943
1006
|
pathname,
|
|
@@ -953,19 +1016,19 @@ export function createRouterDiscoveryPlugin(
|
|
|
953
1016
|
// This prevents returning the wrong entry when multiple routers
|
|
954
1017
|
// have prerenderable routes sharing the same pathname.
|
|
955
1018
|
if (wantRouteName && result.routeName !== wantRouteName) continue;
|
|
1019
|
+
// Pre-encoded MERGED handle string in the intercept body comes
|
|
1020
|
+
// from the producer (handles are Flight-encoded so
|
|
1021
|
+
// Promise/ReactNode values survive the wire).
|
|
1022
|
+
const bodies = payloadBodiesFromResult(result);
|
|
1023
|
+
devPrerenderCache.set(routerInstance, keyMain, bodies.main);
|
|
1024
|
+
devPrerenderCache.set(
|
|
1025
|
+
routerInstance,
|
|
1026
|
+
keyIntercept,
|
|
1027
|
+
bodies.intercept,
|
|
1028
|
+
);
|
|
956
1029
|
res.setHeader("content-type", "application/json");
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
payload = {
|
|
960
|
-
segments: [...result.segments, ...result.interceptSegments],
|
|
961
|
-
// Pre-encoded MERGED handle string from the producer (handles are
|
|
962
|
-
// Flight-encoded so Promise/ReactNode values survive the wire).
|
|
963
|
-
handles: result.interceptHandles ?? "",
|
|
964
|
-
};
|
|
965
|
-
} else {
|
|
966
|
-
payload = { segments: result.segments, handles: result.handles };
|
|
967
|
-
}
|
|
968
|
-
res.end(JSON.stringify(payload));
|
|
1030
|
+
res.setHeader("x-rango-prerender-cache", "MISS");
|
|
1031
|
+
res.end(wantIntercept ? bodies.intercept : bodies.main);
|
|
969
1032
|
logResult(200, `match ${result.routeName}`);
|
|
970
1033
|
return;
|
|
971
1034
|
} catch (err: any) {
|
package/src/cache/shell-cache.ts
DELETED
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PPR Shell Cache Middleware
|
|
3
|
-
*
|
|
4
|
-
* Axis 2 of the two-axis render model (see docs/design/ppr-shell-resume.md).
|
|
5
|
-
* Opt-in middleware that caches the rendered HTML *shell* (React's `prelude`
|
|
6
|
-
* plus the `postponed` state from a static `prerender` abort) and, on a later
|
|
7
|
-
* request, serves those bytes immediately and resumes fizz for just the live
|
|
8
|
-
* holes. The browser sees one ordinary streamed document.
|
|
9
|
-
*
|
|
10
|
-
* The middleware owns only the cheap URL/method gating and the stream
|
|
11
|
-
* composition. The RENDER layer (rsc-rendering, integrated by a later stage) is
|
|
12
|
-
* the final authority on whether a resume actually happens: it reads
|
|
13
|
-
* requestCtx._shellResume, calls the resume strategy, and marks the response
|
|
14
|
-
* with the internal `x-rango-shell-resumed` header ONLY when it truly resumed.
|
|
15
|
-
* This middleware composes the cached prelude in front of the live response ONLY
|
|
16
|
-
* when that marker is present; everything else (redirects, 404s, error renders,
|
|
17
|
-
* nonce/allReady bypasses) flows through untouched — every non-resumed path
|
|
18
|
-
* fails open to axis 1.
|
|
19
|
-
*
|
|
20
|
-
* Flow (the middleware calls next() EXACTLY ONCE on every path — the executor's
|
|
21
|
-
* per-entry next() is a single-use latch, so a second call throws):
|
|
22
|
-
* 1. Bypass matrix (non-GET, _rsc_* params, RSC request, skipPaths, isEnabled,
|
|
23
|
-
* store lacks the shell family) → plain next(), axis 1.
|
|
24
|
-
* 2. getShell(key) HIT + reactVersion matches → arm _shellResume, await next()
|
|
25
|
-
* once. On a stale (SWR) hit, ALSO set the _shellCapture descriptor before
|
|
26
|
-
* that same next() so the render layer schedules a background recapture.
|
|
27
|
-
* - marker present → strip it, prepend prelude bytes, x-rango-shell: HIT.
|
|
28
|
-
* - marker absent → render layer did not resume; return untouched.
|
|
29
|
-
* 3. MISS (or reactVersion mismatch) → set the _shellCapture descriptor before
|
|
30
|
-
* the single next(), stream the live response to the user with
|
|
31
|
-
* x-rango-shell: MISS. The render layer reads the descriptor after building the
|
|
32
|
-
* response and schedules a BACKGROUND capture (via router.match under a derived
|
|
33
|
-
* context — NOT a second next()); see rsc-rendering.ts + shell-capture.ts.
|
|
34
|
-
* The descriptor is cleared in a finally so it never leaks into a reused ctx.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
import React from "react";
|
|
38
|
-
import type { MiddlewareFn, MiddlewareContext } from "../router/middleware.js";
|
|
39
|
-
import {
|
|
40
|
-
getRequestContext,
|
|
41
|
-
type RequestContext,
|
|
42
|
-
} from "../server/request-context.js";
|
|
43
|
-
import { mayNeedSSR } from "../rsc/ssr-setup.js";
|
|
44
|
-
import type { SegmentCacheStore } from "./types.js";
|
|
45
|
-
import { sortedSearchString } from "./cache-key-utils.js";
|
|
46
|
-
import { reportCacheError } from "./cache-error.js";
|
|
47
|
-
|
|
48
|
-
/** Debug/status header the browser (and e2e assertions) can read: HIT | MISS. */
|
|
49
|
-
const SHELL_STATUS_HEADER = "x-rango-shell";
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Internal marker the render layer sets on the live response when — and only
|
|
53
|
-
* when — it actually resumed a cached shell. The middleware composes the prelude
|
|
54
|
-
* in front of the body iff this header is present, then strips it before the
|
|
55
|
-
* response leaves. It is the whole handshake between the middleware (which arms
|
|
56
|
-
* _shellResume optimistically) and the render layer (the final authority).
|
|
57
|
-
*/
|
|
58
|
-
const SHELL_RESUMED_MARKER_HEADER = "x-rango-shell-resumed";
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* React version captured at prerender time is the invalidation gate: a stored
|
|
62
|
-
* shell whose reactVersion differs from the running React cannot be resumed (the
|
|
63
|
-
* postponed blob is build-coupled), so it is treated as a miss. Read once at
|
|
64
|
-
* module load — React.version is stable for the process lifetime.
|
|
65
|
-
*/
|
|
66
|
-
const REACT_VERSION = React.version;
|
|
67
|
-
|
|
68
|
-
/** Decode a base64 prelude back into bytes for stream composition. */
|
|
69
|
-
function base64ToBytes(b64: string): Uint8Array {
|
|
70
|
-
const binary = atob(b64);
|
|
71
|
-
const bytes = new Uint8Array(binary.length);
|
|
72
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
73
|
-
return bytes;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Compose the served response: prelude bytes first, then the live (resumed) body.
|
|
78
|
-
* React relies on HTML-parser foster-parenting for content streamed after the
|
|
79
|
-
* prelude's closing `</body></html>`, so plain byte concatenation is the correct
|
|
80
|
-
* composition (POC item 6) — do not try to reopen or splice the document.
|
|
81
|
-
*
|
|
82
|
-
* Status and headers come from the LIVE next() response: Set-Cookie and friends
|
|
83
|
-
* are per-request and belong to the live pass, not the frozen shell. The internal
|
|
84
|
-
* marker is stripped and x-rango-shell: HIT is added.
|
|
85
|
-
*/
|
|
86
|
-
function composeShellResponse(
|
|
87
|
-
response: Response,
|
|
88
|
-
preludeBase64: string,
|
|
89
|
-
): Response {
|
|
90
|
-
const preludeBytes = base64ToBytes(preludeBase64);
|
|
91
|
-
const body = response.body;
|
|
92
|
-
const composed = new ReadableStream<Uint8Array>({
|
|
93
|
-
async start(controller) {
|
|
94
|
-
controller.enqueue(preludeBytes);
|
|
95
|
-
if (body) {
|
|
96
|
-
const reader = body.getReader();
|
|
97
|
-
try {
|
|
98
|
-
for (;;) {
|
|
99
|
-
const { done, value } = await reader.read();
|
|
100
|
-
if (done) break;
|
|
101
|
-
controller.enqueue(value);
|
|
102
|
-
}
|
|
103
|
-
} finally {
|
|
104
|
-
reader.releaseLock();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
controller.close();
|
|
108
|
-
},
|
|
109
|
-
cancel(reason) {
|
|
110
|
-
// Propagate downstream cancellation to the live body so it does not leak.
|
|
111
|
-
return body?.cancel(reason);
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
const headers = new Headers(response.headers);
|
|
116
|
-
headers.delete(SHELL_RESUMED_MARKER_HEADER);
|
|
117
|
-
headers.set(SHELL_STATUS_HEADER, "HIT");
|
|
118
|
-
return new Response(composed, {
|
|
119
|
-
status: response.status,
|
|
120
|
-
statusText: response.statusText,
|
|
121
|
-
headers,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Clone a response with the x-rango-shell status header added. */
|
|
126
|
-
function withShellStatus(response: Response, status: "HIT" | "MISS"): Response {
|
|
127
|
-
const headers = new Headers(response.headers);
|
|
128
|
-
headers.set(SHELL_STATUS_HEADER, status);
|
|
129
|
-
return new Response(response.body, {
|
|
130
|
-
status: response.status,
|
|
131
|
-
statusText: response.statusText,
|
|
132
|
-
headers,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Options for the PPR shell-cache middleware.
|
|
138
|
-
*/
|
|
139
|
-
export interface ShellCacheOptions<TEnv = any> {
|
|
140
|
-
/**
|
|
141
|
-
* Cache store to use. Defaults to the request context's `_cacheStore`
|
|
142
|
-
* (the app-level store wired via the router's cache config).
|
|
143
|
-
*/
|
|
144
|
-
store?: SegmentCacheStore<TEnv>;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Shell time-to-live in seconds. Defaults to 300.
|
|
148
|
-
*/
|
|
149
|
-
ttlSeconds?: number;
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Stale-while-revalidate window in seconds. On a stale hit the cached shell is
|
|
153
|
-
* still served and a background recapture is scheduled.
|
|
154
|
-
*/
|
|
155
|
-
swrSeconds?: number;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Custom cache key generator. Receives the cleaned request URL. The middleware
|
|
159
|
-
* appends its own `:shell` namespace suffix, so the returned key never collides
|
|
160
|
-
* with a document-cache key.
|
|
161
|
-
*
|
|
162
|
-
* A custom generator owns the FULL key identity, including host scoping: the
|
|
163
|
-
* default key incorporates `url.host` so shells can never leak across tenants
|
|
164
|
-
* in multi-host deployments — include it in custom keys too unless the store
|
|
165
|
-
* is provably single-host.
|
|
166
|
-
*/
|
|
167
|
-
keyGenerator?: (url: URL) => string;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Callback to decide whether shell caching is enabled for this request.
|
|
171
|
-
* Return false to fall through to a normal HTML render (axis 1).
|
|
172
|
-
*/
|
|
173
|
-
isEnabled?: (ctx: MiddlewareContext<TEnv>) => boolean | Promise<boolean>;
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Skip shell caching for specific path prefixes (e.g. admin, API routes).
|
|
177
|
-
*/
|
|
178
|
-
skipPaths?: string[];
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Enable debug logging for shell cache operations (HIT / MISS / CAPTURED).
|
|
182
|
-
* Defaults to false.
|
|
183
|
-
*/
|
|
184
|
-
debug?: boolean;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Create the PPR shell-cache middleware.
|
|
189
|
-
*
|
|
190
|
-
* Add it to a router (or a route subtree) to cache the HTML shell and resume
|
|
191
|
-
* fizz for just the live holes on subsequent requests. Personalization must live
|
|
192
|
-
* in loaders/holes — the shell is shared per URL key (the shell-manifest
|
|
193
|
-
* pattern). Actions, progressive enhancement, formState, and per-request nonce
|
|
194
|
-
* always take axis 1.
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```typescript
|
|
198
|
-
* const router = createRouter<AppEnv>()
|
|
199
|
-
* .use(createShellCacheMiddleware({ ttlSeconds: 600, swrSeconds: 60 }))
|
|
200
|
-
* .route("home", (ctx) => <HomePage />);
|
|
201
|
-
* ```
|
|
202
|
-
*/
|
|
203
|
-
export function createShellCacheMiddleware<TEnv = any>(
|
|
204
|
-
options: ShellCacheOptions<TEnv> = {},
|
|
205
|
-
): MiddlewareFn<TEnv> {
|
|
206
|
-
const {
|
|
207
|
-
ttlSeconds = 300,
|
|
208
|
-
swrSeconds,
|
|
209
|
-
keyGenerator,
|
|
210
|
-
isEnabled,
|
|
211
|
-
skipPaths = [],
|
|
212
|
-
debug = false,
|
|
213
|
-
} = options;
|
|
214
|
-
|
|
215
|
-
const log = debug ? (message: string) => console.log(message) : () => {};
|
|
216
|
-
|
|
217
|
-
return async function shellCacheMiddleware(
|
|
218
|
-
ctx: MiddlewareContext<TEnv>,
|
|
219
|
-
next: () => Promise<Response>,
|
|
220
|
-
): Promise<Response> {
|
|
221
|
-
const url = ctx.url;
|
|
222
|
-
// ctx.url is stripped of _rsc_* params by the pipeline (stripInternalParams);
|
|
223
|
-
// read the raw request URL for internal-param detection, like document-cache.
|
|
224
|
-
const rawUrl = new URL(ctx.request.url);
|
|
225
|
-
|
|
226
|
-
// --- Bypass matrix (each bypass = plain next(), axis 1) ---
|
|
227
|
-
|
|
228
|
-
// Mutations are dynamic — never resume/capture a shell for them.
|
|
229
|
-
if (ctx.request.method !== "GET") return next();
|
|
230
|
-
// RSC action / loader / partial requests are not HTML document requests.
|
|
231
|
-
if (rawUrl.searchParams.has("_rsc_action")) return next();
|
|
232
|
-
if (rawUrl.searchParams.has("_rsc_loader")) return next();
|
|
233
|
-
if (rawUrl.searchParams.has("_rsc_partial")) return next();
|
|
234
|
-
// RSC (Flight) request — the Flight path is untouched by PPR.
|
|
235
|
-
if (!mayNeedSSR(ctx.request, rawUrl)) return next();
|
|
236
|
-
// Consumer opt-outs.
|
|
237
|
-
if (skipPaths.some((path) => url.pathname.startsWith(path))) return next();
|
|
238
|
-
if (isEnabled) {
|
|
239
|
-
const enabled = await isEnabled(ctx);
|
|
240
|
-
if (!enabled) return next();
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const requestCtx = getRequestContext();
|
|
244
|
-
const store = options.store ?? requestCtx?._cacheStore;
|
|
245
|
-
|
|
246
|
-
// Store must implement the shell family — otherwise fail open to axis 1.
|
|
247
|
-
if (!store?.getShell || !store?.putShell) return next();
|
|
248
|
-
|
|
249
|
-
// Track whether next() has been called so the catch block knows whether it is
|
|
250
|
-
// safe to fall through to the handler (mirrors document-cache). cacheKey is
|
|
251
|
-
// assigned inside the try (a throwing keyGenerator must degrade, not 500).
|
|
252
|
-
let handlerCalled = false;
|
|
253
|
-
let cacheKey = "";
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Build the "capture wanted" descriptor. Set on the request context BEFORE
|
|
257
|
-
* the single next() so the render layer can read it after building the
|
|
258
|
-
* response and schedule the background capture (via router.match under a
|
|
259
|
-
* derived context — NOT a second next()). `store` is the SAME store this
|
|
260
|
-
* middleware resolved for getShell, so a store-attached middleware writes
|
|
261
|
-
* captures where it reads them. `tags` is intentionally omitted: the capture
|
|
262
|
-
* collects the shell's own non-loader tags from its derived render.
|
|
263
|
-
*/
|
|
264
|
-
const captureDescriptor = (): NonNullable<
|
|
265
|
-
RequestContext["_shellCapture"]
|
|
266
|
-
> => ({
|
|
267
|
-
key: cacheKey,
|
|
268
|
-
ttl: ttlSeconds,
|
|
269
|
-
swr: swrSeconds,
|
|
270
|
-
store,
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
try {
|
|
274
|
-
// Namespace the key with a `:shell` suffix (mirrors document-cache's
|
|
275
|
-
// `:html`/`:rsc` suffix) so it can never collide with a document-cache key;
|
|
276
|
-
// the store further isolates the shell family internally. Built inside the
|
|
277
|
-
// try so a throwing keyGenerator degrades to a full render, not a 500.
|
|
278
|
-
//
|
|
279
|
-
// The default key includes the request HOST: in a multi-tenant host-router
|
|
280
|
-
// deployment (one worker, one shared KV/runtime-cache store) a host-less
|
|
281
|
-
// key would serve tenant A's captured shell to tenant B's users. The CF
|
|
282
|
-
// document family fixed this exact class at the store tier (toDocKVHost);
|
|
283
|
-
// the shell family fixes it at the key tier so every store is safe.
|
|
284
|
-
let searchSuffix = "";
|
|
285
|
-
if (!keyGenerator) {
|
|
286
|
-
const sorted = sortedSearchString(url.searchParams);
|
|
287
|
-
if (sorted) searchSuffix = `?${sorted}`;
|
|
288
|
-
}
|
|
289
|
-
cacheKey = keyGenerator
|
|
290
|
-
? `${keyGenerator(url)}:shell`
|
|
291
|
-
: `${url.host}${url.pathname}${searchSuffix}:shell`;
|
|
292
|
-
|
|
293
|
-
const cached = await store.getShell(cacheKey);
|
|
294
|
-
const validHit =
|
|
295
|
-
cached != null && cached.entry.reactVersion === REACT_VERSION;
|
|
296
|
-
|
|
297
|
-
if (cached && !validHit) {
|
|
298
|
-
// reactVersion mismatch: the postponed blob is build-coupled and cannot
|
|
299
|
-
// be resumed by the running React. There is no deleteShell primitive in
|
|
300
|
-
// v1, so we simply treat it as a MISS — the recapture below overwrites
|
|
301
|
-
// the same key, and the entry otherwise ages out via TTL.
|
|
302
|
-
log(
|
|
303
|
-
`[ShellCache] MISS ${url.pathname} (reactVersion ${cached.entry.reactVersion} != ${REACT_VERSION})`,
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (validHit) {
|
|
308
|
-
// Arm the resume optimistically. The render layer is the final authority
|
|
309
|
-
// (nonce/formState/allReady bypass); it engages resume and marks the
|
|
310
|
-
// response only when it actually resumed.
|
|
311
|
-
if (requestCtx) {
|
|
312
|
-
requestCtx._shellResume = { postponed: cached!.entry.postponed };
|
|
313
|
-
// SWR: on a stale hit, also request a background recapture by setting
|
|
314
|
-
// the descriptor before this single next(). Resume (foreground) and
|
|
315
|
-
// capture-request (background) legitimately coexist now — the render
|
|
316
|
-
// layer schedules the recapture off the descriptor after building the
|
|
317
|
-
// resumed response. A fresh hit leaves the descriptor unset.
|
|
318
|
-
if (cached!.shouldRevalidate) {
|
|
319
|
-
requestCtx._shellCapture = captureDescriptor();
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
handlerCalled = true;
|
|
323
|
-
let response: Response;
|
|
324
|
-
try {
|
|
325
|
-
response = await next();
|
|
326
|
-
} finally {
|
|
327
|
-
// Always disarm both single-request flags. A next() throw here (resume
|
|
328
|
-
// failure) propagates to the outer catch and rethrows; the
|
|
329
|
-
// version-keyed entry self-heals via axis 1 + recapture on the next
|
|
330
|
-
// request (v1 has no deleteShell to eagerly remove it).
|
|
331
|
-
if (requestCtx) {
|
|
332
|
-
requestCtx._shellResume = undefined;
|
|
333
|
-
requestCtx._shellCapture = undefined;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
if (response.headers.has(SHELL_RESUMED_MARKER_HEADER)) {
|
|
338
|
-
log(`[ShellCache] HIT ${url.pathname}`);
|
|
339
|
-
return composeShellResponse(response, cached!.entry.prelude);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Marker absent: the render layer did NOT resume (redirect, 404, error
|
|
343
|
-
// render, per-request nonce, or allReady buffering). Fail open to axis 1
|
|
344
|
-
// — return the live response untouched. Note: no manual onResponse-
|
|
345
|
-
// callback drain is needed here (or on any path in this middleware),
|
|
346
|
-
// because every path runs a full next() pipeline pass, which already
|
|
347
|
-
// drains those callbacks — unlike document-cache, which serves a fully
|
|
348
|
-
// cached response bypassing next() and must drain them itself.
|
|
349
|
-
log(`[ShellCache] PASS ${url.pathname} (resume not engaged)`);
|
|
350
|
-
return response;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// --- MISS (no entry, or reactVersion mismatch) ---
|
|
354
|
-
// Set the "capture wanted" descriptor before the single next(). The render
|
|
355
|
-
// layer reads it after building the response and, if the response is a
|
|
356
|
-
// servable 200 HTML document, schedules a BACKGROUND capture (router.match
|
|
357
|
-
// under a derived context — never a second next()). The descriptor's mere
|
|
358
|
-
// presence does not change the foreground render (loader masking keys off
|
|
359
|
-
// _shellCaptureRun, which only the background derived context sets).
|
|
360
|
-
if (requestCtx) requestCtx._shellCapture = captureDescriptor();
|
|
361
|
-
handlerCalled = true;
|
|
362
|
-
let response: Response;
|
|
363
|
-
try {
|
|
364
|
-
response = await next();
|
|
365
|
-
} finally {
|
|
366
|
-
// Clear the descriptor so it never leaks into a reused ctx. The render
|
|
367
|
-
// layer already read it (synchronously, inside next()) and captured its
|
|
368
|
-
// own reference for the background task, so clearing here is safe.
|
|
369
|
-
if (requestCtx) requestCtx._shellCapture = undefined;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
log(`[ShellCache] MISS ${url.pathname}`);
|
|
373
|
-
return withShellStatus(response, "MISS");
|
|
374
|
-
} catch (error) {
|
|
375
|
-
reportCacheError(error, "cache-read", "[ShellCache] middleware");
|
|
376
|
-
if (handlerCalled) {
|
|
377
|
-
// Post-handler failure (resume/render throw, or a stream error): do not
|
|
378
|
-
// call next() again — that would re-run handler side effects.
|
|
379
|
-
throw error;
|
|
380
|
-
}
|
|
381
|
-
// Pre-handler failure (cache lookup / key generation): degrade to a full
|
|
382
|
-
// render.
|
|
383
|
-
return next();
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
}
|