@rangojs/router 0.0.0-experimental.13 → 0.0.0-experimental.130
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 +1040 -5
- package/dist/__internal.d.ts +83 -0
- package/dist/__internal.d.ts.map +1 -0
- package/dist/__internal.js +19 -0
- package/dist/__internal.js.map +1 -0
- package/dist/__mocks__/version.d.ts +7 -0
- package/dist/__mocks__/version.d.ts.map +1 -0
- package/dist/__mocks__/version.js +7 -0
- package/dist/__mocks__/version.js.map +1 -0
- package/dist/__tests__/client-href.test.d.ts +2 -0
- package/dist/__tests__/client-href.test.d.ts.map +1 -0
- package/dist/__tests__/client-href.test.js +74 -0
- package/dist/__tests__/client-href.test.js.map +1 -0
- package/dist/__tests__/component-utils.test.d.ts +2 -0
- package/dist/__tests__/component-utils.test.d.ts.map +1 -0
- package/dist/__tests__/component-utils.test.js +51 -0
- package/dist/__tests__/component-utils.test.js.map +1 -0
- package/dist/__tests__/event-controller.test.d.ts +2 -0
- package/dist/__tests__/event-controller.test.d.ts.map +1 -0
- package/dist/__tests__/event-controller.test.js +538 -0
- package/dist/__tests__/event-controller.test.js.map +1 -0
- package/dist/__tests__/helpers/route-tree.d.ts +118 -0
- package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
- package/dist/__tests__/helpers/route-tree.js +374 -0
- package/dist/__tests__/helpers/route-tree.js.map +1 -0
- package/dist/__tests__/match-result.test.d.ts +2 -0
- package/dist/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/__tests__/match-result.test.js +154 -0
- package/dist/__tests__/match-result.test.js.map +1 -0
- package/dist/__tests__/navigation-store.test.d.ts +2 -0
- package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
- package/dist/__tests__/navigation-store.test.js +440 -0
- package/dist/__tests__/navigation-store.test.js.map +1 -0
- package/dist/__tests__/partial-update.test.d.ts +2 -0
- package/dist/__tests__/partial-update.test.d.ts.map +1 -0
- package/dist/__tests__/partial-update.test.js +1009 -0
- package/dist/__tests__/partial-update.test.js.map +1 -0
- package/dist/__tests__/reverse-types.test.d.ts +8 -0
- package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-types.test.js +656 -0
- package/dist/__tests__/reverse-types.test.js.map +1 -0
- package/dist/__tests__/route-definition.test.d.ts +2 -0
- package/dist/__tests__/route-definition.test.d.ts.map +1 -0
- package/dist/__tests__/route-definition.test.js +55 -0
- package/dist/__tests__/route-definition.test.js.map +1 -0
- package/dist/__tests__/router-helpers.test.d.ts +2 -0
- package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/router-helpers.test.js +377 -0
- package/dist/__tests__/router-helpers.test.js.map +1 -0
- package/dist/__tests__/router-integration-2.test.d.ts +2 -0
- package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration-2.test.js +426 -0
- package/dist/__tests__/router-integration-2.test.js.map +1 -0
- package/dist/__tests__/router-integration.test.d.ts +2 -0
- package/dist/__tests__/router-integration.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration.test.js +1051 -0
- package/dist/__tests__/router-integration.test.js.map +1 -0
- package/dist/__tests__/search-params.test.d.ts +5 -0
- package/dist/__tests__/search-params.test.d.ts.map +1 -0
- package/dist/__tests__/search-params.test.js +306 -0
- package/dist/__tests__/search-params.test.js.map +1 -0
- package/dist/__tests__/segment-system.test.d.ts +2 -0
- package/dist/__tests__/segment-system.test.d.ts.map +1 -0
- package/dist/__tests__/segment-system.test.js +627 -0
- package/dist/__tests__/segment-system.test.js.map +1 -0
- package/dist/__tests__/static-handler-types.test.d.ts +8 -0
- package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
- package/dist/__tests__/static-handler-types.test.js +63 -0
- package/dist/__tests__/static-handler-types.test.js.map +1 -0
- package/dist/__tests__/urls.test.d.ts +2 -0
- package/dist/__tests__/urls.test.d.ts.map +1 -0
- package/dist/__tests__/urls.test.js +421 -0
- package/dist/__tests__/urls.test.js.map +1 -0
- package/dist/__tests__/use-mount.test.d.ts +2 -0
- package/dist/__tests__/use-mount.test.d.ts.map +1 -0
- package/dist/__tests__/use-mount.test.js +35 -0
- package/dist/__tests__/use-mount.test.js.map +1 -0
- package/dist/bin/rango.d.ts +2 -0
- package/dist/bin/rango.d.ts.map +1 -0
- package/dist/bin/rango.js +1712 -212
- package/dist/bin/rango.js.map +1 -0
- package/dist/browser/event-controller.d.ts +191 -0
- package/dist/browser/event-controller.d.ts.map +1 -0
- package/dist/browser/event-controller.js +559 -0
- package/dist/browser/event-controller.js.map +1 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/link-interceptor.d.ts +38 -0
- package/dist/browser/link-interceptor.d.ts.map +1 -0
- package/dist/browser/link-interceptor.js +99 -0
- package/dist/browser/link-interceptor.js.map +1 -0
- package/dist/browser/logging.d.ts +10 -0
- package/dist/browser/logging.d.ts.map +1 -0
- package/dist/browser/logging.js +29 -0
- package/dist/browser/logging.js.map +1 -0
- package/dist/browser/lru-cache.d.ts +17 -0
- package/dist/browser/lru-cache.d.ts.map +1 -0
- package/dist/browser/lru-cache.js +50 -0
- package/dist/browser/lru-cache.js.map +1 -0
- package/dist/browser/merge-segment-loaders.d.ts +39 -0
- package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
- package/dist/browser/merge-segment-loaders.js +102 -0
- package/dist/browser/merge-segment-loaders.js.map +1 -0
- package/dist/browser/navigation-bridge.d.ts +102 -0
- package/dist/browser/navigation-bridge.d.ts.map +1 -0
- package/dist/browser/navigation-bridge.js +708 -0
- package/dist/browser/navigation-bridge.js.map +1 -0
- package/dist/browser/navigation-client.d.ts +25 -0
- package/dist/browser/navigation-client.d.ts.map +1 -0
- package/dist/browser/navigation-client.js +157 -0
- package/dist/browser/navigation-client.js.map +1 -0
- package/dist/browser/navigation-store.d.ts +101 -0
- package/dist/browser/navigation-store.d.ts.map +1 -0
- package/dist/browser/navigation-store.js +625 -0
- package/dist/browser/navigation-store.js.map +1 -0
- package/dist/browser/partial-update.d.ts +75 -0
- package/dist/browser/partial-update.d.ts.map +1 -0
- package/dist/browser/partial-update.js +426 -0
- package/dist/browser/partial-update.js.map +1 -0
- package/dist/browser/react/Link.d.ts +86 -0
- package/dist/browser/react/Link.d.ts.map +1 -0
- package/dist/browser/react/Link.js +128 -0
- package/dist/browser/react/Link.js.map +1 -0
- package/dist/browser/react/NavigationProvider.d.ts +63 -0
- package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
- package/dist/browser/react/NavigationProvider.js +216 -0
- package/dist/browser/react/NavigationProvider.js.map +1 -0
- package/dist/browser/react/ScrollRestoration.d.ts +75 -0
- package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
- package/dist/browser/react/ScrollRestoration.js +57 -0
- package/dist/browser/react/ScrollRestoration.js.map +1 -0
- package/dist/browser/react/context.d.ts +46 -0
- package/dist/browser/react/context.d.ts.map +1 -0
- package/dist/browser/react/context.js +10 -0
- package/dist/browser/react/context.js.map +1 -0
- package/dist/browser/react/index.d.ts +11 -0
- package/dist/browser/react/index.d.ts.map +1 -0
- package/dist/browser/react/index.js +22 -0
- package/dist/browser/react/index.js.map +1 -0
- package/dist/browser/react/location-state-shared.d.ts +63 -0
- package/dist/browser/react/location-state-shared.d.ts.map +1 -0
- package/dist/browser/react/location-state-shared.js +81 -0
- package/dist/browser/react/location-state-shared.js.map +1 -0
- package/dist/browser/react/location-state.d.ts +23 -0
- package/dist/browser/react/location-state.d.ts.map +1 -0
- package/dist/browser/react/location-state.js +29 -0
- package/dist/browser/react/location-state.js.map +1 -0
- package/dist/browser/react/mount-context.d.ts +24 -0
- package/dist/browser/react/mount-context.d.ts.map +1 -0
- package/dist/browser/react/mount-context.js +24 -0
- package/dist/browser/react/mount-context.js.map +1 -0
- package/dist/browser/react/use-action.d.ts +64 -0
- package/dist/browser/react/use-action.d.ts.map +1 -0
- package/dist/browser/react/use-action.js +134 -0
- package/dist/browser/react/use-action.js.map +1 -0
- package/dist/browser/react/use-client-cache.d.ts +41 -0
- package/dist/browser/react/use-client-cache.d.ts.map +1 -0
- package/{src/browser/react/use-client-cache.ts → dist/browser/react/use-client-cache.js} +9 -26
- package/dist/browser/react/use-client-cache.js.map +1 -0
- package/dist/browser/react/use-handle.d.ts +31 -0
- package/dist/browser/react/use-handle.d.ts.map +1 -0
- package/dist/browser/react/use-handle.js +144 -0
- package/dist/browser/react/use-handle.js.map +1 -0
- package/dist/browser/react/use-href.d.ts +33 -0
- package/dist/browser/react/use-href.d.ts.map +1 -0
- package/dist/browser/react/use-href.js +39 -0
- package/dist/browser/react/use-href.js.map +1 -0
- package/dist/browser/react/use-link-status.d.ts +37 -0
- package/dist/browser/react/use-link-status.d.ts.map +1 -0
- package/dist/browser/react/use-link-status.js +99 -0
- package/dist/browser/react/use-link-status.js.map +1 -0
- package/dist/browser/react/use-mount.d.ts +25 -0
- package/dist/browser/react/use-mount.d.ts.map +1 -0
- package/dist/browser/react/use-mount.js +30 -0
- package/dist/browser/react/use-mount.js.map +1 -0
- package/dist/browser/react/use-navigation.d.ts +27 -0
- package/dist/browser/react/use-navigation.d.ts.map +1 -0
- package/dist/browser/react/use-navigation.js +87 -0
- package/dist/browser/react/use-navigation.js.map +1 -0
- package/dist/browser/react/use-segments.d.ts +38 -0
- package/dist/browser/react/use-segments.d.ts.map +1 -0
- package/dist/browser/react/use-segments.js +130 -0
- package/dist/browser/react/use-segments.js.map +1 -0
- package/dist/browser/request-controller.d.ts +26 -0
- package/dist/browser/request-controller.d.ts.map +1 -0
- package/dist/browser/request-controller.js +147 -0
- package/dist/browser/request-controller.js.map +1 -0
- package/dist/browser/rsc-router.d.ts +129 -0
- package/dist/browser/rsc-router.d.ts.map +1 -0
- package/dist/browser/rsc-router.js +195 -0
- package/dist/browser/rsc-router.js.map +1 -0
- package/dist/browser/scroll-restoration.d.ts +93 -0
- package/dist/browser/scroll-restoration.d.ts.map +1 -0
- package/dist/browser/scroll-restoration.js +321 -0
- package/dist/browser/scroll-restoration.js.map +1 -0
- package/dist/browser/segment-structure-assert.d.ts +17 -0
- package/dist/browser/segment-structure-assert.d.ts.map +1 -0
- package/dist/browser/segment-structure-assert.js +59 -0
- package/dist/browser/segment-structure-assert.js.map +1 -0
- package/dist/browser/server-action-bridge.d.ts +26 -0
- package/dist/browser/server-action-bridge.d.ts.map +1 -0
- package/dist/browser/server-action-bridge.js +668 -0
- package/dist/browser/server-action-bridge.js.map +1 -0
- package/dist/browser/shallow.d.ts +12 -0
- package/dist/browser/shallow.d.ts.map +1 -0
- package/dist/browser/shallow.js +34 -0
- package/dist/browser/shallow.js.map +1 -0
- package/dist/browser/types.d.ts +369 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
- package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-cli.test.js +237 -0
- package/dist/build/__tests__/generate-cli.test.js.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.js +119 -0
- package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.js +620 -0
- package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.js +308 -0
- package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +81 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +276 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/build/generate-route-types.d.ts +115 -0
- package/dist/build/generate-route-types.d.ts.map +1 -0
- package/dist/build/generate-route-types.js +740 -0
- package/dist/build/generate-route-types.js.map +1 -0
- package/dist/build/index.d.ts +21 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +21 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/route-trie.d.ts +71 -0
- package/dist/build/route-trie.d.ts.map +1 -0
- package/dist/build/route-trie.js +175 -0
- package/dist/build/route-trie.js.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.js +208 -0
- package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
- package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
- package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
- package/dist/cache/__tests__/document-cache.test.js +345 -0
- package/dist/cache/__tests__/document-cache.test.js.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
- package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
- package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-store.test.js +367 -0
- package/dist/cache/__tests__/memory-store.test.js.map +1 -0
- package/dist/cache/cache-scope.d.ts +102 -0
- package/dist/cache/cache-scope.d.ts.map +1 -0
- package/dist/cache/cache-scope.js +440 -0
- package/dist/cache/cache-scope.js.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
- package/dist/cache/cf/cf-cache-store.d.ts +165 -0
- package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
- package/dist/cache/cf/cf-cache-store.js +242 -0
- package/dist/cache/cf/cf-cache-store.js.map +1 -0
- package/dist/cache/cf/index.d.ts +14 -0
- package/dist/cache/cf/index.d.ts.map +1 -0
- package/dist/cache/cf/index.js +17 -0
- package/dist/cache/cf/index.js.map +1 -0
- package/dist/cache/document-cache.d.ts +64 -0
- package/dist/cache/document-cache.d.ts.map +1 -0
- package/dist/cache/document-cache.js +228 -0
- package/dist/cache/document-cache.js.map +1 -0
- package/dist/cache/index.d.ts +19 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +21 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory-segment-store.d.ts +110 -0
- package/dist/cache/memory-segment-store.d.ts.map +1 -0
- package/dist/cache/memory-segment-store.js +117 -0
- package/dist/cache/memory-segment-store.js.map +1 -0
- package/dist/cache/memory-store.d.ts +41 -0
- package/dist/cache/memory-store.d.ts.map +1 -0
- package/dist/cache/memory-store.js +191 -0
- package/dist/cache/memory-store.js.map +1 -0
- package/dist/cache/types.d.ts +317 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +12 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/client.d.ts +248 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/client.rsc.d.ts +26 -0
- package/dist/client.rsc.d.ts.map +1 -0
- package/dist/client.rsc.js +46 -0
- package/dist/client.rsc.js.map +1 -0
- package/dist/component-utils.d.ts +36 -0
- package/dist/component-utils.d.ts.map +1 -0
- package/dist/component-utils.js +61 -0
- package/dist/component-utils.js.map +1 -0
- package/dist/components/DefaultDocument.d.ts +13 -0
- package/dist/components/DefaultDocument.d.ts.map +1 -0
- package/dist/components/DefaultDocument.js +15 -0
- package/dist/components/DefaultDocument.js.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +157 -0
- package/dist/debug.js.map +1 -0
- package/dist/default-error-boundary.d.ts +11 -0
- package/dist/default-error-boundary.d.ts.map +1 -0
- package/dist/default-error-boundary.js +45 -0
- package/dist/default-error-boundary.js.map +1 -0
- package/dist/deps/browser.d.ts +2 -0
- package/dist/deps/browser.d.ts.map +1 -0
- package/dist/deps/browser.js +3 -0
- package/dist/deps/browser.js.map +1 -0
- package/dist/deps/html-stream-client.d.ts +2 -0
- package/dist/deps/html-stream-client.d.ts.map +1 -0
- package/dist/deps/html-stream-client.js +3 -0
- package/dist/deps/html-stream-client.js.map +1 -0
- package/dist/deps/html-stream-server.d.ts +2 -0
- package/dist/deps/html-stream-server.d.ts.map +1 -0
- package/dist/deps/html-stream-server.js +3 -0
- package/dist/deps/html-stream-server.js.map +1 -0
- package/dist/deps/rsc.d.ts +2 -0
- package/dist/deps/rsc.d.ts.map +1 -0
- package/dist/deps/rsc.js +4 -0
- package/dist/deps/rsc.js.map +1 -0
- package/dist/deps/ssr.d.ts +2 -0
- package/dist/deps/ssr.d.ts.map +1 -0
- package/dist/deps/ssr.js +3 -0
- package/dist/deps/ssr.js.map +1 -0
- package/dist/errors.d.ts +174 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/handle.d.ts +78 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +82 -0
- package/dist/handle.js.map +1 -0
- package/dist/handles/MetaTags.d.ts +14 -0
- package/dist/handles/MetaTags.d.ts.map +1 -0
- package/dist/handles/MetaTags.js +136 -0
- package/dist/handles/MetaTags.js.map +1 -0
- package/dist/handles/index.d.ts +6 -0
- package/dist/handles/index.d.ts.map +1 -0
- package/{src/handles/index.ts → dist/handles/index.js} +1 -1
- package/dist/handles/index.js.map +1 -0
- package/dist/handles/meta.d.ts +39 -0
- package/dist/handles/meta.d.ts.map +1 -0
- package/dist/handles/meta.js +202 -0
- package/dist/handles/meta.js.map +1 -0
- package/dist/host/__tests__/errors.test.d.ts +2 -0
- package/dist/host/__tests__/errors.test.d.ts.map +1 -0
- package/dist/host/__tests__/errors.test.js +76 -0
- package/dist/host/__tests__/errors.test.js.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.js +251 -0
- package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/host/__tests__/router.test.d.ts +2 -0
- package/dist/host/__tests__/router.test.d.ts.map +1 -0
- package/dist/host/__tests__/router.test.js +241 -0
- package/dist/host/__tests__/router.test.js.map +1 -0
- package/dist/host/__tests__/testing.test.d.ts +2 -0
- package/dist/host/__tests__/testing.test.d.ts.map +1 -0
- package/dist/host/__tests__/testing.test.js +64 -0
- package/dist/host/__tests__/testing.test.js.map +1 -0
- package/dist/host/__tests__/utils.test.d.ts +2 -0
- package/dist/host/__tests__/utils.test.d.ts.map +1 -0
- package/dist/host/__tests__/utils.test.js +29 -0
- package/dist/host/__tests__/utils.test.js.map +1 -0
- package/dist/host/cookie-handler.d.ts +34 -0
- package/dist/host/cookie-handler.d.ts.map +1 -0
- package/dist/host/cookie-handler.js +124 -0
- package/dist/host/cookie-handler.js.map +1 -0
- package/dist/host/errors.d.ts +56 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +79 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +32 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pattern-matcher.d.ts +36 -0
- package/dist/host/pattern-matcher.d.ts.map +1 -0
- package/dist/host/pattern-matcher.js +172 -0
- package/dist/host/pattern-matcher.js.map +1 -0
- package/dist/host/router.d.ts +26 -0
- package/dist/host/router.d.ts.map +1 -0
- package/dist/host/router.js +218 -0
- package/dist/host/router.js.map +1 -0
- package/dist/host/testing.d.ts +36 -0
- package/dist/host/testing.d.ts.map +1 -0
- package/dist/host/testing.js +55 -0
- package/dist/host/testing.js.map +1 -0
- package/dist/host/types.d.ts +115 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/host/utils.d.ts +21 -0
- package/dist/host/utils.d.ts.map +1 -0
- package/dist/host/utils.js +23 -0
- package/dist/host/utils.js.map +1 -0
- package/dist/href-client.d.ts +131 -0
- package/dist/href-client.d.ts.map +1 -0
- package/dist/href-client.js +64 -0
- package/dist/href-client.js.map +1 -0
- package/{src/href-context.ts → dist/href-context.d.ts} +7 -11
- package/dist/href-context.d.ts.map +1 -0
- package/dist/href-context.js +21 -0
- package/dist/href-context.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/index.rsc.d.ts +32 -0
- package/dist/index.rsc.d.ts.map +1 -0
- package/dist/index.rsc.js +40 -0
- package/dist/index.rsc.js.map +1 -0
- package/dist/internal-debug.d.ts +2 -0
- package/dist/internal-debug.d.ts.map +1 -0
- package/dist/internal-debug.js +5 -0
- package/dist/internal-debug.js.map +1 -0
- package/dist/loader.d.ts +14 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +20 -0
- package/dist/loader.js.map +1 -0
- package/dist/loader.rsc.d.ts +19 -0
- package/dist/loader.rsc.d.ts.map +1 -0
- package/dist/loader.rsc.js +99 -0
- package/dist/loader.rsc.js.map +1 -0
- package/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/testing/vitest.js +82 -0
- package/dist/theme/ThemeProvider.d.ts +20 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +240 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/ThemeScript.d.ts +48 -0
- package/dist/theme/ThemeScript.d.ts.map +1 -0
- package/dist/theme/ThemeScript.js +13 -0
- package/dist/theme/ThemeScript.js.map +1 -0
- package/dist/theme/__tests__/theme.test.d.ts +2 -0
- package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
- package/dist/theme/__tests__/theme.test.js +103 -0
- package/dist/theme/__tests__/theme.test.js.map +1 -0
- package/dist/theme/constants.d.ts +29 -0
- package/dist/theme/constants.d.ts.map +1 -0
- package/dist/theme/constants.js +48 -0
- package/dist/theme/constants.js.map +1 -0
- package/dist/theme/index.d.ts +31 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +36 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-context.d.ts +40 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +60 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-script.d.ts +27 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +147 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/dist/theme/types.d.ts +163 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +11 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme/use-theme.d.ts +12 -0
- package/dist/theme/use-theme.d.ts.map +1 -0
- package/dist/theme/use-theme.js +40 -0
- package/dist/theme/use-theme.js.map +1 -0
- package/dist/types.d.ts +1479 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/urls.d.ts +441 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.gen.d.ts +8 -0
- package/dist/urls.gen.d.ts.map +1 -0
- package/dist/urls.gen.js +8 -0
- package/dist/urls.gen.js.map +1 -0
- package/dist/urls.js +443 -0
- package/dist/urls.js.map +1 -0
- package/dist/use-loader.d.ts +127 -0
- package/dist/use-loader.d.ts.map +1 -0
- package/dist/use-loader.js +237 -0
- package/dist/use-loader.js.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
- package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.js +39 -0
- package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
- package/dist/vite/ast-handler-extract.d.ts +49 -0
- package/dist/vite/ast-handler-extract.d.ts.map +1 -0
- package/dist/vite/ast-handler-extract.js +249 -0
- package/dist/vite/ast-handler-extract.js.map +1 -0
- package/dist/vite/expose-action-id.d.ts +19 -0
- package/dist/vite/expose-action-id.d.ts.map +1 -0
- package/dist/vite/expose-action-id.js +250 -0
- package/dist/vite/expose-action-id.js.map +1 -0
- package/dist/vite/expose-id-utils.d.ts +69 -0
- package/dist/vite/expose-id-utils.d.ts.map +1 -0
- package/dist/vite/expose-id-utils.js +289 -0
- package/dist/vite/expose-id-utils.js.map +1 -0
- package/dist/vite/expose-internal-ids.d.ts +22 -0
- package/dist/vite/expose-internal-ids.d.ts.map +1 -0
- package/dist/vite/expose-internal-ids.js +886 -0
- package/dist/vite/expose-internal-ids.js.map +1 -0
- package/dist/vite/index.d.ts +149 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +6263 -2733
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/package-resolution.d.ts +43 -0
- package/dist/vite/package-resolution.d.ts.map +1 -0
- package/{src/vite/package-resolution.ts → dist/vite/package-resolution.js} +53 -66
- package/dist/vite/package-resolution.js.map +1 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/dist/vite/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/{src/vite/virtual-entries.ts → dist/vite/virtual-entries.js} +12 -16
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +123 -68
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +312 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +486 -0
- package/skills/caching/SKILL.md +349 -24
- package/skills/composability/SKILL.md +197 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +278 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +175 -8
- package/skills/layout/SKILL.md +128 -5
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +604 -54
- package/skills/middleware/SKILL.md +213 -37
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +41 -10
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +276 -3
- package/skills/prerender/SKILL.md +432 -52
- package/skills/rango/SKILL.md +313 -21
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +248 -120
- package/skills/route/SKILL.md +287 -21
- package/skills/router-setup/SKILL.md +231 -33
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +120 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +547 -107
- package/skills/use-cache/SKILL.md +355 -0
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +162 -200
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +323 -563
- package/src/browser/navigation-client.ts +219 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +104 -112
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +328 -348
- package/src/browser/prefetch/cache.ts +324 -0
- package/src/browser/prefetch/fetch.ts +357 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +194 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +253 -71
- package/src/browser/react/NavigationProvider.tsx +155 -34
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +53 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +260 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-link-status.ts +6 -9
- package/src/browser/react/use-navigation.ts +44 -68
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +124 -0
- package/src/browser/rsc-router.tsx +290 -72
- package/src/browser/scroll-restoration.ts +132 -49
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +621 -613
- package/src/browser/types.ts +175 -50
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +123 -56
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +9 -6
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +165 -34
- 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 +113 -0
- package/src/build/route-types/include-resolution.ts +418 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +131 -0
- package/src/build/route-types/router-processing.ts +651 -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-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +165 -0
- package/src/cache/cache-runtime.ts +444 -0
- package/src/cache/cache-scope.ts +231 -325
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2644 -75
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +172 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +104 -0
- package/src/cache/index.ts +11 -35
- package/src/cache/memory-segment-store.ts +307 -30
- package/src/cache/profile-registry.ts +49 -0
- package/src/cache/read-through-swr.ts +164 -0
- package/src/cache/segment-codec.ts +240 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +94 -211
- package/src/client.rsc.tsx +8 -21
- package/src/client.tsx +123 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +106 -10
- package/src/handle.ts +76 -23
- package/src/handles/MetaTags.tsx +73 -34
- package/src/handles/breadcrumbs.ts +77 -0
- package/src/handles/meta.ts +30 -52
- package/src/host/cookie-handler.ts +21 -51
- package/src/host/errors.ts +8 -32
- package/src/host/index.ts +12 -9
- package/src/host/pattern-matcher.ts +34 -77
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +174 -34
- package/src/index.ts +241 -73
- package/src/internal-debug.ts +8 -4
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/network-error-thrower.tsx +4 -7
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +14 -13
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +445 -24
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +10 -72
- package/src/route-definition/dsl-helpers.ts +1116 -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 +135 -0
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-definition.ts +1 -1450
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +72 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +215 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +22 -26
- package/src/router/find-match.ts +181 -0
- package/src/router/handler-context.ts +372 -125
- package/src/router/instrument.ts +308 -0
- package/src/router/intercept-resolution.ts +34 -27
- package/src/router/lazy-includes.ts +200 -0
- package/src/router/loader-resolution.ts +381 -147
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +88 -51
- package/src/router/match-api.ts +162 -245
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +90 -89
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +75 -33
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +421 -413
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +263 -79
- package/src/router/prerender-match.ts +541 -0
- package/src/router/preview-match.ts +100 -0
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +143 -44
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +41 -47
- package/src/router/router-interfaces.ts +525 -0
- package/src/router/router-options.ts +726 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +748 -0
- package/src/router/segment-resolution/helpers.ts +313 -0
- package/src/router/segment-resolution/loader-cache.ts +207 -0
- package/src/router/segment-resolution/revalidation.ts +1322 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +24 -1354
- package/src/router/segment-wrappers.ts +289 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +172 -60
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +748 -2376
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +861 -1141
- package/src/rsc/helpers.ts +269 -19
- package/src/rsc/index.ts +1 -21
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +235 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +413 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +374 -0
- package/src/rsc/rsc-rendering.ts +261 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +376 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/types.ts +58 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +70 -74
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +292 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +439 -85
- package/src/server/cookie-store.ts +265 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +112 -31
- package/src/server/loader-registry.ts +23 -82
- package/src/server/request-context.ts +724 -143
- package/src/server.ts +26 -164
- package/src/ssr/index.tsx +113 -36
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +21 -67
- package/src/theme/ThemeScript.tsx +5 -11
- package/src/theme/constants.ts +5 -14
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +21 -32
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +79 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +126 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +171 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +160 -0
- package/src/urls/index.ts +43 -0
- package/src/urls/path-helper-types.ts +386 -0
- package/src/urls/path-helper.ts +275 -0
- package/src/urls/pattern-types.ts +124 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +291 -0
- package/src/urls/urls-function.ts +81 -0
- package/src/urls.ts +1 -1323
- package/src/use-loader.tsx +406 -141
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -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 +467 -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 +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +17 -2259
- package/src/vite/plugin-types.ts +221 -0
- package/src/vite/plugins/cjs-to-esm.ts +83 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +13 -87
- package/src/vite/plugins/expose-ids/export-analysis.ts +338 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +141 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +57 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +124 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +806 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/version-injector.ts +79 -0
- package/src/vite/plugins/version-plugin.ts +275 -0
- package/src/vite/plugins/virtual-entries.ts +108 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +444 -0
- package/src/vite/router-discovery.ts +1581 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +193 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +223 -0
- package/src/vite/utils/shared-utils.ts +219 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LoaderStore — shared subscription model for `useLoader` / `useFetchLoader`.
|
|
3
|
+
*
|
|
4
|
+
* Each bucket key gets one entry that holds the latest committed snapshot plus a
|
|
5
|
+
* set of listeners. Snapshots are frozen and replaced atomically on mutation, so
|
|
6
|
+
* subscribers can compare snapshot identity and avoid unnecessary updates
|
|
7
|
+
* between real changes.
|
|
8
|
+
*
|
|
9
|
+
* The bucket key is `loader.$$id` by default, or `loader.$$id + key` when the
|
|
10
|
+
* hook is given an explicit client refresh `key`. Multiple buckets belonging to
|
|
11
|
+
* the same loader form a family (indexed by `loader.$$id`) so a navigation /
|
|
12
|
+
* route-context reset can clear them all at once via `clearFamily`.
|
|
13
|
+
*
|
|
14
|
+
* Mutations that come in for an old request id (e.g. a slow response that
|
|
15
|
+
* resolves after a newer load() was issued, or after a navigation cleared the
|
|
16
|
+
* entry) are silently dropped. `reserveRequestId` is the only way to claim the
|
|
17
|
+
* "latest" slot; `clear` bumps it too so pre-navigation in-flight loads cannot
|
|
18
|
+
* commit into the new route's context.
|
|
19
|
+
*
|
|
20
|
+
* Bucket lifecycle differs by registration:
|
|
21
|
+
* - Sticky buckets (a route-registered reader subscribed at least once) keep
|
|
22
|
+
* their entry after the last subscriber leaves so an in-flight load() can
|
|
23
|
+
* still commit on remount; they reset on navigation via `clearFamily`.
|
|
24
|
+
* - Ephemeral buckets (only ever subscribed by readers with no route context,
|
|
25
|
+
* i.e. keyed `useFetchLoader` of an unregistered loader) have no
|
|
26
|
+
* route-context reset trigger, so they are reference-counted: dropped once
|
|
27
|
+
* the last subscriber unsubscribes. The drop is deferred to a microtask and
|
|
28
|
+
* cancelled on resubscribe so a StrictMode / transition remount does not
|
|
29
|
+
* reclaim a bucket that is about to be reused, and is held until any
|
|
30
|
+
* in-flight load settles.
|
|
31
|
+
*
|
|
32
|
+
* The store is intentionally module-level: each browser tab is its own JS
|
|
33
|
+
* realm, so there is no cross-request pollution. Server renders never mutate
|
|
34
|
+
* the store — the hook falls back to `OutletContext.loaderData`.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
export interface LoaderEntry<T = unknown> {
|
|
38
|
+
readonly value: T | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Whether a load has committed a value to this bucket. Distinguishes a
|
|
41
|
+
* committed `null`/`undefined` result from "never loaded", so a loader that
|
|
42
|
+
* resolves to a falsy value is not mistaken for an empty bucket and is not
|
|
43
|
+
* overridden by the server-seeded context value.
|
|
44
|
+
*/
|
|
45
|
+
readonly hasValue: boolean;
|
|
46
|
+
readonly error: Error | null;
|
|
47
|
+
readonly isLoading: boolean;
|
|
48
|
+
/** Identifies the request that produced this snapshot. 0 means "no request". */
|
|
49
|
+
readonly requestId: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const EMPTY_SNAPSHOT: LoaderEntry = Object.freeze({
|
|
53
|
+
value: undefined,
|
|
54
|
+
hasValue: false,
|
|
55
|
+
error: null,
|
|
56
|
+
isLoading: false,
|
|
57
|
+
requestId: 0,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Options for `subscribe`.
|
|
62
|
+
*/
|
|
63
|
+
export interface SubscribeOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Family id (`loader.$$id`) this bucket belongs to. `clearFamily` uses it to
|
|
66
|
+
* reach every keyed bucket of the same loader. Defaults to the bucket key.
|
|
67
|
+
*/
|
|
68
|
+
loaderId?: string;
|
|
69
|
+
/**
|
|
70
|
+
* When true, this subscription is from a reader with no route context (keyed
|
|
71
|
+
* `useFetchLoader` of an unregistered loader). Such buckets have no
|
|
72
|
+
* route-context reset trigger and are reference-counted instead. A bucket
|
|
73
|
+
* becomes sticky for the rest of its life as soon as any non-ephemeral
|
|
74
|
+
* subscriber attaches, and from then on resets via `clearFamily`.
|
|
75
|
+
*/
|
|
76
|
+
ephemeral?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Cross-loader refresh group name(s). Tags this bucket so `refreshGroups(name)`
|
|
79
|
+
* can refresh it alongside buckets of other loaders. A bucket may be tagged
|
|
80
|
+
* with several group names at once (pass an array); it is then refreshed when
|
|
81
|
+
* ANY of its groups is refreshed. Group membership follows subscriber presence:
|
|
82
|
+
* a bucket leaves a group when that group's last subscriber unsubscribes.
|
|
83
|
+
*/
|
|
84
|
+
group?: string | string[];
|
|
85
|
+
/**
|
|
86
|
+
* Plain-GET refresh thunk used by `refreshGroups`. Provided alongside `group`.
|
|
87
|
+
* Refreshes this bucket in place (no params/body) and rejects on failure.
|
|
88
|
+
*/
|
|
89
|
+
refetch?: () => Promise<void>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface InternalEntry {
|
|
93
|
+
snapshot: LoaderEntry;
|
|
94
|
+
listeners: Set<() => void>;
|
|
95
|
+
/** Monotonically increasing. Bumped by reserveRequestId() and clear(). */
|
|
96
|
+
latestRequestId: number;
|
|
97
|
+
/** Family id (loader.$$id) this bucket belongs to. */
|
|
98
|
+
loaderId: string;
|
|
99
|
+
/**
|
|
100
|
+
* True once any non-ephemeral subscriber has attached. Sticky buckets are
|
|
101
|
+
* never reference-count-dropped; they reset via clearFamily().
|
|
102
|
+
*/
|
|
103
|
+
sticky: boolean;
|
|
104
|
+
/** A deferred refcount-drop microtask is scheduled and not yet cancelled. */
|
|
105
|
+
pendingClear: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* The last subscriber left while a load() was in flight. Drop the bucket once
|
|
108
|
+
* that request settles, if it is still subscriberless.
|
|
109
|
+
*/
|
|
110
|
+
clearWhenSettled: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Cross-loader refresh groups this bucket belongs to, mapped to the number of
|
|
113
|
+
* current subscribers that requested each group. A bucket can be in several
|
|
114
|
+
* groups at once (one read tagged with multiple names, or different subscribers
|
|
115
|
+
* tagging the same shared bucket with different names); refcounting keeps
|
|
116
|
+
* membership independent of subscribe/unsubscribe order.
|
|
117
|
+
*/
|
|
118
|
+
groups: Map<string, number>;
|
|
119
|
+
/** Plain-GET refresh thunk for `refreshGroups`, set while in any group. */
|
|
120
|
+
refetch: (() => Promise<void>) | undefined;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Normalize a group tag option (`undefined | string | string[]`) to a deduped
|
|
125
|
+
* list of names. Deduping keeps a single subscriber from being counted more than
|
|
126
|
+
* once in one group when the caller passes a repeated name.
|
|
127
|
+
*/
|
|
128
|
+
function normalizeGroups(group: string | string[] | undefined): string[] {
|
|
129
|
+
if (group === undefined) return [];
|
|
130
|
+
if (typeof group === "string") return [group];
|
|
131
|
+
return [...new Set(group)];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export class LoaderStore {
|
|
135
|
+
private readonly entries = new Map<string, InternalEntry>();
|
|
136
|
+
/** loader.$$id -> set of bucket keys, so clearFamily() can reach every bucket. */
|
|
137
|
+
private readonly families = new Map<string, Set<string>>();
|
|
138
|
+
/** refresh group name -> set of bucket keys, for refreshGroups(). */
|
|
139
|
+
private readonly groups = new Map<string, Set<string>>();
|
|
140
|
+
|
|
141
|
+
private getOrCreate(bucketKey: string): InternalEntry {
|
|
142
|
+
let e = this.entries.get(bucketKey);
|
|
143
|
+
if (!e) {
|
|
144
|
+
e = {
|
|
145
|
+
snapshot: EMPTY_SNAPSHOT,
|
|
146
|
+
listeners: new Set(),
|
|
147
|
+
latestRequestId: 0,
|
|
148
|
+
loaderId: bucketKey,
|
|
149
|
+
sticky: false,
|
|
150
|
+
pendingClear: false,
|
|
151
|
+
clearWhenSettled: false,
|
|
152
|
+
groups: new Map(),
|
|
153
|
+
refetch: undefined,
|
|
154
|
+
};
|
|
155
|
+
this.entries.set(bucketKey, e);
|
|
156
|
+
}
|
|
157
|
+
return e;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private registerFamily(loaderId: string, bucketKey: string): void {
|
|
161
|
+
let fam = this.families.get(loaderId);
|
|
162
|
+
if (!fam) {
|
|
163
|
+
fam = new Set();
|
|
164
|
+
this.families.set(loaderId, fam);
|
|
165
|
+
}
|
|
166
|
+
fam.add(bucketKey);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Subscribe to entry changes for `bucketKey`.
|
|
171
|
+
* Returns an unsubscribe function. A sticky bucket's entry is kept around even
|
|
172
|
+
* after the last subscriber leaves so that an in-flight `load()` can still
|
|
173
|
+
* commit if the consumer remounts. An ephemeral bucket is dropped once its
|
|
174
|
+
* last subscriber leaves (deferred, see maybeScheduleRefcountClear).
|
|
175
|
+
*/
|
|
176
|
+
subscribe(
|
|
177
|
+
bucketKey: string,
|
|
178
|
+
cb: () => void,
|
|
179
|
+
options?: SubscribeOptions,
|
|
180
|
+
): () => void {
|
|
181
|
+
const e = this.getOrCreate(bucketKey);
|
|
182
|
+
const loaderId = options?.loaderId ?? bucketKey;
|
|
183
|
+
e.loaderId = loaderId;
|
|
184
|
+
this.registerFamily(loaderId, bucketKey);
|
|
185
|
+
if (options?.ephemeral !== true) e.sticky = true;
|
|
186
|
+
// Normalize the group tag(s) to a deduped list so one subscriber is counted
|
|
187
|
+
// once per distinct group, and subscribe/unsubscribe stay symmetric (the
|
|
188
|
+
// same list drives both addToGroup and releaseGroup).
|
|
189
|
+
const groups = normalizeGroups(options?.group);
|
|
190
|
+
for (const group of groups) {
|
|
191
|
+
this.addToGroup(group, bucketKey, e, options?.refetch);
|
|
192
|
+
}
|
|
193
|
+
// A fresh subscriber means the bucket is wanted again: cancel any pending
|
|
194
|
+
// refcount-drop and the settle-then-drop intent.
|
|
195
|
+
e.pendingClear = false;
|
|
196
|
+
e.clearWhenSettled = false;
|
|
197
|
+
e.listeners.add(cb);
|
|
198
|
+
return () => {
|
|
199
|
+
e.listeners.delete(cb);
|
|
200
|
+
// Group membership is refcounted per subscriber so refreshGroups() never
|
|
201
|
+
// fetches for an unmounted reader, and a bucket shared by subscribers in
|
|
202
|
+
// different groups stays in each group until ALL of that group's
|
|
203
|
+
// subscribers have left (order-independent).
|
|
204
|
+
for (const group of groups) this.releaseGroup(group, bucketKey, e);
|
|
205
|
+
this.maybeScheduleRefcountClear(bucketKey, e);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private addToGroup(
|
|
210
|
+
group: string,
|
|
211
|
+
bucketKey: string,
|
|
212
|
+
e: InternalEntry,
|
|
213
|
+
refetch: (() => Promise<void>) | undefined,
|
|
214
|
+
): void {
|
|
215
|
+
e.groups.set(group, (e.groups.get(group) ?? 0) + 1);
|
|
216
|
+
// One thunk per bucket — every subscriber of a bucket provides an
|
|
217
|
+
// equivalent plain-GET refresh, so keeping the latest is fine.
|
|
218
|
+
if (refetch) e.refetch = refetch;
|
|
219
|
+
let members = this.groups.get(group);
|
|
220
|
+
if (!members) {
|
|
221
|
+
members = new Set();
|
|
222
|
+
this.groups.set(group, members);
|
|
223
|
+
}
|
|
224
|
+
members.add(bucketKey);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private releaseGroup(
|
|
228
|
+
group: string,
|
|
229
|
+
bucketKey: string,
|
|
230
|
+
e: InternalEntry,
|
|
231
|
+
): void {
|
|
232
|
+
const next = (e.groups.get(group) ?? 0) - 1;
|
|
233
|
+
if (next > 0) {
|
|
234
|
+
e.groups.set(group, next);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
e.groups.delete(group);
|
|
238
|
+
const members = this.groups.get(group);
|
|
239
|
+
if (members) {
|
|
240
|
+
members.delete(bucketKey);
|
|
241
|
+
if (members.size === 0) this.groups.delete(group);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Remove a bucket from every group it belongs to (used when it is dropped). */
|
|
246
|
+
private removeFromAllGroups(bucketKey: string, e: InternalEntry): void {
|
|
247
|
+
for (const group of e.groups.keys()) {
|
|
248
|
+
const members = this.groups.get(group);
|
|
249
|
+
if (members) {
|
|
250
|
+
members.delete(bucketKey);
|
|
251
|
+
if (members.size === 0) this.groups.delete(group);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
e.groups.clear();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Refresh every currently-mounted bucket tagged with ANY of the given group
|
|
259
|
+
* names, with a plain GET (no params/body). Accepts a single name or an array
|
|
260
|
+
* of names. A bucket that belongs to more than one of the named groups is
|
|
261
|
+
* refreshed exactly once (members are unioned and deduped by bucket key), as
|
|
262
|
+
* are multiple reads of one bucket. Resolves when all refreshes settle; rejects
|
|
263
|
+
* with an `AggregateError` of the failures if any member fails — each failing
|
|
264
|
+
* member also records its error on its own snapshot.
|
|
265
|
+
*/
|
|
266
|
+
async refreshGroups(groups: string | string[]): Promise<void> {
|
|
267
|
+
const names = typeof groups === "string" ? [groups] : groups;
|
|
268
|
+
// Union the member buckets across every named group, deduped by key, so a
|
|
269
|
+
// bucket tagged into two of the requested groups is fetched a single time.
|
|
270
|
+
const buckets = new Set<string>();
|
|
271
|
+
for (const name of names) {
|
|
272
|
+
const members = this.groups.get(name);
|
|
273
|
+
if (!members) continue;
|
|
274
|
+
for (const bucketKey of members) buckets.add(bucketKey);
|
|
275
|
+
}
|
|
276
|
+
if (buckets.size === 0) return;
|
|
277
|
+
const thunks: Array<() => Promise<void>> = [];
|
|
278
|
+
for (const bucketKey of buckets) {
|
|
279
|
+
const e = this.entries.get(bucketKey);
|
|
280
|
+
if (!e || e.listeners.size === 0 || !e.refetch) continue;
|
|
281
|
+
thunks.push(e.refetch);
|
|
282
|
+
}
|
|
283
|
+
if (thunks.length === 0) return;
|
|
284
|
+
const results = await Promise.allSettled(thunks.map((t) => t()));
|
|
285
|
+
const reasons = results
|
|
286
|
+
.filter((r): r is PromiseRejectedResult => r.status === "rejected")
|
|
287
|
+
.map((r) => r.reason);
|
|
288
|
+
if (reasons.length > 0) {
|
|
289
|
+
const label = names.map((n) => `"${n}"`).join(", ");
|
|
290
|
+
throw new AggregateError(
|
|
291
|
+
reasons,
|
|
292
|
+
`refreshGroups(${label}) had ${reasons.length} failure(s)`,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Schedule a deferred drop for an ad-hoc (never-sticky) bucket whose last
|
|
299
|
+
* subscriber just left. Deferred to a microtask so a StrictMode / transition
|
|
300
|
+
* remount that resubscribes in the same tick cancels it.
|
|
301
|
+
*/
|
|
302
|
+
private maybeScheduleRefcountClear(
|
|
303
|
+
bucketKey: string,
|
|
304
|
+
e: InternalEntry,
|
|
305
|
+
): void {
|
|
306
|
+
if (e.listeners.size > 0) return;
|
|
307
|
+
// Sticky buckets persist for remount; they reset via clearFamily().
|
|
308
|
+
if (e.sticky) return;
|
|
309
|
+
if (e.pendingClear) return;
|
|
310
|
+
e.pendingClear = true;
|
|
311
|
+
queueMicrotask(() => {
|
|
312
|
+
if (!e.pendingClear) return; // cancelled by a resubscribe
|
|
313
|
+
e.pendingClear = false;
|
|
314
|
+
if (e.listeners.size > 0) return; // resubscribed before the microtask ran
|
|
315
|
+
if (e.snapshot.isLoading) {
|
|
316
|
+
// Don't drop mid-flight; let the request commit, then drop.
|
|
317
|
+
e.clearWhenSettled = true;
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
this.dropBucket(bucketKey);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** Remove a bucket entry entirely and prune it from its family/group indexes. */
|
|
325
|
+
private dropBucket(bucketKey: string): void {
|
|
326
|
+
const e = this.entries.get(bucketKey);
|
|
327
|
+
if (!e) return;
|
|
328
|
+
this.removeFromAllGroups(bucketKey, e);
|
|
329
|
+
this.entries.delete(bucketKey);
|
|
330
|
+
const fam = this.families.get(e.loaderId);
|
|
331
|
+
if (fam) {
|
|
332
|
+
fam.delete(bucketKey);
|
|
333
|
+
if (fam.size === 0) this.families.delete(e.loaderId);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** Drop an ephemeral bucket that settled with no subscribers left. */
|
|
338
|
+
private dropIfSettled(bucketKey: string, e: InternalEntry): void {
|
|
339
|
+
if (e.clearWhenSettled && e.listeners.size === 0) {
|
|
340
|
+
e.clearWhenSettled = false;
|
|
341
|
+
this.dropBucket(bucketKey);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Returns the current snapshot for `bucketKey`. Stable reference between
|
|
347
|
+
* mutations — subscribers rely on this to avoid spurious re-renders.
|
|
348
|
+
* Returns `EMPTY_SNAPSHOT` (a singleton) when the entry has never been
|
|
349
|
+
* mutated or has been cleared.
|
|
350
|
+
*/
|
|
351
|
+
getSnapshot(bucketKey: string): LoaderEntry {
|
|
352
|
+
return this.entries.get(bucketKey)?.snapshot ?? EMPTY_SNAPSHOT;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Reserve a fresh request id for an upcoming `load()` call. The returned id
|
|
357
|
+
* is the new "latest"; any older in-flight requests will fail their gating
|
|
358
|
+
* check on `finishData` / `finishError` / `finishLoading` and be dropped.
|
|
359
|
+
*
|
|
360
|
+
* Callers should follow with `beginRequest(id, requestId)` to flip the
|
|
361
|
+
* loading flag on AND clear any leftover error from a previous attempt
|
|
362
|
+
* — the latter matters for `throwOnError: false` consumers, which would
|
|
363
|
+
* otherwise keep showing the stale error throughout the retry.
|
|
364
|
+
*/
|
|
365
|
+
reserveRequestId(bucketKey: string): number {
|
|
366
|
+
const e = this.getOrCreate(bucketKey);
|
|
367
|
+
e.latestRequestId++;
|
|
368
|
+
return e.latestRequestId;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Mark the request as in-flight: `isLoading = true`, `error = null`.
|
|
373
|
+
* Combines the two operations so a retry doesn't render the previous
|
|
374
|
+
* error during the new request. Gated on `requestId === latestRequestId`
|
|
375
|
+
* for symmetry with the other mutators.
|
|
376
|
+
*/
|
|
377
|
+
beginRequest(bucketKey: string, requestId: number): void {
|
|
378
|
+
const e = this.entries.get(bucketKey);
|
|
379
|
+
if (!e || requestId !== e.latestRequestId) return;
|
|
380
|
+
if (e.snapshot.isLoading && e.snapshot.error === null) return;
|
|
381
|
+
e.snapshot = Object.freeze({
|
|
382
|
+
value: e.snapshot.value,
|
|
383
|
+
hasValue: e.snapshot.hasValue,
|
|
384
|
+
error: null,
|
|
385
|
+
isLoading: true,
|
|
386
|
+
requestId,
|
|
387
|
+
});
|
|
388
|
+
this.notify(e);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Commit a successful result. No-op if `requestId` is not the latest
|
|
393
|
+
* (a newer `load()` was issued or `clear()` ran). Clearing `error` is
|
|
394
|
+
* intentional: a successful refetch should hide the previous failure.
|
|
395
|
+
*/
|
|
396
|
+
finishData<T>(bucketKey: string, requestId: number, value: T): void {
|
|
397
|
+
const e = this.entries.get(bucketKey);
|
|
398
|
+
if (!e || requestId !== e.latestRequestId) return;
|
|
399
|
+
e.snapshot = Object.freeze({
|
|
400
|
+
value,
|
|
401
|
+
hasValue: true,
|
|
402
|
+
error: null,
|
|
403
|
+
isLoading: false,
|
|
404
|
+
requestId,
|
|
405
|
+
});
|
|
406
|
+
this.notify(e);
|
|
407
|
+
this.dropIfSettled(bucketKey, e);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Commit an error. Preserves the last good `value` so consumers can keep
|
|
412
|
+
* showing previous data while displaying the error if they choose. No-op
|
|
413
|
+
* if `requestId` is not the latest.
|
|
414
|
+
*/
|
|
415
|
+
finishError(bucketKey: string, requestId: number, error: Error): void {
|
|
416
|
+
const e = this.entries.get(bucketKey);
|
|
417
|
+
if (!e || requestId !== e.latestRequestId) return;
|
|
418
|
+
e.snapshot = Object.freeze({
|
|
419
|
+
value: e.snapshot.value,
|
|
420
|
+
hasValue: e.snapshot.hasValue,
|
|
421
|
+
error,
|
|
422
|
+
isLoading: false,
|
|
423
|
+
requestId,
|
|
424
|
+
});
|
|
425
|
+
this.notify(e);
|
|
426
|
+
this.dropIfSettled(bucketKey, e);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Update loading flag. Gated on `requestId` to fix the race where an old
|
|
431
|
+
* load() finishes after a new one started — its `setLoading(false)` would
|
|
432
|
+
* otherwise hide the new request's spinner.
|
|
433
|
+
*/
|
|
434
|
+
setLoading(bucketKey: string, requestId: number, isLoading: boolean): void {
|
|
435
|
+
const e = this.entries.get(bucketKey);
|
|
436
|
+
if (!e || requestId !== e.latestRequestId) return;
|
|
437
|
+
if (e.snapshot.isLoading === isLoading) return;
|
|
438
|
+
e.snapshot = Object.freeze({
|
|
439
|
+
...e.snapshot,
|
|
440
|
+
isLoading,
|
|
441
|
+
});
|
|
442
|
+
this.notify(e);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Reset a single bucket entry. Bumps `latestRequestId` so any in-flight
|
|
447
|
+
* `load()` whose promise is still pending will fail its gate when it resolves
|
|
448
|
+
* and be dropped — prevents pre-navigation loads from clobbering the new
|
|
449
|
+
* route's context. The entry itself is kept (sticky-bucket semantics).
|
|
450
|
+
*/
|
|
451
|
+
clear(bucketKey: string): void {
|
|
452
|
+
const e = this.entries.get(bucketKey);
|
|
453
|
+
if (!e) return;
|
|
454
|
+
e.latestRequestId++;
|
|
455
|
+
if (e.snapshot === EMPTY_SNAPSHOT) return;
|
|
456
|
+
e.snapshot = EMPTY_SNAPSHOT;
|
|
457
|
+
this.notify(e);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Reset every sticky bucket belonging to `loaderId`. Called on navigation /
|
|
462
|
+
* route-context change: all route-registered reads of the loader (keyed or
|
|
463
|
+
* not) drop back to seeding from fresh `loaderData`. Ephemeral buckets are
|
|
464
|
+
* intentionally left alone — they are governed by subscriber refcount, so a
|
|
465
|
+
* persistent keyed reader outside the outlet keeps its value across a
|
|
466
|
+
* navigation rather than blanking out.
|
|
467
|
+
*/
|
|
468
|
+
clearFamily(loaderId: string): void {
|
|
469
|
+
const fam = this.families.get(loaderId);
|
|
470
|
+
if (!fam) return;
|
|
471
|
+
for (const bucketKey of fam) {
|
|
472
|
+
const e = this.entries.get(bucketKey);
|
|
473
|
+
if (!e || !e.sticky) continue;
|
|
474
|
+
this.clear(bucketKey);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
private notify(e: InternalEntry): void {
|
|
479
|
+
for (const cb of e.listeners) cb();
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Test-only escape hatch. Drops every entry. Production code should never
|
|
484
|
+
* call this; the store is process-scoped and lives for the tab's lifetime.
|
|
485
|
+
* @internal
|
|
486
|
+
*/
|
|
487
|
+
reset(): void {
|
|
488
|
+
this.entries.clear();
|
|
489
|
+
this.families.clear();
|
|
490
|
+
this.groups.clear();
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Module-level singleton. Each browser tab gets its own; SSR never mutates it.
|
|
496
|
+
* The hook falls through to `OutletContext.loaderData` during the server render.
|
|
497
|
+
*/
|
|
498
|
+
export const loaderStore: LoaderStore = new LoaderStore();
|
|
499
|
+
|
|
500
|
+
export const EMPTY_LOADER_SNAPSHOT: LoaderEntry = EMPTY_SNAPSHOT;
|
package/src/loader.rsc.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Only used in react-server context via export conditions.
|
|
6
6
|
*
|
|
7
7
|
* For non-fetchable loaders: returns a loader definition with fn included
|
|
8
|
-
* For fetchable loaders: stores fn in registry and returns a serializable loader
|
|
8
|
+
* For fetchable loaders: stores fn in registry and returns a serializable loader
|
|
9
9
|
*
|
|
10
10
|
* The $$id is injected by the Vite exposeInternalIds plugin as a hidden parameter.
|
|
11
11
|
* Users don't need to pass any name - IDs are auto-generated from file path.
|
|
@@ -17,29 +17,33 @@ import type {
|
|
|
17
17
|
LoaderFn,
|
|
18
18
|
} from "./types.js";
|
|
19
19
|
import type { MiddlewareFn } from "./router/middleware.js";
|
|
20
|
-
import { getRequestContext } from "./server/request-context.js";
|
|
21
20
|
import {
|
|
22
21
|
registerFetchableLoader,
|
|
23
22
|
getFetchableLoader,
|
|
24
23
|
} from "./server/fetchable-loader-store.js";
|
|
24
|
+
import { missingInjectedIdError } from "./missing-id-error.js";
|
|
25
|
+
import { isUnderTestRunner } from "./runtime-env.js";
|
|
25
26
|
|
|
26
27
|
export { getFetchableLoader };
|
|
27
28
|
|
|
29
|
+
// Runtime-fallback counter for bare unit tests (no Vite plugin); process-stable.
|
|
30
|
+
let runtimeLoaderIdCounter = 0;
|
|
31
|
+
|
|
28
32
|
// Overload 1: With function only (not fetchable)
|
|
29
33
|
export function createLoader<T>(
|
|
30
|
-
fn: LoaderFn<T, Record<string, string | undefined>, any
|
|
34
|
+
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
31
35
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
32
36
|
|
|
33
37
|
// Overload 2: Fetchable with `true` (no middleware)
|
|
34
38
|
export function createLoader<T>(
|
|
35
39
|
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
36
|
-
fetchable: true
|
|
40
|
+
fetchable: true,
|
|
37
41
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
38
42
|
|
|
39
43
|
// Overload 3: Fetchable with middleware options
|
|
40
44
|
export function createLoader<T>(
|
|
41
45
|
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
42
|
-
options: FetchableLoaderOptions
|
|
46
|
+
options: FetchableLoaderOptions,
|
|
43
47
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
44
48
|
|
|
45
49
|
// Implementation - the $$id parameter is injected by Vite plugin, not user-provided
|
|
@@ -47,17 +51,30 @@ export function createLoader<T>(
|
|
|
47
51
|
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
48
52
|
fetchable?: true | FetchableLoaderOptions,
|
|
49
53
|
// Hidden parameter injected by Vite exposeInternalIds plugin
|
|
50
|
-
__injectedId?: string
|
|
54
|
+
__injectedId?: string,
|
|
51
55
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>> {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
let loaderId = __injectedId || "";
|
|
57
|
+
|
|
58
|
+
// Under test runner, fall back to synthetic id (recovers fn from registry by $$id).
|
|
59
|
+
// Otherwise (dev or prod), missing id means unsupported shape — fail loud.
|
|
60
|
+
if (!loaderId) {
|
|
61
|
+
if (isUnderTestRunner()) {
|
|
62
|
+
loaderId = `__rango_runtime_loader_${runtimeLoaderIdCounter++}`;
|
|
63
|
+
} else if (process.env.NODE_ENV !== "production") {
|
|
64
|
+
throw missingInjectedIdError("Loader", "createLoader");
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error(
|
|
67
|
+
"[rango] Loader is missing $$id — the build plugin did not inject one. " +
|
|
68
|
+
"Export it as `export const X = createLoader(...)`.",
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
55
72
|
|
|
56
|
-
// If not fetchable, store fn in registry
|
|
57
|
-
//
|
|
73
|
+
// If not fetchable, store fn in registry (for SSR ctx.use() resolution)
|
|
74
|
+
// but mark fetchable=false so the _rsc_loader endpoint rejects it.
|
|
58
75
|
if (fetchable === undefined) {
|
|
59
76
|
if (fn && loaderId) {
|
|
60
|
-
registerFetchableLoader(loaderId, fn, []);
|
|
77
|
+
registerFetchableLoader(loaderId, fn, [], false);
|
|
61
78
|
}
|
|
62
79
|
return {
|
|
63
80
|
__brand: "loader",
|
|
@@ -65,100 +82,15 @@ export function createLoader<T>(
|
|
|
65
82
|
};
|
|
66
83
|
}
|
|
67
84
|
|
|
68
|
-
// Fetchable loader - store fn in registry and return a serializable object
|
|
85
|
+
// Fetchable loader - store fn in registry and return a serializable object.
|
|
69
86
|
const middleware: MiddlewareFn[] =
|
|
70
87
|
fetchable === true ? [] : fetchable?.middleware || [];
|
|
71
|
-
|
|
72
|
-
// Register the function in the internal registry by $$id (server-side only)
|
|
73
|
-
// The server action will look it up by $$id when executed
|
|
74
88
|
if (fn && loaderId) {
|
|
75
|
-
registerFetchableLoader(loaderId, fn, middleware);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Create server action for form-based fetching
|
|
79
|
-
// This action is serializable and can be passed to client components
|
|
80
|
-
// The loaderId is captured in closure (it's a primitive string)
|
|
81
|
-
//
|
|
82
|
-
// IMPORTANT: The signature must be (prevState, formData) for useActionState compatibility.
|
|
83
|
-
// When used with useActionState, React passes the previous state as the first argument.
|
|
84
|
-
// The prevState is ignored here since loaders are stateless data fetchers.
|
|
85
|
-
async function loaderAction(
|
|
86
|
-
_prevState: Awaited<T> | null,
|
|
87
|
-
formData: FormData
|
|
88
|
-
): Promise<Awaited<T>> {
|
|
89
|
-
"use server";
|
|
90
|
-
|
|
91
|
-
// Look up the loader from registry by $$id
|
|
92
|
-
const registered = getFetchableLoader(loaderId);
|
|
93
|
-
if (!registered) {
|
|
94
|
-
throw new Error(`Loader "${loaderId}" not found in registry`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Get request context (env, request, url, variables) from the RSC handler
|
|
98
|
-
// This is set by runWithRequestContext in rsc/index.ts when executing actions
|
|
99
|
-
const requestCtx = getRequestContext();
|
|
100
|
-
|
|
101
|
-
// Convert FormData to params object
|
|
102
|
-
const params: Record<string, string> = {};
|
|
103
|
-
formData.forEach((value, key) => {
|
|
104
|
-
if (typeof value === "string") {
|
|
105
|
-
params[key] = value;
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Use real request/url from context, or fall back to synthetic for edge cases
|
|
110
|
-
const actionUrl = requestCtx?.url ?? new URL("http://localhost/");
|
|
111
|
-
const actionRequest = requestCtx?.request ?? new Request(actionUrl, { method: "POST" });
|
|
112
|
-
const env = requestCtx?.env ?? {};
|
|
113
|
-
|
|
114
|
-
// Merge variables from request context (app-level middleware) with loader-specific variables
|
|
115
|
-
// requestCtx.var is the shared variables object from the handler
|
|
116
|
-
const variables: Record<string, any> = { ...requestCtx?.var };
|
|
117
|
-
|
|
118
|
-
// Execute middleware for auth checks, headers, cookies
|
|
119
|
-
// Headers/cookies set on ctx.res will be merged into the final response
|
|
120
|
-
if (registered.middleware.length > 0 && requestCtx?.res) {
|
|
121
|
-
const { executeServerActionMiddleware } = await import(
|
|
122
|
-
"./router/middleware.js"
|
|
123
|
-
);
|
|
124
|
-
await executeServerActionMiddleware(
|
|
125
|
-
registered.middleware,
|
|
126
|
-
actionRequest,
|
|
127
|
-
env,
|
|
128
|
-
params,
|
|
129
|
-
variables,
|
|
130
|
-
requestCtx.res
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Build context using createHandlerContext for consistency with route handlers
|
|
135
|
-
// Variables are now accessed from request context via getRequestContext()
|
|
136
|
-
const { createHandlerContext } = await import("./router/handler-context.js");
|
|
137
|
-
const baseCtx = createHandlerContext(
|
|
138
|
-
params,
|
|
139
|
-
actionRequest,
|
|
140
|
-
actionUrl.searchParams,
|
|
141
|
-
actionUrl.pathname,
|
|
142
|
-
actionUrl,
|
|
143
|
-
env
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
// Extend with server action specific properties
|
|
147
|
-
const ctx: any = {
|
|
148
|
-
...baseCtx,
|
|
149
|
-
method: "POST",
|
|
150
|
-
formData,
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
// Execute and return result
|
|
154
|
-
return registered.fn(ctx);
|
|
89
|
+
registerFetchableLoader(loaderId, fn, middleware, true);
|
|
155
90
|
}
|
|
156
91
|
|
|
157
|
-
// Return a plain object with action for form-based fetching.
|
|
158
|
-
// loaderAction has "use server" so RSC Flight serializes it natively as a server action reference.
|
|
159
92
|
return {
|
|
160
93
|
__brand: "loader",
|
|
161
94
|
$$id: loaderId,
|
|
162
|
-
action: loaderAction,
|
|
163
95
|
};
|
|
164
96
|
}
|