@rangojs/router 0.0.0-experimental.2 → 0.0.0-experimental.204030a9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -0
- package/README.md +1037 -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/{src/__mocks__/version.ts → dist/__mocks__/version.js} +1 -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 +1779 -0
- package/dist/bin/rango.js.map +1 -0
- package/dist/browser/event-controller.d.ts +191 -0
- package/dist/browser/event-controller.d.ts.map +1 -0
- package/dist/browser/event-controller.js +559 -0
- package/dist/browser/event-controller.js.map +1 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/link-interceptor.d.ts +38 -0
- package/dist/browser/link-interceptor.d.ts.map +1 -0
- package/dist/browser/link-interceptor.js +99 -0
- package/dist/browser/link-interceptor.js.map +1 -0
- package/dist/browser/logging.d.ts +10 -0
- package/dist/browser/logging.d.ts.map +1 -0
- package/dist/browser/logging.js +29 -0
- package/dist/browser/logging.js.map +1 -0
- package/dist/browser/lru-cache.d.ts +17 -0
- package/dist/browser/lru-cache.d.ts.map +1 -0
- package/dist/browser/lru-cache.js +50 -0
- package/dist/browser/lru-cache.js.map +1 -0
- package/dist/browser/merge-segment-loaders.d.ts +39 -0
- package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
- package/dist/browser/merge-segment-loaders.js +102 -0
- package/dist/browser/merge-segment-loaders.js.map +1 -0
- package/dist/browser/navigation-bridge.d.ts +102 -0
- package/dist/browser/navigation-bridge.d.ts.map +1 -0
- package/dist/browser/navigation-bridge.js +708 -0
- package/dist/browser/navigation-bridge.js.map +1 -0
- package/dist/browser/navigation-client.d.ts +25 -0
- package/dist/browser/navigation-client.d.ts.map +1 -0
- package/dist/browser/navigation-client.js +157 -0
- package/dist/browser/navigation-client.js.map +1 -0
- package/dist/browser/navigation-store.d.ts +101 -0
- package/dist/browser/navigation-store.d.ts.map +1 -0
- package/dist/browser/navigation-store.js +625 -0
- package/dist/browser/navigation-store.js.map +1 -0
- package/dist/browser/partial-update.d.ts +75 -0
- package/dist/browser/partial-update.d.ts.map +1 -0
- package/dist/browser/partial-update.js +426 -0
- package/dist/browser/partial-update.js.map +1 -0
- package/dist/browser/react/Link.d.ts +86 -0
- package/dist/browser/react/Link.d.ts.map +1 -0
- package/dist/browser/react/Link.js +128 -0
- package/dist/browser/react/Link.js.map +1 -0
- package/dist/browser/react/NavigationProvider.d.ts +63 -0
- package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
- package/dist/browser/react/NavigationProvider.js +216 -0
- package/dist/browser/react/NavigationProvider.js.map +1 -0
- package/dist/browser/react/ScrollRestoration.d.ts +75 -0
- package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
- package/dist/browser/react/ScrollRestoration.js +57 -0
- package/dist/browser/react/ScrollRestoration.js.map +1 -0
- package/dist/browser/react/context.d.ts +46 -0
- package/dist/browser/react/context.d.ts.map +1 -0
- package/dist/browser/react/context.js +10 -0
- package/dist/browser/react/context.js.map +1 -0
- package/dist/browser/react/index.d.ts +11 -0
- package/dist/browser/react/index.d.ts.map +1 -0
- package/dist/browser/react/index.js +22 -0
- package/dist/browser/react/index.js.map +1 -0
- package/dist/browser/react/location-state-shared.d.ts +63 -0
- package/dist/browser/react/location-state-shared.d.ts.map +1 -0
- package/dist/browser/react/location-state-shared.js +81 -0
- package/dist/browser/react/location-state-shared.js.map +1 -0
- package/dist/browser/react/location-state.d.ts +23 -0
- package/dist/browser/react/location-state.d.ts.map +1 -0
- package/dist/browser/react/location-state.js +29 -0
- package/dist/browser/react/location-state.js.map +1 -0
- package/dist/browser/react/mount-context.d.ts +24 -0
- package/dist/browser/react/mount-context.d.ts.map +1 -0
- package/dist/browser/react/mount-context.js +24 -0
- package/dist/browser/react/mount-context.js.map +1 -0
- package/dist/browser/react/use-action.d.ts +64 -0
- package/dist/browser/react/use-action.d.ts.map +1 -0
- package/dist/browser/react/use-action.js +134 -0
- package/dist/browser/react/use-action.js.map +1 -0
- package/dist/browser/react/use-client-cache.d.ts +41 -0
- package/dist/browser/react/use-client-cache.d.ts.map +1 -0
- package/dist/browser/react/use-client-cache.js +39 -0
- package/dist/browser/react/use-client-cache.js.map +1 -0
- package/dist/browser/react/use-handle.d.ts +31 -0
- package/dist/browser/react/use-handle.d.ts.map +1 -0
- package/dist/browser/react/use-handle.js +144 -0
- package/dist/browser/react/use-handle.js.map +1 -0
- package/dist/browser/react/use-href.d.ts +33 -0
- package/dist/browser/react/use-href.d.ts.map +1 -0
- package/dist/browser/react/use-href.js +39 -0
- package/dist/browser/react/use-href.js.map +1 -0
- package/dist/browser/react/use-link-status.d.ts +37 -0
- package/dist/browser/react/use-link-status.d.ts.map +1 -0
- package/dist/browser/react/use-link-status.js +99 -0
- package/dist/browser/react/use-link-status.js.map +1 -0
- package/dist/browser/react/use-mount.d.ts +25 -0
- package/dist/browser/react/use-mount.d.ts.map +1 -0
- package/dist/browser/react/use-mount.js +30 -0
- package/dist/browser/react/use-mount.js.map +1 -0
- package/dist/browser/react/use-navigation.d.ts +27 -0
- package/dist/browser/react/use-navigation.d.ts.map +1 -0
- package/dist/browser/react/use-navigation.js +87 -0
- package/dist/browser/react/use-navigation.js.map +1 -0
- package/dist/browser/react/use-segments.d.ts +38 -0
- package/dist/browser/react/use-segments.d.ts.map +1 -0
- package/dist/browser/react/use-segments.js +130 -0
- package/dist/browser/react/use-segments.js.map +1 -0
- package/dist/browser/request-controller.d.ts +26 -0
- package/dist/browser/request-controller.d.ts.map +1 -0
- package/dist/browser/request-controller.js +147 -0
- package/dist/browser/request-controller.js.map +1 -0
- package/dist/browser/rsc-router.d.ts +129 -0
- package/dist/browser/rsc-router.d.ts.map +1 -0
- package/dist/browser/rsc-router.js +195 -0
- package/dist/browser/rsc-router.js.map +1 -0
- package/dist/browser/scroll-restoration.d.ts +93 -0
- package/dist/browser/scroll-restoration.d.ts.map +1 -0
- package/dist/browser/scroll-restoration.js +321 -0
- package/dist/browser/scroll-restoration.js.map +1 -0
- package/dist/browser/segment-structure-assert.d.ts +17 -0
- package/dist/browser/segment-structure-assert.d.ts.map +1 -0
- package/dist/browser/segment-structure-assert.js +59 -0
- package/dist/browser/segment-structure-assert.js.map +1 -0
- package/dist/browser/server-action-bridge.d.ts +26 -0
- package/dist/browser/server-action-bridge.d.ts.map +1 -0
- package/dist/browser/server-action-bridge.js +668 -0
- package/dist/browser/server-action-bridge.js.map +1 -0
- package/dist/browser/shallow.d.ts +12 -0
- package/dist/browser/shallow.d.ts.map +1 -0
- package/dist/browser/shallow.js +34 -0
- package/dist/browser/shallow.js.map +1 -0
- package/dist/browser/types.d.ts +369 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
- package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-cli.test.js +237 -0
- package/dist/build/__tests__/generate-cli.test.js.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.js +119 -0
- package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.js +620 -0
- package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.js +308 -0
- package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +81 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +276 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/build/generate-route-types.d.ts +115 -0
- package/dist/build/generate-route-types.d.ts.map +1 -0
- package/dist/build/generate-route-types.js +740 -0
- package/dist/build/generate-route-types.js.map +1 -0
- package/dist/build/index.d.ts +21 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +21 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/route-trie.d.ts +71 -0
- package/dist/build/route-trie.d.ts.map +1 -0
- package/dist/build/route-trie.js +175 -0
- package/dist/build/route-trie.js.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.js +208 -0
- package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
- package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
- package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
- package/dist/cache/__tests__/document-cache.test.js +345 -0
- package/dist/cache/__tests__/document-cache.test.js.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
- package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
- package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-store.test.js +367 -0
- package/dist/cache/__tests__/memory-store.test.js.map +1 -0
- package/dist/cache/cache-scope.d.ts +102 -0
- package/dist/cache/cache-scope.d.ts.map +1 -0
- package/dist/cache/cache-scope.js +440 -0
- package/dist/cache/cache-scope.js.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
- package/dist/cache/cf/cf-cache-store.d.ts +165 -0
- package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
- package/dist/cache/cf/cf-cache-store.js +242 -0
- package/dist/cache/cf/cf-cache-store.js.map +1 -0
- package/dist/cache/cf/index.d.ts +14 -0
- package/dist/cache/cf/index.d.ts.map +1 -0
- package/dist/cache/cf/index.js +17 -0
- package/dist/cache/cf/index.js.map +1 -0
- package/dist/cache/document-cache.d.ts +64 -0
- package/dist/cache/document-cache.d.ts.map +1 -0
- package/dist/cache/document-cache.js +228 -0
- package/dist/cache/document-cache.js.map +1 -0
- package/dist/cache/index.d.ts +19 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +21 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory-segment-store.d.ts +110 -0
- package/dist/cache/memory-segment-store.d.ts.map +1 -0
- package/dist/cache/memory-segment-store.js +117 -0
- package/dist/cache/memory-segment-store.js.map +1 -0
- package/dist/cache/memory-store.d.ts +41 -0
- package/dist/cache/memory-store.d.ts.map +1 -0
- package/dist/cache/memory-store.js +191 -0
- package/dist/cache/memory-store.js.map +1 -0
- package/dist/cache/types.d.ts +317 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +12 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/client.d.ts +248 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/client.rsc.d.ts +26 -0
- package/dist/client.rsc.d.ts.map +1 -0
- package/dist/client.rsc.js +46 -0
- package/dist/client.rsc.js.map +1 -0
- package/dist/component-utils.d.ts +36 -0
- package/dist/component-utils.d.ts.map +1 -0
- package/dist/component-utils.js +61 -0
- package/dist/component-utils.js.map +1 -0
- package/dist/components/DefaultDocument.d.ts +13 -0
- package/dist/components/DefaultDocument.d.ts.map +1 -0
- package/dist/components/DefaultDocument.js +15 -0
- package/dist/components/DefaultDocument.js.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +157 -0
- package/dist/debug.js.map +1 -0
- package/dist/default-error-boundary.d.ts +11 -0
- package/dist/default-error-boundary.d.ts.map +1 -0
- package/dist/default-error-boundary.js +45 -0
- package/dist/default-error-boundary.js.map +1 -0
- package/dist/deps/browser.d.ts +2 -0
- package/dist/deps/browser.d.ts.map +1 -0
- package/dist/deps/browser.js +3 -0
- package/dist/deps/browser.js.map +1 -0
- package/dist/deps/html-stream-client.d.ts +2 -0
- package/dist/deps/html-stream-client.d.ts.map +1 -0
- package/dist/deps/html-stream-client.js +3 -0
- package/dist/deps/html-stream-client.js.map +1 -0
- package/dist/deps/html-stream-server.d.ts +2 -0
- package/dist/deps/html-stream-server.d.ts.map +1 -0
- package/dist/deps/html-stream-server.js +3 -0
- package/dist/deps/html-stream-server.js.map +1 -0
- package/dist/deps/rsc.d.ts +2 -0
- package/dist/deps/rsc.d.ts.map +1 -0
- package/dist/deps/rsc.js +4 -0
- package/dist/deps/rsc.js.map +1 -0
- package/dist/deps/ssr.d.ts +2 -0
- package/dist/deps/ssr.d.ts.map +1 -0
- package/dist/deps/ssr.js +3 -0
- package/dist/deps/ssr.js.map +1 -0
- package/dist/errors.d.ts +174 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/handle.d.ts +78 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +82 -0
- package/dist/handle.js.map +1 -0
- package/dist/handles/MetaTags.d.ts +14 -0
- package/dist/handles/MetaTags.d.ts.map +1 -0
- package/dist/handles/MetaTags.js +136 -0
- package/dist/handles/MetaTags.js.map +1 -0
- package/dist/handles/index.d.ts +6 -0
- package/dist/handles/index.d.ts.map +1 -0
- package/dist/handles/index.js +6 -0
- package/dist/handles/index.js.map +1 -0
- package/dist/handles/meta.d.ts +39 -0
- package/dist/handles/meta.d.ts.map +1 -0
- package/dist/handles/meta.js +202 -0
- package/dist/handles/meta.js.map +1 -0
- package/dist/host/__tests__/errors.test.d.ts +2 -0
- package/dist/host/__tests__/errors.test.d.ts.map +1 -0
- package/dist/host/__tests__/errors.test.js +76 -0
- package/dist/host/__tests__/errors.test.js.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.js +251 -0
- package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/host/__tests__/router.test.d.ts +2 -0
- package/dist/host/__tests__/router.test.d.ts.map +1 -0
- package/dist/host/__tests__/router.test.js +241 -0
- package/dist/host/__tests__/router.test.js.map +1 -0
- package/dist/host/__tests__/testing.test.d.ts +2 -0
- package/dist/host/__tests__/testing.test.d.ts.map +1 -0
- package/dist/host/__tests__/testing.test.js +64 -0
- package/dist/host/__tests__/testing.test.js.map +1 -0
- package/dist/host/__tests__/utils.test.d.ts +2 -0
- package/dist/host/__tests__/utils.test.d.ts.map +1 -0
- package/dist/host/__tests__/utils.test.js +29 -0
- package/dist/host/__tests__/utils.test.js.map +1 -0
- package/dist/host/cookie-handler.d.ts +34 -0
- package/dist/host/cookie-handler.d.ts.map +1 -0
- package/dist/host/cookie-handler.js +124 -0
- package/dist/host/cookie-handler.js.map +1 -0
- package/dist/host/errors.d.ts +56 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +79 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +32 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pattern-matcher.d.ts +36 -0
- package/dist/host/pattern-matcher.d.ts.map +1 -0
- package/dist/host/pattern-matcher.js +172 -0
- package/dist/host/pattern-matcher.js.map +1 -0
- package/dist/host/router.d.ts +26 -0
- package/dist/host/router.d.ts.map +1 -0
- package/dist/host/router.js +218 -0
- package/dist/host/router.js.map +1 -0
- package/dist/host/testing.d.ts +36 -0
- package/dist/host/testing.d.ts.map +1 -0
- package/dist/host/testing.js +55 -0
- package/dist/host/testing.js.map +1 -0
- package/dist/host/types.d.ts +115 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/host/utils.d.ts +21 -0
- package/dist/host/utils.d.ts.map +1 -0
- package/dist/host/utils.js +23 -0
- package/dist/host/utils.js.map +1 -0
- package/dist/href-client.d.ts +131 -0
- package/dist/href-client.d.ts.map +1 -0
- package/dist/href-client.js +64 -0
- package/dist/href-client.js.map +1 -0
- package/{src/href-context.ts → dist/href-context.d.ts} +7 -11
- package/dist/href-context.d.ts.map +1 -0
- package/dist/href-context.js +21 -0
- package/dist/href-context.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/index.rsc.d.ts +32 -0
- package/dist/index.rsc.d.ts.map +1 -0
- package/dist/index.rsc.js +40 -0
- package/dist/index.rsc.js.map +1 -0
- package/dist/internal-debug.d.ts +2 -0
- package/dist/internal-debug.d.ts.map +1 -0
- package/dist/internal-debug.js +5 -0
- package/dist/internal-debug.js.map +1 -0
- package/dist/loader.d.ts +14 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +20 -0
- package/dist/loader.js.map +1 -0
- package/dist/loader.rsc.d.ts +19 -0
- package/dist/loader.rsc.d.ts.map +1 -0
- package/dist/loader.rsc.js +99 -0
- package/dist/loader.rsc.js.map +1 -0
- package/dist/network-error-thrower.d.ts +17 -0
- package/dist/network-error-thrower.d.ts.map +1 -0
- package/dist/network-error-thrower.js +14 -0
- package/dist/network-error-thrower.js.map +1 -0
- package/dist/outlet-context.d.ts +13 -0
- package/dist/outlet-context.d.ts.map +1 -0
- package/dist/outlet-context.js +3 -0
- package/dist/outlet-context.js.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.js +148 -0
- package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
- package/dist/prerender/param-hash.d.ts +16 -0
- package/dist/prerender/param-hash.d.ts.map +1 -0
- package/dist/prerender/param-hash.js +36 -0
- package/dist/prerender/param-hash.js.map +1 -0
- package/dist/prerender/store.d.ts +38 -0
- package/dist/prerender/store.d.ts.map +1 -0
- package/dist/prerender/store.js +61 -0
- package/dist/prerender/store.js.map +1 -0
- package/dist/prerender.d.ts +66 -0
- package/dist/prerender.d.ts.map +1 -0
- package/dist/prerender.js +57 -0
- package/dist/prerender.js.map +1 -0
- package/dist/reverse.d.ts +196 -0
- package/dist/reverse.d.ts.map +1 -0
- package/dist/reverse.js +78 -0
- package/dist/reverse.js.map +1 -0
- package/dist/root-error-boundary.d.ts +33 -0
- package/dist/root-error-boundary.d.ts.map +1 -0
- package/dist/root-error-boundary.js +165 -0
- package/dist/root-error-boundary.js.map +1 -0
- package/dist/route-content-wrapper.d.ts +46 -0
- package/dist/route-content-wrapper.d.ts.map +1 -0
- package/dist/route-content-wrapper.js +77 -0
- package/dist/route-content-wrapper.js.map +1 -0
- package/dist/route-definition.d.ts +421 -0
- package/dist/route-definition.d.ts.map +1 -0
- package/dist/route-definition.js +868 -0
- package/dist/route-definition.js.map +1 -0
- package/dist/route-map-builder.d.ts +155 -0
- package/dist/route-map-builder.d.ts.map +1 -0
- package/dist/route-map-builder.js +237 -0
- package/dist/route-map-builder.js.map +1 -0
- package/dist/route-types.d.ts +165 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +7 -0
- package/dist/route-types.js.map +1 -0
- package/dist/router/__tests__/handler-context.test.d.ts +2 -0
- package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/handler-context.test.js +65 -0
- package/dist/router/__tests__/handler-context.test.js.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
- package/dist/router/__tests__/match-context.test.d.ts +2 -0
- package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-context.test.js +92 -0
- package/dist/router/__tests__/match-context.test.js.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.js +417 -0
- package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
- package/dist/router/__tests__/match-result.test.d.ts +2 -0
- package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-result.test.js +457 -0
- package/dist/router/__tests__/match-result.test.js.map +1 -0
- package/dist/router/__tests__/on-error.test.d.ts +2 -0
- package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
- package/dist/router/__tests__/on-error.test.js +678 -0
- package/dist/router/__tests__/on-error.test.js.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.js +629 -0
- package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
- package/dist/router/error-handling.d.ts +77 -0
- package/dist/router/error-handling.d.ts.map +1 -0
- package/dist/router/error-handling.js +202 -0
- package/dist/router/error-handling.js.map +1 -0
- package/dist/router/handler-context.d.ts +20 -0
- package/dist/router/handler-context.d.ts.map +1 -0
- package/dist/router/handler-context.js +198 -0
- package/dist/router/handler-context.js.map +1 -0
- package/dist/router/intercept-resolution.d.ts +66 -0
- package/dist/router/intercept-resolution.d.ts.map +1 -0
- package/dist/router/intercept-resolution.js +246 -0
- package/dist/router/intercept-resolution.js.map +1 -0
- package/dist/router/loader-resolution.d.ts +64 -0
- package/dist/router/loader-resolution.d.ts.map +1 -0
- package/dist/router/loader-resolution.js +284 -0
- package/dist/router/loader-resolution.js.map +1 -0
- package/dist/router/logging.d.ts +15 -0
- package/dist/router/logging.d.ts.map +1 -0
- package/dist/router/logging.js +99 -0
- package/dist/router/logging.js.map +1 -0
- package/dist/router/manifest.d.ts +22 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +181 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/router/match-api.d.ts +35 -0
- package/dist/router/match-api.d.ts.map +1 -0
- package/dist/router/match-api.js +406 -0
- package/dist/router/match-api.js.map +1 -0
- package/dist/router/match-context.d.ts +206 -0
- package/dist/router/match-context.d.ts.map +1 -0
- package/dist/router/match-context.js +17 -0
- package/dist/router/match-context.js.map +1 -0
- package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
- package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
- package/dist/router/match-middleware/background-revalidation.js +75 -0
- package/dist/router/match-middleware/background-revalidation.js.map +1 -0
- package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
- package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-lookup.js +257 -0
- package/dist/router/match-middleware/cache-lookup.js.map +1 -0
- package/dist/router/match-middleware/cache-store.d.ts +113 -0
- package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-store.js +108 -0
- package/dist/router/match-middleware/cache-store.js.map +1 -0
- package/dist/router/match-middleware/index.d.ts +81 -0
- package/dist/router/match-middleware/index.d.ts.map +1 -0
- package/dist/router/match-middleware/index.js +80 -0
- package/dist/router/match-middleware/index.js.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.js +134 -0
- package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
- package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
- package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/segment-resolution.js +53 -0
- package/dist/router/match-middleware/segment-resolution.js.map +1 -0
- package/dist/router/match-pipelines.d.ts +147 -0
- package/dist/router/match-pipelines.d.ts.map +1 -0
- package/dist/router/match-pipelines.js +82 -0
- package/dist/router/match-pipelines.js.map +1 -0
- package/dist/router/match-result.d.ts +126 -0
- package/dist/router/match-result.d.ts.map +1 -0
- package/dist/router/match-result.js +93 -0
- package/dist/router/match-result.js.map +1 -0
- package/dist/router/metrics.d.ts +20 -0
- package/dist/router/metrics.d.ts.map +1 -0
- package/dist/router/metrics.js +47 -0
- package/dist/router/metrics.js.map +1 -0
- package/dist/router/middleware.d.ts +249 -0
- package/dist/router/middleware.d.ts.map +1 -0
- package/dist/router/middleware.js +434 -0
- package/dist/router/middleware.js.map +1 -0
- package/dist/router/middleware.test.d.ts +2 -0
- package/dist/router/middleware.test.d.ts.map +1 -0
- package/dist/router/middleware.test.js +816 -0
- package/dist/router/middleware.test.js.map +1 -0
- package/dist/router/pattern-matching.d.ts +149 -0
- package/dist/router/pattern-matching.d.ts.map +1 -0
- package/dist/router/pattern-matching.js +349 -0
- package/dist/router/pattern-matching.js.map +1 -0
- package/dist/router/revalidation.d.ts +44 -0
- package/dist/router/revalidation.d.ts.map +1 -0
- package/dist/router/revalidation.js +147 -0
- package/dist/router/revalidation.js.map +1 -0
- package/dist/router/router-context.d.ts +135 -0
- package/dist/router/router-context.d.ts.map +1 -0
- package/dist/router/router-context.js +36 -0
- package/dist/router/router-context.js.map +1 -0
- package/dist/router/segment-resolution.d.ts +127 -0
- package/dist/router/segment-resolution.d.ts.map +1 -0
- package/dist/router/segment-resolution.js +919 -0
- package/dist/router/segment-resolution.js.map +1 -0
- package/dist/router/trie-matching.d.ts +40 -0
- package/dist/router/trie-matching.d.ts.map +1 -0
- package/dist/router/trie-matching.js +127 -0
- package/dist/router/trie-matching.js.map +1 -0
- package/dist/router/types.d.ts +136 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +7 -0
- package/dist/router/types.js.map +1 -0
- package/dist/router.d.ts +753 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.gen.d.ts +6 -0
- package/dist/router.gen.d.ts.map +1 -0
- package/dist/router.gen.js +6 -0
- package/dist/router.gen.js.map +1 -0
- package/dist/router.js +1304 -0
- package/dist/router.js.map +1 -0
- package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
- package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
- package/dist/rsc/__tests__/helpers.test.js +140 -0
- package/dist/rsc/__tests__/helpers.test.js.map +1 -0
- package/dist/rsc/handler.d.ts +45 -0
- package/dist/rsc/handler.d.ts.map +1 -0
- package/dist/rsc/handler.js +1172 -0
- package/dist/rsc/handler.js.map +1 -0
- package/dist/rsc/helpers.d.ts +16 -0
- package/dist/rsc/helpers.d.ts.map +1 -0
- package/dist/rsc/helpers.js +55 -0
- package/dist/rsc/helpers.js.map +1 -0
- package/dist/rsc/index.d.ts +22 -0
- package/dist/rsc/index.d.ts.map +1 -0
- package/dist/rsc/index.js +23 -0
- package/dist/rsc/index.js.map +1 -0
- package/dist/rsc/nonce.d.ts +9 -0
- package/dist/rsc/nonce.d.ts.map +1 -0
- package/dist/rsc/nonce.js +18 -0
- package/dist/rsc/nonce.js.map +1 -0
- package/dist/rsc/types.d.ts +206 -0
- package/dist/rsc/types.d.ts.map +1 -0
- package/dist/rsc/types.js +8 -0
- package/dist/rsc/types.js.map +1 -0
- package/dist/search-params.d.ts +103 -0
- package/dist/search-params.d.ts.map +1 -0
- package/dist/search-params.js +74 -0
- package/dist/search-params.js.map +1 -0
- package/dist/segment-system.d.ts +75 -0
- package/dist/segment-system.d.ts.map +1 -0
- package/dist/segment-system.js +336 -0
- package/dist/segment-system.js.map +1 -0
- package/dist/server/context.d.ts +245 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +197 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/fetchable-loader-store.d.ts +18 -0
- package/dist/server/fetchable-loader-store.d.ts.map +1 -0
- package/dist/server/fetchable-loader-store.js +18 -0
- package/dist/server/fetchable-loader-store.js.map +1 -0
- package/dist/server/handle-store.d.ts +85 -0
- package/dist/server/handle-store.d.ts.map +1 -0
- package/dist/server/handle-store.js +142 -0
- package/dist/server/handle-store.js.map +1 -0
- package/dist/server/loader-registry.d.ts +55 -0
- package/dist/server/loader-registry.d.ts.map +1 -0
- package/dist/server/loader-registry.js +132 -0
- package/dist/server/loader-registry.js.map +1 -0
- package/dist/server/request-context.d.ts +226 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +290 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/root-layout.d.ts +4 -0
- package/dist/server/root-layout.d.ts.map +1 -0
- package/dist/server/root-layout.js +5 -0
- package/dist/server/root-layout.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +20 -0
- package/dist/server.js.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
- package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
- package/dist/ssr/index.d.ts +98 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +158 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/static-handler.d.ts +50 -0
- package/dist/static-handler.d.ts.map +1 -0
- package/dist/static-handler.gen.d.ts +5 -0
- package/dist/static-handler.gen.d.ts.map +1 -0
- package/dist/static-handler.gen.js +5 -0
- package/dist/static-handler.gen.js.map +1 -0
- package/dist/static-handler.js +29 -0
- package/dist/static-handler.js.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +20 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +240 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/ThemeScript.d.ts +48 -0
- package/dist/theme/ThemeScript.d.ts.map +1 -0
- package/dist/theme/ThemeScript.js +13 -0
- package/dist/theme/ThemeScript.js.map +1 -0
- package/dist/theme/__tests__/theme.test.d.ts +2 -0
- package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
- package/dist/theme/__tests__/theme.test.js +103 -0
- package/dist/theme/__tests__/theme.test.js.map +1 -0
- package/dist/theme/constants.d.ts +29 -0
- package/dist/theme/constants.d.ts.map +1 -0
- package/dist/theme/constants.js +48 -0
- package/dist/theme/constants.js.map +1 -0
- package/dist/theme/index.d.ts +31 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +36 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-context.d.ts +40 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +60 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-script.d.ts +27 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +147 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/dist/theme/types.d.ts +163 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +11 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme/use-theme.d.ts +12 -0
- package/dist/theme/use-theme.d.ts.map +1 -0
- package/dist/theme/use-theme.js +40 -0
- package/dist/theme/use-theme.js.map +1 -0
- package/dist/types.d.ts +1479 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/urls.d.ts +441 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.gen.d.ts +8 -0
- package/dist/urls.gen.d.ts.map +1 -0
- package/dist/urls.gen.js +8 -0
- package/dist/urls.gen.js.map +1 -0
- package/dist/urls.js +443 -0
- package/dist/urls.js.map +1 -0
- package/dist/use-loader.d.ts +127 -0
- package/dist/use-loader.d.ts.map +1 -0
- package/dist/use-loader.js +237 -0
- package/dist/use-loader.js.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
- package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.js +39 -0
- package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
- package/dist/vite/ast-handler-extract.d.ts +49 -0
- package/dist/vite/ast-handler-extract.d.ts.map +1 -0
- package/dist/vite/ast-handler-extract.js +249 -0
- package/dist/vite/ast-handler-extract.js.map +1 -0
- package/dist/vite/expose-action-id.d.ts +19 -0
- package/dist/vite/expose-action-id.d.ts.map +1 -0
- package/dist/vite/expose-action-id.js +250 -0
- package/dist/vite/expose-action-id.js.map +1 -0
- package/dist/vite/expose-id-utils.d.ts +69 -0
- package/dist/vite/expose-id-utils.d.ts.map +1 -0
- package/dist/vite/expose-id-utils.js +289 -0
- package/dist/vite/expose-id-utils.js.map +1 -0
- package/dist/vite/expose-internal-ids.d.ts +22 -0
- package/dist/vite/expose-internal-ids.d.ts.map +1 -0
- package/dist/vite/expose-internal-ids.js +886 -0
- package/dist/vite/expose-internal-ids.js.map +1 -0
- package/dist/vite/index.d.ts +149 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +6440 -809
- 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/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
- package/dist/vite/package-resolution.js.map +1 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/dist/vite/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +18 -17
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +140 -57
- package/skills/breadcrumbs/SKILL.md +252 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +484 -0
- package/skills/caching/SKILL.md +276 -226
- package/skills/composability/SKILL.md +197 -0
- package/skills/debug-manifest/SKILL.md +112 -0
- package/skills/document-cache/SKILL.md +106 -53
- package/skills/fonts/SKILL.md +167 -0
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +621 -67
- package/skills/host-router/SKILL.md +243 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +265 -202
- package/skills/layout/SKILL.md +261 -146
- package/skills/links/SKILL.md +471 -0
- package/skills/loader/SKILL.md +701 -250
- package/skills/middleware/SKILL.md +254 -320
- package/skills/migrate-nextjs/SKILL.md +562 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +155 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +399 -158
- package/skills/prerender/SKILL.md +666 -0
- package/skills/rango/SKILL.md +338 -0
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +468 -0
- package/skills/route/SKILL.md +417 -89
- package/skills/router-setup/SKILL.md +389 -268
- package/skills/server-actions/SKILL.md +751 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/testing/SKILL.md +549 -0
- package/skills/theme/SKILL.md +36 -11
- package/skills/typesafety/SKILL.md +747 -174
- package/skills/use-cache/SKILL.md +353 -0
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +117 -0
- package/src/__internal.ts +273 -0
- package/src/bin/rango.ts +321 -0
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +172 -128
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +390 -557
- package/src/browser/navigation-client.ts +228 -70
- package/src/browser/navigation-store.ts +104 -63
- package/src/browser/navigation-transaction.ts +279 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +397 -303
- package/src/browser/prefetch/cache.ts +314 -0
- package/src/browser/prefetch/fetch.ts +282 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +191 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +152 -0
- package/src/browser/react/Link.tsx +258 -74
- package/src/browser/react/NavigationProvider.tsx +237 -49
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +55 -0
- package/src/browser/react/index.ts +15 -12
- package/src/browser/react/location-state-shared.ts +269 -56
- package/src/browser/react/location-state.ts +90 -19
- package/src/browser/react/mount-context.ts +37 -0
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +41 -98
- package/src/browser/react/use-href.tsx +20 -188
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-mount.ts +31 -0
- package/src/browser/react/use-navigation.ts +49 -80
- package/src/browser/react/use-params.ts +77 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +96 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +85 -99
- package/src/browser/response-adapter.ts +98 -0
- package/src/browser/rsc-router.tsx +273 -78
- package/src/browser/scroll-restoration.ts +132 -49
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +83 -0
- package/src/browser/server-action-bridge.ts +504 -589
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +184 -58
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +463 -0
- package/src/build/generate-route-types.ts +41 -0
- package/src/build/index.ts +37 -0
- package/src/build/route-trie.ts +292 -0
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +418 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +131 -0
- package/src/build/route-types/router-processing.ts +659 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +220 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +342 -0
- package/src/cache/cache-scope.ts +150 -306
- package/src/cache/cf/cf-cache-store.ts +619 -24
- package/src/cache/cf/index.ts +13 -3
- package/src/cache/document-cache.ts +116 -77
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +1 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +76 -121
- package/src/client.rsc.tsx +15 -15
- package/src/client.tsx +145 -309
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +6 -2
- package/src/context-var.ts +156 -0
- package/src/debug.ts +243 -0
- package/src/decode-loader-results.ts +36 -0
- package/src/errors.ts +138 -3
- package/src/handle.ts +90 -22
- package/src/handles/MetaTags.tsx +76 -23
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +32 -15
- package/src/host/cookie-handler.ts +165 -0
- package/src/host/errors.ts +97 -0
- package/src/host/index.ts +53 -0
- package/src/host/pattern-matcher.ts +214 -0
- package/src/host/router.ts +424 -0
- package/src/host/testing.ts +79 -0
- package/src/host/types.ts +175 -0
- package/src/host/utils.ts +25 -0
- package/src/href-client.ts +263 -49
- package/src/index.rsc.ts +190 -29
- package/src/index.ts +278 -38
- package/src/internal-debug.ts +11 -0
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +24 -142
- package/src/loader.ts +21 -11
- package/src/missing-id-error.ts +68 -0
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +37 -0
- package/src/prerender/store.ts +186 -0
- package/src/prerender.ts +524 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +380 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +15 -39
- package/src/route-definition/dsl-helpers.ts +1109 -0
- package/src/route-definition/helper-factories.ts +90 -0
- package/src/route-definition/helpers-types.ts +506 -0
- package/src/route-definition/index.ts +55 -0
- package/src/route-definition/redirect.ts +101 -0
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-definition.ts +1 -1371
- package/src/route-map-builder.ts +247 -112
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +99 -42
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +228 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +10 -10
- package/src/router/find-match.ts +160 -0
- package/src/router/handler-context.ts +420 -88
- package/src/router/intercept-resolution.ts +388 -0
- package/src/router/lazy-includes.ts +237 -0
- package/src/router/loader-resolution.ts +374 -128
- package/src/router/logging.ts +251 -0
- package/src/router/manifest.ts +187 -43
- package/src/router/match-api.ts +556 -0
- package/src/router/match-context.ts +6 -4
- package/src/router/match-handlers.ts +483 -0
- package/src/router/match-middleware/background-revalidation.ts +108 -93
- package/src/router/match-middleware/cache-lookup.ts +413 -10
- package/src/router/match-middleware/cache-store.ts +99 -26
- package/src/router/match-middleware/intercept-resolution.ts +57 -17
- package/src/router/match-middleware/segment-resolution.ts +80 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +156 -36
- package/src/router/metrics.ts +241 -16
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +209 -0
- package/src/router/middleware.ts +359 -346
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +416 -41
- package/src/router/prerender-match.ts +502 -0
- package/src/router/preview-match.ts +100 -0
- package/src/router/request-classification.ts +286 -0
- package/src/router/revalidation.ts +195 -40
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +45 -23
- package/src/router/router-interfaces.ts +501 -0
- package/src/router/router-options.ts +657 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +769 -0
- package/src/router/segment-resolution/helpers.ts +268 -0
- package/src/router/segment-resolution/loader-cache.ts +199 -0
- package/src/router/segment-resolution/revalidation.ts +1420 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +21 -0
- package/src/router/segment-wrappers.ts +291 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +299 -0
- package/src/router/telemetry.ts +399 -0
- package/src/router/timeout.ts +148 -0
- package/src/router/trie-matching.ts +244 -0
- package/src/router/types.ts +87 -4
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +768 -3574
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +894 -806
- package/src/rsc/helpers.ts +201 -19
- package/src/rsc/index.ts +5 -25
- package/src/rsc/loader-fetch.ts +229 -0
- package/src/rsc/manifest-init.ts +90 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +159 -0
- package/src/rsc/progressive-enhancement.ts +395 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +340 -0
- package/src/rsc/rsc-rendering.ts +230 -0
- package/src/rsc/runtime-warnings.ts +41 -0
- package/src/rsc/server-action.ts +336 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/types.ts +54 -14
- package/src/search-params.ts +230 -0
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +265 -115
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +480 -90
- package/src/server/cookie-store.ts +214 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +117 -20
- package/src/server/loader-registry.ts +24 -64
- package/src/server/request-context.ts +613 -109
- package/src/server.ts +36 -131
- package/src/ssr/index.tsx +164 -25
- package/src/static-handler.ts +126 -0
- package/src/testing/cache-status.ts +166 -0
- package/src/testing/collect-handle.ts +63 -0
- package/src/testing/dispatch.ts +440 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +154 -0
- package/src/testing/e2e/index.ts +149 -0
- package/src/testing/e2e/matchers.ts +51 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +306 -0
- package/src/testing/e2e/server.ts +183 -0
- package/src/testing/flight-matchers.ts +104 -0
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/flight.entry.ts +22 -0
- package/src/testing/flight.ts +182 -0
- package/src/testing/generated-routes.ts +223 -0
- package/src/testing/index.ts +98 -0
- package/src/testing/internal/context.ts +151 -0
- package/src/testing/render-route.tsx +536 -0
- package/src/testing/run-loader.ts +296 -0
- package/src/testing/run-middleware.ts +170 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +112 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +11 -4
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +5 -31
- package/src/theme/theme-script.ts +21 -18
- package/src/theme/types.ts +1 -1
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +809 -0
- package/src/types/index.ts +89 -0
- package/src/types/loader-types.ts +209 -0
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +120 -0
- package/src/types/segments.ts +184 -0
- package/src/types.ts +1 -1561
- package/src/urls/include-helper.ts +164 -0
- package/src/urls/index.ts +50 -0
- package/src/urls/path-helper-types.ts +380 -0
- package/src/urls/path-helper.ts +329 -0
- package/src/urls/pattern-types.ts +124 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +282 -0
- package/src/urls/urls-function.ts +94 -0
- package/src/urls.ts +1 -726
- package/src/use-loader.tsx +559 -108
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +181 -0
- package/src/vite/discovery/discover-routers.ts +398 -0
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +480 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +150 -0
- package/src/vite/discovery/virtual-module-codegen.ts +193 -0
- package/src/vite/index.ts +20 -785
- package/src/vite/plugin-types.ts +170 -0
- package/src/vite/plugins/cjs-to-esm.ts +94 -0
- package/src/vite/plugins/client-ref-dedup.ts +131 -0
- package/src/vite/plugins/client-ref-hashing.ts +128 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +109 -66
- package/src/vite/plugins/expose-id-utils.ts +303 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +376 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +156 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +72 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +127 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +796 -0
- package/src/vite/plugins/performance-tracks.ts +92 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +338 -0
- package/src/vite/plugins/version-injector.ts +99 -0
- package/src/vite/plugins/version-plugin.ts +323 -0
- package/src/vite/plugins/virtual-entries.ts +123 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +549 -0
- package/src/vite/router-discovery.ts +1568 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +139 -0
- package/src/vite/utils/client-chunks.ts +190 -0
- package/src/vite/utils/forward-user-plugins.ts +193 -0
- package/src/vite/utils/manifest-utils.ts +86 -0
- package/src/vite/utils/package-resolution.ts +161 -0
- package/src/vite/utils/prerender-utils.ts +222 -0
- package/src/vite/utils/shared-utils.ts +251 -0
- package/CLAUDE.md +0 -7
- package/src/__tests__/component-utils.test.ts +0 -76
- package/src/__tests__/route-definition.test.ts +0 -63
- package/src/__tests__/urls.test.tsx +0 -436
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/__tests__/document-cache.test.ts +0 -522
- package/src/cache/__tests__/memory-segment-store.test.ts +0 -487
- package/src/cache/__tests__/memory-store.test.ts +0 -484
- package/src/cache/cf/__tests__/cf-cache-store.test.ts +0 -428
- package/src/cache/memory-store.ts +0 -253
- package/src/href.ts +0 -177
- package/src/route-utils.ts +0 -89
- package/src/router/__tests__/match-context.test.ts +0 -104
- package/src/router/__tests__/match-pipelines.test.ts +0 -537
- package/src/router/__tests__/match-result.test.ts +0 -566
- package/src/router/__tests__/on-error.test.ts +0 -935
- package/src/router/__tests__/pattern-matching.test.ts +0 -577
- package/src/router/middleware.test.ts +0 -1355
- package/src/rsc/__tests__/helpers.test.ts +0 -175
- package/src/server/__tests__/request-context.test.ts +0 -171
- package/src/ssr/__tests__/ssr-handler.test.tsx +0 -188
- package/src/theme/__tests__/theme.test.ts +0 -120
- package/src/vite/__tests__/expose-loader-id.test.ts +0 -117
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -357
- package/src/vite/expose-location-state-id.ts +0 -177
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,1109 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type {
|
|
3
|
+
PartialCacheOptions,
|
|
4
|
+
Handler,
|
|
5
|
+
LoaderDefinition,
|
|
6
|
+
MiddlewareFn,
|
|
7
|
+
ShouldRevalidateFn,
|
|
8
|
+
TransitionConfig,
|
|
9
|
+
} from "../types.js";
|
|
10
|
+
import {
|
|
11
|
+
getContext,
|
|
12
|
+
getNamePrefix,
|
|
13
|
+
getUrlPrefix,
|
|
14
|
+
requireDslContext,
|
|
15
|
+
type EntryData,
|
|
16
|
+
type EntryPropDatas,
|
|
17
|
+
type EntryPropSegments,
|
|
18
|
+
type HelperContext,
|
|
19
|
+
type InterceptEntry,
|
|
20
|
+
} from "../server/context";
|
|
21
|
+
import { invariant } from "../errors";
|
|
22
|
+
import { isCachedFunction } from "../cache/taint.js";
|
|
23
|
+
import { RangoContext } from "../server/context";
|
|
24
|
+
import { isStaticHandler } from "../static-handler.js";
|
|
25
|
+
import RootLayout from "../server/root-layout";
|
|
26
|
+
import type {
|
|
27
|
+
AllUseItems,
|
|
28
|
+
RouteItem,
|
|
29
|
+
ParallelItem,
|
|
30
|
+
InterceptItem,
|
|
31
|
+
MiddlewareItem,
|
|
32
|
+
RevalidateItem,
|
|
33
|
+
LoaderItem,
|
|
34
|
+
LoadingItem,
|
|
35
|
+
ErrorBoundaryItem,
|
|
36
|
+
NotFoundBoundaryItem,
|
|
37
|
+
LayoutItem,
|
|
38
|
+
WhenItem,
|
|
39
|
+
CacheItem,
|
|
40
|
+
TransitionItem,
|
|
41
|
+
UseItems,
|
|
42
|
+
} from "../route-types.js";
|
|
43
|
+
import type { RouteHelpers } from "./helpers-types.js";
|
|
44
|
+
import { resolveHandlerUse, mergeHandlerUse } from "./resolve-handler-use.js";
|
|
45
|
+
import { ALL_USE_ITEM_TYPES } from "./use-item-types.js";
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Check if an item contains routes (directly or inside nested structures like cache).
|
|
49
|
+
* Used to determine if a layout or cache should be treated as an orphan.
|
|
50
|
+
*/
|
|
51
|
+
const hasRoutesInItem = (item: AllUseItems): boolean => {
|
|
52
|
+
if (item.type === "route") return true;
|
|
53
|
+
// Lazy includes contain deferred routes — treat them as having routes
|
|
54
|
+
// to prevent the parent layout from being misclassified as orphan,
|
|
55
|
+
// which would clear its parent pointer and break the middleware chain.
|
|
56
|
+
if (item.type === "include") return true;
|
|
57
|
+
if (item.type === "cache" && item.uses) {
|
|
58
|
+
return item.uses.some((child) => hasRoutesInItem(child));
|
|
59
|
+
}
|
|
60
|
+
if (item.type === "layout" && item.uses) {
|
|
61
|
+
return item.uses.some((child) => hasRoutesInItem(child));
|
|
62
|
+
}
|
|
63
|
+
if (item.type === "middleware" && item.uses) {
|
|
64
|
+
return item.uses.some((child) => hasRoutesInItem(child));
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Fresh empty collections shared by every from-scratch segment entry. Returns
|
|
71
|
+
* new arrays/objects per call so no two entries share mutable references.
|
|
72
|
+
* mountPath is intentionally NOT included here — each call site adds it from
|
|
73
|
+
* getUrlPrefix() where applicable: the route() and transition() helpers add
|
|
74
|
+
* none, while path() (which also builds a `type: "route"` entry) and the
|
|
75
|
+
* structural helpers (layout/cache/middleware/parallel) do.
|
|
76
|
+
*/
|
|
77
|
+
const emptySegmentBase = (): EntryPropDatas &
|
|
78
|
+
EntryPropSegments & { loading: undefined } => ({
|
|
79
|
+
loading: undefined,
|
|
80
|
+
middleware: [],
|
|
81
|
+
revalidate: [],
|
|
82
|
+
errorBoundary: [],
|
|
83
|
+
notFoundBoundary: [],
|
|
84
|
+
layout: [],
|
|
85
|
+
parallel: {},
|
|
86
|
+
intercept: [],
|
|
87
|
+
loader: [],
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Run a children/use callback as a nested scope, flatten the result, and assert
|
|
92
|
+
* every item is a valid use item. `kind` preserves the existing error wording
|
|
93
|
+
* ("use()" vs "children" callback).
|
|
94
|
+
*/
|
|
95
|
+
function runAndValidateUseItems(
|
|
96
|
+
store: ReturnType<typeof getContext>,
|
|
97
|
+
namespace: string,
|
|
98
|
+
entry: EntryData,
|
|
99
|
+
cb: () => any,
|
|
100
|
+
label: string,
|
|
101
|
+
kind: "use" | "children",
|
|
102
|
+
): AllUseItems[] {
|
|
103
|
+
const result = store.run(namespace, entry, cb)?.flat(3);
|
|
104
|
+
return validateUseItems(result, namespace, label, kind);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Assert an already-invoked, flattened callback result is a use-item array. */
|
|
108
|
+
function validateUseItems(
|
|
109
|
+
result: any,
|
|
110
|
+
namespace: string,
|
|
111
|
+
label: string,
|
|
112
|
+
kind: "use" | "children",
|
|
113
|
+
): AllUseItems[] {
|
|
114
|
+
invariant(
|
|
115
|
+
Array.isArray(result) && result.every((item) => isValidUseItem(item)),
|
|
116
|
+
`${label}() ${kind === "use" ? "use()" : "children"} callback must return an array of use items [${namespace}]`,
|
|
117
|
+
);
|
|
118
|
+
return result as AllUseItems[];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** True when a children/use result contains no routes (directly or nested). */
|
|
122
|
+
const isOrphan = (result: AllUseItems[]): boolean =>
|
|
123
|
+
!result.some((item) => item != null && hasRoutesInItem(item));
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Register a routeless structural entry as an orphan sibling: clear its parent
|
|
127
|
+
* pointer so it leaves the middleware/parent-pointer chain (LOAD-BEARING — see
|
|
128
|
+
* docs/tree-structure.md) and push it onto the parent's layout[] so it renders
|
|
129
|
+
* as a wrapper. Used by cache()/middleware()/transition(); layout() runs extra
|
|
130
|
+
* validation and registers inline.
|
|
131
|
+
*/
|
|
132
|
+
const attachOrphanSibling = (
|
|
133
|
+
parent: EntryData | null,
|
|
134
|
+
entry: EntryData,
|
|
135
|
+
): void => {
|
|
136
|
+
entry.parent = null;
|
|
137
|
+
if (parent && "layout" in parent) parent.layout.push(entry);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Run `fn` with `ctx.parent` temporarily redirected to `temp` — a satellite
|
|
142
|
+
* entry that captures the attachments declared by a use() callback — restoring
|
|
143
|
+
* the original parent afterward, including on throw. loader()/intercept() each
|
|
144
|
+
* build their own tempParent shape (intercept keeps a loading get/set accessor
|
|
145
|
+
* and a captured-layouts array); this only centralizes the save/restore.
|
|
146
|
+
*/
|
|
147
|
+
function withParent<T>(ctx: HelperContext, temp: EntryData, fn: () => T): T {
|
|
148
|
+
const original = ctx.parent;
|
|
149
|
+
ctx.parent = temp;
|
|
150
|
+
try {
|
|
151
|
+
return fn();
|
|
152
|
+
} finally {
|
|
153
|
+
ctx.parent = original;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const revalidate: RouteHelpers<any, any>["revalidate"] = (fn) => {
|
|
158
|
+
const { store, ctx } = requireDslContext(
|
|
159
|
+
"revalidate() must be called inside urls()",
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
// Attach to last entry in stack
|
|
163
|
+
const parent = ctx.parent;
|
|
164
|
+
if (!parent || !("revalidate" in parent)) {
|
|
165
|
+
invariant(false, "No parent entry available for revalidate()");
|
|
166
|
+
}
|
|
167
|
+
const name = `$${store.getNextIndex("revalidate")}`;
|
|
168
|
+
parent.revalidate.push(fn);
|
|
169
|
+
return { name, type: "revalidate" } as RevalidateItem;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Error boundary helper - attaches an error fallback to the current entry
|
|
174
|
+
*
|
|
175
|
+
* When an error occurs during rendering of this segment or its children,
|
|
176
|
+
* the fallback will be rendered instead. The fallback can be:
|
|
177
|
+
* - A static ReactNode (e.g., <ErrorPage />)
|
|
178
|
+
* - A handler function that receives error info and reset function
|
|
179
|
+
*
|
|
180
|
+
* Error boundaries catch errors from:
|
|
181
|
+
* - Middleware execution
|
|
182
|
+
* - Loader execution
|
|
183
|
+
* - Handler/component rendering
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* layout(<ShopLayout />, () => [
|
|
188
|
+
* errorBoundary(<ShopErrorFallback />),
|
|
189
|
+
* route("products.detail", ProductDetail),
|
|
190
|
+
* ])
|
|
191
|
+
*
|
|
192
|
+
* // Or with handler for dynamic error UI:
|
|
193
|
+
* route("products.detail", ProductDetail, () => [
|
|
194
|
+
* errorBoundary(({ error, reset }) => (
|
|
195
|
+
* <div>
|
|
196
|
+
* <h2>Product failed to load</h2>
|
|
197
|
+
* <p>{error.message}</p>
|
|
198
|
+
* <button onClick={reset}>Retry</button>
|
|
199
|
+
* </div>
|
|
200
|
+
* )),
|
|
201
|
+
* ])
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
const errorBoundary: RouteHelpers<any, any>["errorBoundary"] = (fallback) => {
|
|
205
|
+
const { store, ctx } = requireDslContext(
|
|
206
|
+
"errorBoundary() must be called inside urls()",
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
// Attach to parent entry in stack
|
|
210
|
+
const parent = ctx.parent;
|
|
211
|
+
if (!parent || !("errorBoundary" in parent)) {
|
|
212
|
+
invariant(false, "No parent entry available for errorBoundary()");
|
|
213
|
+
}
|
|
214
|
+
const name = `$${store.getNextIndex("errorBoundary")}`;
|
|
215
|
+
parent.errorBoundary.push(fallback);
|
|
216
|
+
return { name, type: "errorBoundary" } as ErrorBoundaryItem;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* NotFound boundary helper - attaches a not-found fallback to the current entry
|
|
221
|
+
*
|
|
222
|
+
* When a DataNotFoundError is thrown (via notFound()) during rendering of this
|
|
223
|
+
* segment or its children, the fallback will be rendered instead. The fallback can be:
|
|
224
|
+
* - A static ReactNode (e.g., <ProductNotFound />)
|
|
225
|
+
* - A handler function that receives not found info
|
|
226
|
+
*
|
|
227
|
+
* NotFound boundaries catch DataNotFoundError from:
|
|
228
|
+
* - Loader execution
|
|
229
|
+
* - Handler/component rendering
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* layout(<ShopLayout />, () => [
|
|
234
|
+
* notFoundBoundary(<ProductNotFound />),
|
|
235
|
+
* route("products.detail", ProductDetail),
|
|
236
|
+
* ])
|
|
237
|
+
*
|
|
238
|
+
* // Or with handler for dynamic not found UI:
|
|
239
|
+
* route("products.detail", ProductDetail, () => [
|
|
240
|
+
* notFoundBoundary(({ notFound }) => (
|
|
241
|
+
* <div>
|
|
242
|
+
* <h2>Product not found</h2>
|
|
243
|
+
* <p>{notFound.message}</p>
|
|
244
|
+
* <a href="/products">Browse all products</a>
|
|
245
|
+
* </div>
|
|
246
|
+
* )),
|
|
247
|
+
* ])
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
const notFoundBoundary: RouteHelpers<any, any>["notFoundBoundary"] = (
|
|
251
|
+
fallback,
|
|
252
|
+
) => {
|
|
253
|
+
const { store, ctx } = requireDslContext(
|
|
254
|
+
"notFoundBoundary() must be called inside urls()",
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
// Attach to parent entry in stack
|
|
258
|
+
const parent = ctx.parent;
|
|
259
|
+
if (!parent || !("notFoundBoundary" in parent)) {
|
|
260
|
+
invariant(false, "No parent entry available for notFoundBoundary()");
|
|
261
|
+
}
|
|
262
|
+
const name = `$${store.getNextIndex("notFoundBoundary")}`;
|
|
263
|
+
parent.notFoundBoundary.push(fallback);
|
|
264
|
+
return { name, type: "notFoundBoundary" } as NotFoundBoundaryItem;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* When helper - defines a condition for intercept activation
|
|
269
|
+
*
|
|
270
|
+
* Only valid inside intercept() use() callback. The when() function
|
|
271
|
+
* is captured by the intercept and stored in its `when` array.
|
|
272
|
+
* During soft navigation, all when() conditions must return true
|
|
273
|
+
* for the intercept to activate.
|
|
274
|
+
*/
|
|
275
|
+
const when: RouteHelpers<any, any>["when"] = (fn) => {
|
|
276
|
+
const { store, ctx } = requireDslContext(
|
|
277
|
+
"when() must be called inside intercept()",
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// The when() function needs to be captured by the intercept's tempParent
|
|
281
|
+
// which should have a `when` array. If not present, we're not inside intercept()
|
|
282
|
+
const parent = ctx.parent as any;
|
|
283
|
+
if (!parent || !("when" in parent)) {
|
|
284
|
+
invariant(
|
|
285
|
+
false,
|
|
286
|
+
"when() can only be used inside intercept() use() callback",
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const name = `$${store.getNextIndex("when")}`;
|
|
291
|
+
parent.when.push(fn);
|
|
292
|
+
return { name, type: "when" } as WhenItem;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Cache helper - defines caching configuration for segments
|
|
297
|
+
*
|
|
298
|
+
* Creates a cache boundary that applies to all children unless overridden.
|
|
299
|
+
* When used without children, attaches cache config to the parent entry
|
|
300
|
+
* (e.g., for loader-specific caching).
|
|
301
|
+
*
|
|
302
|
+
* Supports these call signatures:
|
|
303
|
+
* - cache() - no args, uses app-level defaults (for loader caching)
|
|
304
|
+
* - cache(() => [...]) - wraps children with app-level defaults
|
|
305
|
+
* - cache('profileName') - uses a named cache profile
|
|
306
|
+
* - cache('profileName', () => [...]) - named profile with children
|
|
307
|
+
* - cache({ ttl: 60 }, () => [...]) - with explicit options
|
|
308
|
+
*/
|
|
309
|
+
const cache: RouteHelpers<any, any>["cache"] = (
|
|
310
|
+
optionsOrChildren?:
|
|
311
|
+
| PartialCacheOptions
|
|
312
|
+
| false
|
|
313
|
+
| string
|
|
314
|
+
| (() => UseItems<AllUseItems>),
|
|
315
|
+
maybeChildren?: () => UseItems<AllUseItems>,
|
|
316
|
+
) => {
|
|
317
|
+
const { store, ctx } = requireDslContext(
|
|
318
|
+
"cache() must be called inside urls()",
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
// Handle overloaded signature
|
|
322
|
+
let options: PartialCacheOptions | false;
|
|
323
|
+
let children: (() => UseItems<AllUseItems>) | undefined;
|
|
324
|
+
|
|
325
|
+
if (optionsOrChildren === undefined) {
|
|
326
|
+
// cache() - no args, use defaults
|
|
327
|
+
options = {};
|
|
328
|
+
children = undefined;
|
|
329
|
+
} else if (typeof optionsOrChildren === "string") {
|
|
330
|
+
// cache('profileName') or cache('profileName', () => [...])
|
|
331
|
+
// Resolve from context-scoped profiles (set per-router via HelperContext).
|
|
332
|
+
const ctxStore = RangoContext.getStore();
|
|
333
|
+
const profile = ctxStore?.cacheProfiles?.[optionsOrChildren];
|
|
334
|
+
invariant(
|
|
335
|
+
profile,
|
|
336
|
+
`cache("${optionsOrChildren}"): unknown cache profile. ` +
|
|
337
|
+
`Define it in createRouter({ cacheProfiles: { "${optionsOrChildren}": { ttl: ... } } }).`,
|
|
338
|
+
);
|
|
339
|
+
options = { ttl: profile.ttl, swr: profile.swr, tags: profile.tags };
|
|
340
|
+
children = maybeChildren;
|
|
341
|
+
} else if (typeof optionsOrChildren === "function") {
|
|
342
|
+
// cache(() => [...]) - use empty options (will use defaults)
|
|
343
|
+
options = {};
|
|
344
|
+
children = optionsOrChildren;
|
|
345
|
+
} else {
|
|
346
|
+
// cache(options, children) - explicit options
|
|
347
|
+
options = optionsOrChildren;
|
|
348
|
+
children = maybeChildren;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Allocate a single index for this cache() call (used in all paths)
|
|
352
|
+
const cacheIndex = store.getNextIndex("cache");
|
|
353
|
+
const name = `$${cacheIndex}`;
|
|
354
|
+
const cacheConfig = { options };
|
|
355
|
+
|
|
356
|
+
// If no children, create an orphan cache entry (like orphan layouts)
|
|
357
|
+
// This allows cache() to wrap subsequent siblings
|
|
358
|
+
if (!children) {
|
|
359
|
+
const parent = ctx.parent as any;
|
|
360
|
+
|
|
361
|
+
// Check if we're inside a loader() use() callback - special case for loader caching
|
|
362
|
+
if (parent && parent.type === "loader") {
|
|
363
|
+
// Direct assignment to loader entry's cache field
|
|
364
|
+
parent.cache = cacheConfig;
|
|
365
|
+
return { name, type: "cache" } as CacheItem;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Create orphan cache entry (like orphan layout)
|
|
369
|
+
// Subsequent siblings in the same array will attach to this entry
|
|
370
|
+
const namespace = `${ctx.namespace}.${cacheIndex}`;
|
|
371
|
+
const urlPrefix = getUrlPrefix();
|
|
372
|
+
|
|
373
|
+
const entry = {
|
|
374
|
+
...emptySegmentBase(),
|
|
375
|
+
id: namespace,
|
|
376
|
+
shortCode: store.getShortCode("cache"),
|
|
377
|
+
type: "cache",
|
|
378
|
+
parent: parent, // link to current parent for hierarchy
|
|
379
|
+
cache: cacheConfig,
|
|
380
|
+
handler: RootLayout,
|
|
381
|
+
...(urlPrefix ? { mountPath: urlPrefix } : {}),
|
|
382
|
+
} satisfies EntryData;
|
|
383
|
+
|
|
384
|
+
// Attach to parent's layout array (cache entries are structural like layouts)
|
|
385
|
+
if (parent && "layout" in parent) {
|
|
386
|
+
parent.layout.push(entry);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Update context parent so subsequent siblings attach to this cache entry
|
|
390
|
+
// This makes cache() act as sugar for cache(() => [...])
|
|
391
|
+
ctx.parent = entry;
|
|
392
|
+
|
|
393
|
+
return { name: namespace, type: "cache" } as CacheItem;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Inside a loader() use() callback, only the direct form — cache()/cache(opts)/
|
|
397
|
+
// cache("profile") — writes cache config to the loader entry. The wrapper
|
|
398
|
+
// form creates a structural cache boundary with its own children scope, which
|
|
399
|
+
// has no effect on the loader and would silently no-op.
|
|
400
|
+
invariant(
|
|
401
|
+
!(ctx.parent && (ctx.parent as any).type === "loader"),
|
|
402
|
+
"cache() wrapper form is not valid inside loader() use(). Use cache({...}) without children to configure the loader's cache.",
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
// With children: create a cache entry (like layout with caching semantics)
|
|
406
|
+
const namespace = `${ctx.namespace}.${cacheIndex}`;
|
|
407
|
+
const cacheShortCode = store.getShortCode("cache");
|
|
408
|
+
|
|
409
|
+
const urlPrefix = getUrlPrefix();
|
|
410
|
+
|
|
411
|
+
const entry = {
|
|
412
|
+
...emptySegmentBase(),
|
|
413
|
+
id: namespace,
|
|
414
|
+
shortCode: cacheShortCode,
|
|
415
|
+
type: "cache",
|
|
416
|
+
parent: ctx.parent,
|
|
417
|
+
cache: cacheConfig,
|
|
418
|
+
// Cache entries render like layouts (with Outlet as default handler)
|
|
419
|
+
handler: RootLayout, // RootLayout just renders <Outlet />
|
|
420
|
+
...(urlPrefix ? { mountPath: urlPrefix } : {}),
|
|
421
|
+
} satisfies EntryData;
|
|
422
|
+
|
|
423
|
+
// Run children with cache entry as parent
|
|
424
|
+
const result = runAndValidateUseItems(
|
|
425
|
+
store,
|
|
426
|
+
namespace,
|
|
427
|
+
entry,
|
|
428
|
+
children,
|
|
429
|
+
"cache",
|
|
430
|
+
"children",
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
// Cache entries are structural like layouts: with no routes inside, register
|
|
434
|
+
// as an orphan sibling.
|
|
435
|
+
if (isOrphan(result)) attachOrphanSibling(ctx.parent, entry);
|
|
436
|
+
|
|
437
|
+
return { name: namespace, type: "cache", uses: result } as CacheItem;
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
const middleware: RouteHelpers<any, any>["middleware"] = (...args: any[]) => {
|
|
441
|
+
// Four call forms:
|
|
442
|
+
// middleware(fn) — single fn, sibling
|
|
443
|
+
// middleware(fn, () => [...]) — single fn, wrapping
|
|
444
|
+
// middleware([fn1, fn2]) — array, sibling
|
|
445
|
+
// middleware([fn1, fn2], () => [...]) — array, wrapping
|
|
446
|
+
const isArray = Array.isArray(args[0]);
|
|
447
|
+
|
|
448
|
+
// Reject the removed variadic form before executing anything.
|
|
449
|
+
// middleware(fn1, fn2, fn3) — 3+ args, always wrong.
|
|
450
|
+
// middleware(fn1, fn2) where fn2 is a middleware fn (length >= 1), not a
|
|
451
|
+
// children callback (length === 0) — legacy two-fn form, reject early.
|
|
452
|
+
if (
|
|
453
|
+
args.length > 2 ||
|
|
454
|
+
(!isArray &&
|
|
455
|
+
args.length === 2 &&
|
|
456
|
+
typeof args[1] === "function" &&
|
|
457
|
+
args[1].length > 0)
|
|
458
|
+
) {
|
|
459
|
+
throw new Error(
|
|
460
|
+
"middleware() no longer accepts variadic arguments. " +
|
|
461
|
+
"Use middleware([fn1, fn2, ...]) instead of middleware(fn1, fn2, ...).",
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const fns: MiddlewareFn<any>[] = isArray ? args[0] : [args[0]];
|
|
466
|
+
const children: (() => any[]) | undefined =
|
|
467
|
+
typeof args[1] === "function" ? args[1] : undefined;
|
|
468
|
+
|
|
469
|
+
// Prevent "use cache" functions from being used as middleware.
|
|
470
|
+
for (const f of fns) {
|
|
471
|
+
if (isCachedFunction(f)) {
|
|
472
|
+
throw new Error(
|
|
473
|
+
`A "use cache" function cannot be used as middleware. ` +
|
|
474
|
+
`Cached functions return data and do not participate in the ` +
|
|
475
|
+
`middleware chain. Remove the "use cache" directive or use a ` +
|
|
476
|
+
`regular middleware function instead.`,
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const { store, ctx } = requireDslContext(
|
|
482
|
+
"middleware() must be called inside urls()",
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
if (!children) {
|
|
486
|
+
// Sibling mode: attach to parent entry
|
|
487
|
+
const parent = ctx.parent;
|
|
488
|
+
if (!parent || !("middleware" in parent)) {
|
|
489
|
+
invariant(false, "No parent entry available for middleware()");
|
|
490
|
+
}
|
|
491
|
+
const name = `$${store.getNextIndex("middleware")}`;
|
|
492
|
+
parent.middleware.push(...fns);
|
|
493
|
+
return { name, type: "middleware" } as MiddlewareItem;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Wrapping mode: create a transparent layout that carries the middleware
|
|
497
|
+
const mwIndex = store.getNextIndex("middleware");
|
|
498
|
+
const namespace = `${ctx.namespace}.${mwIndex}`;
|
|
499
|
+
|
|
500
|
+
const urlPrefix = getUrlPrefix();
|
|
501
|
+
const entry = {
|
|
502
|
+
...emptySegmentBase(),
|
|
503
|
+
id: namespace,
|
|
504
|
+
shortCode: store.getShortCode("layout"),
|
|
505
|
+
type: "layout",
|
|
506
|
+
parent: ctx.parent,
|
|
507
|
+
handler: RootLayout,
|
|
508
|
+
middleware: [...fns],
|
|
509
|
+
...(urlPrefix ? { mountPath: urlPrefix } : {}),
|
|
510
|
+
} satisfies EntryData;
|
|
511
|
+
|
|
512
|
+
// Run children callback. If the second arg was actually a middleware fn
|
|
513
|
+
// (old variadic form: middleware(mw1, mw2)), this will return a non-array
|
|
514
|
+
// and the invariant below gives a clear migration error.
|
|
515
|
+
const rawResult = store.run(namespace, entry, children);
|
|
516
|
+
|
|
517
|
+
invariant(
|
|
518
|
+
Array.isArray(rawResult),
|
|
519
|
+
"middleware(fn, children) expects the second argument to return an array of use items. " +
|
|
520
|
+
"To pass multiple middleware, use middleware([fn1, fn2]).",
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
const result = validateUseItems(
|
|
524
|
+
rawResult.flat(3),
|
|
525
|
+
namespace,
|
|
526
|
+
"middleware",
|
|
527
|
+
"children",
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
if (isOrphan(result)) attachOrphanSibling(ctx.parent, entry);
|
|
531
|
+
|
|
532
|
+
return {
|
|
533
|
+
name: namespace,
|
|
534
|
+
type: "middleware",
|
|
535
|
+
uses: result,
|
|
536
|
+
} as MiddlewareItem;
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
const parallel: RouteHelpers<any, any>["parallel"] = (slots, use) => {
|
|
540
|
+
const { store, ctx } = requireDslContext(
|
|
541
|
+
"parallel() must be called inside urls()",
|
|
542
|
+
);
|
|
543
|
+
|
|
544
|
+
if (!ctx.parent || !ctx.parent?.parallel) {
|
|
545
|
+
invariant(false, "No parent entry available for parallel()");
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
invariant(
|
|
549
|
+
ctx.parent.type !== "parallel",
|
|
550
|
+
"parallel() cannot be nested inside another parallel()",
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
const slotNames = Object.keys(slots as Record<string, any>) as `@${string}`[];
|
|
554
|
+
|
|
555
|
+
const namespace = `${ctx.namespace}.$${store.getNextIndex("parallel")}`;
|
|
556
|
+
|
|
557
|
+
// Unwrap slot values. A slot value can be:
|
|
558
|
+
// - a Handler / ReactNode (legacy form)
|
|
559
|
+
// - a Static() definition (build-time only)
|
|
560
|
+
// - a slot descriptor `{ handler, use? }` for slot-local overrides
|
|
561
|
+
// The descriptor's `use` runs after the broadcast `use` for that slot,
|
|
562
|
+
// so single-assignment items like `loading()` placed there win without
|
|
563
|
+
// affecting siblings.
|
|
564
|
+
const unwrappedSlots: Record<string, any> = {};
|
|
565
|
+
const slotLocalUses: Record<string, (() => any[]) | undefined> = {};
|
|
566
|
+
let hasStaticSlot = false;
|
|
567
|
+
const staticSlotIds: Record<string, string> = {};
|
|
568
|
+
for (const [slotName, rawSlot] of Object.entries(
|
|
569
|
+
slots as Record<string, any>,
|
|
570
|
+
)) {
|
|
571
|
+
let slotHandler: any = rawSlot;
|
|
572
|
+
if (isSlotDescriptor(rawSlot)) {
|
|
573
|
+
slotHandler = rawSlot.handler;
|
|
574
|
+
slotLocalUses[slotName] = rawSlot.use;
|
|
575
|
+
}
|
|
576
|
+
if (isStaticHandler(slotHandler)) {
|
|
577
|
+
hasStaticSlot = true;
|
|
578
|
+
unwrappedSlots[slotName] = slotHandler.handler;
|
|
579
|
+
if (slotHandler.$$id) {
|
|
580
|
+
staticSlotIds[slotName] = slotHandler.$$id;
|
|
581
|
+
// Capture namespace prefix for build-time reverse() resolution
|
|
582
|
+
if (ctx.namePrefix) {
|
|
583
|
+
(slotHandler as any).$$routePrefix = ctx.namePrefix;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
} else {
|
|
587
|
+
unwrappedSlots[slotName] = slotHandler;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Create full EntryData for parallel with its own loaders/revalidate/loading
|
|
592
|
+
const parallelUrlPrefix = getUrlPrefix();
|
|
593
|
+
const entry = {
|
|
594
|
+
...emptySegmentBase(),
|
|
595
|
+
id: namespace,
|
|
596
|
+
shortCode: store.getShortCode("parallel"),
|
|
597
|
+
type: "parallel",
|
|
598
|
+
parent: null, // Parallels don't participate in parent chain traversal
|
|
599
|
+
handler: unwrappedSlots,
|
|
600
|
+
...(parallelUrlPrefix ? { mountPath: parallelUrlPrefix } : {}),
|
|
601
|
+
...(hasStaticSlot
|
|
602
|
+
? {
|
|
603
|
+
isStaticPrerender: true as const,
|
|
604
|
+
...(Object.keys(staticSlotIds).length > 0
|
|
605
|
+
? { staticHandlerIds: staticSlotIds }
|
|
606
|
+
: {}),
|
|
607
|
+
}
|
|
608
|
+
: {}),
|
|
609
|
+
} satisfies EntryData;
|
|
610
|
+
|
|
611
|
+
for (const slotName of slotNames) {
|
|
612
|
+
const slotEntry = {
|
|
613
|
+
...entry,
|
|
614
|
+
handler: { [slotName]: unwrappedSlots[slotName]! },
|
|
615
|
+
middleware: [...entry.middleware],
|
|
616
|
+
revalidate: [...entry.revalidate],
|
|
617
|
+
errorBoundary: [...entry.errorBoundary],
|
|
618
|
+
notFoundBoundary: [...entry.notFoundBoundary],
|
|
619
|
+
layout: [...entry.layout],
|
|
620
|
+
parallel: { ...entry.parallel },
|
|
621
|
+
intercept: [...entry.intercept],
|
|
622
|
+
loader: [...entry.loader],
|
|
623
|
+
...(entry.staticHandlerIds?.[slotName]
|
|
624
|
+
? {
|
|
625
|
+
isStaticPrerender: true as const,
|
|
626
|
+
staticHandlerIds: { [slotName]: entry.staticHandlerIds[slotName]! },
|
|
627
|
+
}
|
|
628
|
+
: {
|
|
629
|
+
isStaticPrerender: undefined,
|
|
630
|
+
staticHandlerIds: undefined,
|
|
631
|
+
}),
|
|
632
|
+
} satisfies EntryData;
|
|
633
|
+
|
|
634
|
+
// Per-slot merge order (narrowest-scope-wins for single-assignment items
|
|
635
|
+
// like loading()):
|
|
636
|
+
// 1. handler.use — defaults baked into the handler
|
|
637
|
+
// 2. shared `use` — broadcast at the parallel() call site
|
|
638
|
+
// 3. slot-local `use` — per-slot override via `{ handler, use }` descriptor
|
|
639
|
+
// Items that accumulate (loader, middleware, revalidate, …) compose
|
|
640
|
+
// across all three layers regardless of order.
|
|
641
|
+
const rawSlot = (slots as Record<string, any>)[slotName];
|
|
642
|
+
const slotHandlerForUse = isSlotDescriptor(rawSlot)
|
|
643
|
+
? rawSlot.handler
|
|
644
|
+
: rawSlot;
|
|
645
|
+
const slotHandlerUse = resolveHandlerUse(slotHandlerForUse);
|
|
646
|
+
const slotLocalUse = slotLocalUses[slotName];
|
|
647
|
+
const explicitUse = combineExplicitUses(use, slotLocalUse);
|
|
648
|
+
const slotMergedUse = mergeHandlerUse(
|
|
649
|
+
slotHandlerUse,
|
|
650
|
+
explicitUse,
|
|
651
|
+
"parallel",
|
|
652
|
+
);
|
|
653
|
+
if (slotMergedUse) {
|
|
654
|
+
runAndValidateUseItems(
|
|
655
|
+
store,
|
|
656
|
+
namespace,
|
|
657
|
+
slotEntry,
|
|
658
|
+
slotMergedUse,
|
|
659
|
+
"parallel",
|
|
660
|
+
"use",
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
ctx.parent.parallel[slotName] = slotEntry;
|
|
665
|
+
}
|
|
666
|
+
return { name: namespace, type: "parallel" } as ParallelItem;
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
function isSlotDescriptor(
|
|
670
|
+
value: unknown,
|
|
671
|
+
): value is { handler: unknown; use?: () => any[] } {
|
|
672
|
+
return (
|
|
673
|
+
typeof value === "object" &&
|
|
674
|
+
value !== null &&
|
|
675
|
+
!("__brand" in value) &&
|
|
676
|
+
"handler" in value &&
|
|
677
|
+
typeof (value as any).handler !== "undefined"
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
function combineExplicitUses(
|
|
682
|
+
sharedUse: (() => any[]) | undefined,
|
|
683
|
+
slotLocalUse: (() => any[]) | undefined,
|
|
684
|
+
): (() => any[]) | undefined {
|
|
685
|
+
if (!sharedUse && !slotLocalUse) return undefined;
|
|
686
|
+
if (!slotLocalUse) return sharedUse;
|
|
687
|
+
if (!sharedUse) return slotLocalUse;
|
|
688
|
+
return () => [...sharedUse(), ...slotLocalUse()];
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Intercept helper - defines an intercepting route for soft navigation
|
|
693
|
+
*/
|
|
694
|
+
const intercept = (
|
|
695
|
+
slotName: `@${string}`,
|
|
696
|
+
routeName: string,
|
|
697
|
+
handler: any,
|
|
698
|
+
use?: () => any[],
|
|
699
|
+
) => {
|
|
700
|
+
const { store, ctx } = requireDslContext(
|
|
701
|
+
"intercept() must be called inside urls()",
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
if (!ctx.parent || !ctx.parent?.intercept) {
|
|
705
|
+
invariant(false, "No parent entry available for intercept()");
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
invariant(
|
|
709
|
+
ctx.parent.type !== "parallel",
|
|
710
|
+
"intercept() cannot be used inside parallel()",
|
|
711
|
+
);
|
|
712
|
+
|
|
713
|
+
const namespace = `${ctx.namespace}.$${store.getNextIndex("intercept")}.${slotName}`;
|
|
714
|
+
|
|
715
|
+
// Dot-prefixed = local (add include prefix), unprefixed = global (use as-is)
|
|
716
|
+
const isLocal = typeof routeName === "string" && routeName.startsWith(".");
|
|
717
|
+
const bareRouteName = isLocal ? routeName.slice(1) : routeName;
|
|
718
|
+
const namePrefix = getNamePrefix();
|
|
719
|
+
const prefixedRouteName =
|
|
720
|
+
isLocal && namePrefix ? `${namePrefix}.${bareRouteName}` : bareRouteName;
|
|
721
|
+
|
|
722
|
+
// Create intercept entry with its own loaders/revalidate/middleware/when
|
|
723
|
+
const entry: InterceptEntry = {
|
|
724
|
+
slotName: slotName as `@${string}`,
|
|
725
|
+
routeName: prefixedRouteName,
|
|
726
|
+
handler,
|
|
727
|
+
middleware: [],
|
|
728
|
+
revalidate: [],
|
|
729
|
+
errorBoundary: [],
|
|
730
|
+
notFoundBoundary: [],
|
|
731
|
+
loader: [],
|
|
732
|
+
when: [], // Selector conditions for conditional interception
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
// Merge handler.use defaults with explicit use
|
|
736
|
+
const handlerUseFn = resolveHandlerUse(handler);
|
|
737
|
+
const mergedUse = mergeHandlerUse(handlerUseFn, use, "intercept");
|
|
738
|
+
|
|
739
|
+
// Run merged use callback to collect loaders, revalidate, middleware, etc.
|
|
740
|
+
if (mergedUse) {
|
|
741
|
+
// Capture layout() calls into a temporary array
|
|
742
|
+
const capturedLayouts: EntryData[] = [];
|
|
743
|
+
|
|
744
|
+
// Temporary parent so middleware/loader/revalidate/when attach to the
|
|
745
|
+
// intercept entry; the loading get/set accessor mirrors writes onto `entry`.
|
|
746
|
+
const tempParent = {
|
|
747
|
+
...ctx.parent,
|
|
748
|
+
middleware: entry.middleware,
|
|
749
|
+
revalidate: entry.revalidate,
|
|
750
|
+
errorBoundary: entry.errorBoundary,
|
|
751
|
+
notFoundBoundary: entry.notFoundBoundary,
|
|
752
|
+
loader: entry.loader,
|
|
753
|
+
layout: capturedLayouts, // Capture layout() calls
|
|
754
|
+
when: entry.when, // Capture when() conditions
|
|
755
|
+
get loading() {
|
|
756
|
+
return entry.loading;
|
|
757
|
+
},
|
|
758
|
+
set loading(value: ReactNode | false | undefined) {
|
|
759
|
+
entry.loading = value;
|
|
760
|
+
},
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
const result = withParent(ctx, tempParent as EntryData, () =>
|
|
764
|
+
mergedUse()?.flat(3),
|
|
765
|
+
);
|
|
766
|
+
|
|
767
|
+
// Extract layout from captured layouts (use first one if multiple)
|
|
768
|
+
// Layout inside intercept should always be ReactNode or Handler, not Record slots
|
|
769
|
+
if (capturedLayouts.length > 0 && capturedLayouts[0].type === "layout") {
|
|
770
|
+
entry.layout = capturedLayouts[0].handler as
|
|
771
|
+
| ReactNode
|
|
772
|
+
| Handler<any, any, any>;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
validateUseItems(result, namespace, "intercept", "use");
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
ctx.parent.intercept.push(entry);
|
|
779
|
+
return { name: namespace, type: "intercept" } as InterceptItem;
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Loader helper - attaches a loader to the current entry
|
|
784
|
+
*/
|
|
785
|
+
const loader: RouteHelpers<any, any>["loader"] = (loaderDef, use) => {
|
|
786
|
+
const { store, ctx } = requireDslContext(
|
|
787
|
+
"loader() must be called inside urls()",
|
|
788
|
+
);
|
|
789
|
+
|
|
790
|
+
// Attach to last entry in stack
|
|
791
|
+
if (!ctx.parent || !ctx.parent?.loader) {
|
|
792
|
+
invariant(false, "No parent entry available for loader()");
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const name = `${ctx.namespace}.$${store.getNextIndex("loader")}`;
|
|
796
|
+
|
|
797
|
+
// Create loader entry with empty revalidate array
|
|
798
|
+
const loaderEntry = {
|
|
799
|
+
loader: loaderDef,
|
|
800
|
+
revalidate: [] as ShouldRevalidateFn<any, any>[],
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
// Merge handler.use defaults (attached to the loader definition) with explicit use
|
|
804
|
+
const handlerUseFn = resolveHandlerUse(loaderDef);
|
|
805
|
+
const mergedUse = mergeHandlerUse(handlerUseFn, use, "loader");
|
|
806
|
+
|
|
807
|
+
// If any use callback is in effect, run it to collect revalidation rules and cache config
|
|
808
|
+
if (mergedUse) {
|
|
809
|
+
// Create a temporary "parent" with type "loader" so cache() can detect it.
|
|
810
|
+
// Save existing .cache to distinguish inherited config from newly set config.
|
|
811
|
+
const parentCache = (ctx.parent as any).cache;
|
|
812
|
+
const tempParent = {
|
|
813
|
+
...ctx.parent,
|
|
814
|
+
type: "loader",
|
|
815
|
+
revalidate: loaderEntry.revalidate,
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
const result = withParent(ctx, tempParent as EntryData, () =>
|
|
819
|
+
mergedUse()?.flat(3),
|
|
820
|
+
);
|
|
821
|
+
|
|
822
|
+
// Copy cache config only if cache() was called during the use() callback.
|
|
823
|
+
// The spread may carry an inherited .cache from a parent cache() boundary —
|
|
824
|
+
// only copy if it was newly set.
|
|
825
|
+
if (
|
|
826
|
+
(tempParent as any).cache &&
|
|
827
|
+
(tempParent as any).cache !== parentCache
|
|
828
|
+
) {
|
|
829
|
+
(loaderEntry as any).cache = (tempParent as any).cache;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
validateUseItems(result, name, "loader", "use");
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
ctx.parent.loader.push(loaderEntry);
|
|
836
|
+
return { name, type: "loader" } as LoaderItem;
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Loading helper - attaches a loading component to the current entry
|
|
841
|
+
* Loading components are static (no context) and shown during navigation
|
|
842
|
+
*/
|
|
843
|
+
const loading: RouteHelpers<any, any>["loading"] = (component, options) => {
|
|
844
|
+
const { store, ctx } = requireDslContext(
|
|
845
|
+
"loading() must be called inside urls()",
|
|
846
|
+
);
|
|
847
|
+
|
|
848
|
+
const parent = ctx.parent;
|
|
849
|
+
if (!parent || !("loading" in parent)) {
|
|
850
|
+
invariant(false, "No parent entry available for loading()");
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// Unwrap function form: loading(() => <Skeleton />) → loading(<Skeleton />)
|
|
854
|
+
const resolved =
|
|
855
|
+
typeof component === "function" ? (component as () => any)() : component;
|
|
856
|
+
|
|
857
|
+
// If ssr: false and we're in SSR, set loading to false
|
|
858
|
+
if (options?.ssr === false && ctx.isSSR) {
|
|
859
|
+
parent.loading = false;
|
|
860
|
+
} else {
|
|
861
|
+
parent.loading = resolved;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
const name = `$${store.getNextIndex("loading")}`;
|
|
865
|
+
return { name, type: "loading" } as LoadingItem;
|
|
866
|
+
};
|
|
867
|
+
|
|
868
|
+
/**
|
|
869
|
+
* Transition helper - opts the entry (or a wrapped group of routes) into
|
|
870
|
+
* transition-driven navigation by attaching a TransitionConfig. This drives the
|
|
871
|
+
* commit through startTransition (content hold on all React versions) and, on
|
|
872
|
+
* experimental React, places a `<ViewTransition>` boundary unless
|
|
873
|
+
* `viewTransition: false`. See skills/view-transitions for the matrix.
|
|
874
|
+
*/
|
|
875
|
+
const transition = (
|
|
876
|
+
configOrChildren?: TransitionConfig | (() => UseItems<AllUseItems>),
|
|
877
|
+
maybeChildren?: () => UseItems<AllUseItems>,
|
|
878
|
+
): TransitionItem => {
|
|
879
|
+
// Resolve overloaded arguments:
|
|
880
|
+
// transition() -> config={}, children=undefined
|
|
881
|
+
// transition(config) -> config=config, children=undefined
|
|
882
|
+
// transition(children) -> config={}, children=children
|
|
883
|
+
// transition(config, children) -> config=config, children=children
|
|
884
|
+
const config: TransitionConfig =
|
|
885
|
+
typeof configOrChildren === "function" ? {} : (configOrChildren ?? {});
|
|
886
|
+
const children: (() => UseItems<AllUseItems>) | undefined =
|
|
887
|
+
typeof configOrChildren === "function" ? configOrChildren : maybeChildren;
|
|
888
|
+
|
|
889
|
+
const { store, ctx } = requireDslContext(
|
|
890
|
+
"transition() must be called inside urls()",
|
|
891
|
+
);
|
|
892
|
+
|
|
893
|
+
const name = `$${store.getNextIndex("transition")}`;
|
|
894
|
+
|
|
895
|
+
if (!children) {
|
|
896
|
+
// Position 1: child of path() — attach to parent entry
|
|
897
|
+
const parent = ctx.parent;
|
|
898
|
+
if (!parent || !("loading" in parent)) {
|
|
899
|
+
invariant(false, "No parent entry available for transition()");
|
|
900
|
+
}
|
|
901
|
+
parent.transition = config;
|
|
902
|
+
return { name, type: "transition" } as TransitionItem;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// Position 2: wrapper — create a transparent layout with transition config
|
|
906
|
+
const namespace = `${ctx.namespace}.${store.getNextIndex("transition")}`;
|
|
907
|
+
const entry = {
|
|
908
|
+
...emptySegmentBase(),
|
|
909
|
+
id: namespace,
|
|
910
|
+
shortCode: store.getShortCode("layout"),
|
|
911
|
+
type: "layout",
|
|
912
|
+
parent: ctx.parent,
|
|
913
|
+
handler: RootLayout,
|
|
914
|
+
transition: config,
|
|
915
|
+
} satisfies EntryData;
|
|
916
|
+
|
|
917
|
+
const result = runAndValidateUseItems(
|
|
918
|
+
store,
|
|
919
|
+
namespace,
|
|
920
|
+
entry,
|
|
921
|
+
children,
|
|
922
|
+
"transition",
|
|
923
|
+
"children",
|
|
924
|
+
);
|
|
925
|
+
|
|
926
|
+
if (isOrphan(result)) attachOrphanSibling(ctx.parent, entry);
|
|
927
|
+
|
|
928
|
+
return { name: namespace, type: "transition" } as TransitionItem;
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
const route: RouteHelpers<any, any>["route"] = (name, handler, use) => {
|
|
932
|
+
const { store, ctx } = requireDslContext(
|
|
933
|
+
"route() must be called inside urls()",
|
|
934
|
+
);
|
|
935
|
+
|
|
936
|
+
const namespace = `${ctx.namespace}.${store.getNextIndex("route")}.${name}`;
|
|
937
|
+
|
|
938
|
+
const entry = {
|
|
939
|
+
...emptySegmentBase(),
|
|
940
|
+
id: namespace,
|
|
941
|
+
shortCode: store.getShortCode("route"),
|
|
942
|
+
type: "route",
|
|
943
|
+
parent: ctx.parent,
|
|
944
|
+
handler: handler as unknown as Handler<any, any, any>,
|
|
945
|
+
} satisfies EntryData;
|
|
946
|
+
|
|
947
|
+
/* We will throw if user is registring same route name twice */
|
|
948
|
+
invariant(
|
|
949
|
+
ctx.manifest.get(name) === undefined,
|
|
950
|
+
`Duplicate route name: ${name} at ${namespace}`,
|
|
951
|
+
);
|
|
952
|
+
/* Register route entry */
|
|
953
|
+
ctx.manifest.set(name, entry);
|
|
954
|
+
/* Merge handler.use defaults with explicit use */
|
|
955
|
+
const handlerUseFn = resolveHandlerUse(handler);
|
|
956
|
+
const mergedUse = mergeHandlerUse(handlerUseFn, use, "route");
|
|
957
|
+
/* Run use and attach handlers */
|
|
958
|
+
if (mergedUse) {
|
|
959
|
+
const result = runAndValidateUseItems(
|
|
960
|
+
store,
|
|
961
|
+
namespace,
|
|
962
|
+
entry,
|
|
963
|
+
mergedUse,
|
|
964
|
+
"route",
|
|
965
|
+
"use",
|
|
966
|
+
);
|
|
967
|
+
return { name: namespace, type: "route", uses: result } as RouteItem;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/* typesafe item */
|
|
971
|
+
return { name: namespace, type: "route" } as RouteItem;
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
const layout: RouteHelpers<any, any>["layout"] = (handler, use) => {
|
|
975
|
+
const { store, ctx } = requireDslContext(
|
|
976
|
+
"layout() must be called inside urls()",
|
|
977
|
+
);
|
|
978
|
+
|
|
979
|
+
invariant(
|
|
980
|
+
!ctx.parent || ctx.parent.type !== "parallel",
|
|
981
|
+
"layout() cannot be used inside parallel()",
|
|
982
|
+
);
|
|
983
|
+
|
|
984
|
+
const isRoot = !ctx.parent || ctx.parent === null;
|
|
985
|
+
const nextIndex = isRoot ? "$root" : store.getNextIndex("layout");
|
|
986
|
+
const namespace = `${ctx.namespace}.${nextIndex}`;
|
|
987
|
+
const shortCode = store.getShortCode("layout");
|
|
988
|
+
|
|
989
|
+
// Unwrap static handler definition, extract the actual handler function
|
|
990
|
+
const isStatic = isStaticHandler(handler);
|
|
991
|
+
const unwrappedHandler = isStatic ? handler.handler : handler;
|
|
992
|
+
|
|
993
|
+
const urlPrefix = getUrlPrefix();
|
|
994
|
+
const entry = {
|
|
995
|
+
...emptySegmentBase(),
|
|
996
|
+
id: namespace,
|
|
997
|
+
shortCode,
|
|
998
|
+
type: "layout",
|
|
999
|
+
parent: ctx.parent,
|
|
1000
|
+
handler: unwrappedHandler,
|
|
1001
|
+
...(urlPrefix ? { mountPath: urlPrefix } : {}),
|
|
1002
|
+
...(isStatic
|
|
1003
|
+
? {
|
|
1004
|
+
isStaticPrerender: true as const,
|
|
1005
|
+
...(handler.$$id ? { staticHandlerId: handler.$$id } : {}),
|
|
1006
|
+
}
|
|
1007
|
+
: {}),
|
|
1008
|
+
} satisfies EntryData;
|
|
1009
|
+
|
|
1010
|
+
// Capture namespace prefix on static handler for build-time reverse() resolution
|
|
1011
|
+
if (isStatic && handler.$$id && ctx.namePrefix) {
|
|
1012
|
+
(handler as any).$$routePrefix = ctx.namePrefix;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Merge handler.use defaults with explicit use
|
|
1016
|
+
const handlerUseFn = resolveHandlerUse(handler);
|
|
1017
|
+
const mergedUse = mergeHandlerUse(handlerUseFn, use, "layout");
|
|
1018
|
+
|
|
1019
|
+
// Run merged use callback if present
|
|
1020
|
+
let result: AllUseItems[] | undefined;
|
|
1021
|
+
if (mergedUse) {
|
|
1022
|
+
result = runAndValidateUseItems(
|
|
1023
|
+
store,
|
|
1024
|
+
namespace,
|
|
1025
|
+
entry,
|
|
1026
|
+
mergedUse,
|
|
1027
|
+
"layout",
|
|
1028
|
+
"use",
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// Check if this is an orphan layout (no routes in children, including nested caches)
|
|
1033
|
+
const hasRoutes =
|
|
1034
|
+
result &&
|
|
1035
|
+
Array.isArray(result) &&
|
|
1036
|
+
result.some((item) => hasRoutesInItem(item));
|
|
1037
|
+
|
|
1038
|
+
if (!hasRoutes) {
|
|
1039
|
+
// Orphan layouts must not contain other layouts as children.
|
|
1040
|
+
// If we're here, all child layouts are also orphan (if any had routes,
|
|
1041
|
+
// hasRoutesInItem would have returned true). Nested orphan chains are
|
|
1042
|
+
// confusing — use sibling orphan layouts instead.
|
|
1043
|
+
if (result) {
|
|
1044
|
+
invariant(
|
|
1045
|
+
!result.some((item) => item?.type === "layout"),
|
|
1046
|
+
`orphan layout cannot contain other layouts as children [${namespace}]`,
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
const parent = ctx.parent;
|
|
1051
|
+
|
|
1052
|
+
// Allow orphan layouts at root level if they're part of map() builder result
|
|
1053
|
+
if (!parent || parent === null) {
|
|
1054
|
+
if (!isRoot) {
|
|
1055
|
+
invariant(
|
|
1056
|
+
false,
|
|
1057
|
+
`Orphan layout cannot be used at non-root level without parent [${namespace}]`,
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
// Root-level orphan is allowed (e.g., sibling layouts in map() builder)
|
|
1061
|
+
} else {
|
|
1062
|
+
// Has parent - register as orphan layout
|
|
1063
|
+
invariant(
|
|
1064
|
+
parent.type === "route" ||
|
|
1065
|
+
parent.type === "layout" ||
|
|
1066
|
+
parent.type === "cache",
|
|
1067
|
+
`Orphan layouts can only be defined inside route or layout > check [${namespace}]`,
|
|
1068
|
+
);
|
|
1069
|
+
|
|
1070
|
+
attachOrphanSibling(parent, entry);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (result) {
|
|
1075
|
+
return { name: namespace, type: "layout", uses: result } as LayoutItem;
|
|
1076
|
+
}
|
|
1077
|
+
return {
|
|
1078
|
+
name: namespace,
|
|
1079
|
+
type: "layout",
|
|
1080
|
+
} as LayoutItem;
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
const isValidUseItem = (item: any): item is AllUseItems | undefined | null =>
|
|
1084
|
+
item == null ||
|
|
1085
|
+
(typeof item === "object" &&
|
|
1086
|
+
"type" in item &&
|
|
1087
|
+
ALL_USE_ITEM_TYPES.has(item.type));
|
|
1088
|
+
|
|
1089
|
+
// DSL helpers exported for direct import from @rangojs/router and for
|
|
1090
|
+
// assembly into the RouteHelpers object in helper-factories.ts. The route-item
|
|
1091
|
+
// types are discriminated by their `type` literal, so the helpers carry no brand.
|
|
1092
|
+
export {
|
|
1093
|
+
layout,
|
|
1094
|
+
cache,
|
|
1095
|
+
middleware,
|
|
1096
|
+
revalidate,
|
|
1097
|
+
parallel,
|
|
1098
|
+
intercept,
|
|
1099
|
+
when,
|
|
1100
|
+
errorBoundary,
|
|
1101
|
+
notFoundBoundary,
|
|
1102
|
+
route,
|
|
1103
|
+
loader,
|
|
1104
|
+
loading,
|
|
1105
|
+
transition,
|
|
1106
|
+
isValidUseItem,
|
|
1107
|
+
emptySegmentBase,
|
|
1108
|
+
runAndValidateUseItems,
|
|
1109
|
+
};
|