@rangojs/router 0.0.0-experimental.109 → 0.0.0-experimental.110
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/dist/__internal.d.ts +83 -0
- package/dist/__internal.d.ts.map +1 -0
- package/dist/__internal.js +19 -0
- package/dist/__internal.js.map +1 -0
- package/dist/__mocks__/version.d.ts +7 -0
- package/dist/__mocks__/version.d.ts.map +1 -0
- package/dist/__mocks__/version.js +7 -0
- package/dist/__mocks__/version.js.map +1 -0
- package/dist/__tests__/client-href.test.d.ts +2 -0
- package/dist/__tests__/client-href.test.d.ts.map +1 -0
- package/dist/__tests__/client-href.test.js +74 -0
- package/dist/__tests__/client-href.test.js.map +1 -0
- package/dist/__tests__/component-utils.test.d.ts +2 -0
- package/dist/__tests__/component-utils.test.d.ts.map +1 -0
- package/dist/__tests__/component-utils.test.js +51 -0
- package/dist/__tests__/component-utils.test.js.map +1 -0
- package/dist/__tests__/event-controller.test.d.ts +2 -0
- package/dist/__tests__/event-controller.test.d.ts.map +1 -0
- package/dist/__tests__/event-controller.test.js +538 -0
- package/dist/__tests__/event-controller.test.js.map +1 -0
- package/dist/__tests__/helpers/route-tree.d.ts +118 -0
- package/dist/__tests__/helpers/route-tree.d.ts.map +1 -0
- package/dist/__tests__/helpers/route-tree.js +374 -0
- package/dist/__tests__/helpers/route-tree.js.map +1 -0
- package/dist/__tests__/match-result.test.d.ts +2 -0
- package/dist/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/__tests__/match-result.test.js +154 -0
- package/dist/__tests__/match-result.test.js.map +1 -0
- package/dist/__tests__/navigation-store.test.d.ts +2 -0
- package/dist/__tests__/navigation-store.test.d.ts.map +1 -0
- package/dist/__tests__/navigation-store.test.js +440 -0
- package/dist/__tests__/navigation-store.test.js.map +1 -0
- package/dist/__tests__/partial-update.test.d.ts +2 -0
- package/dist/__tests__/partial-update.test.d.ts.map +1 -0
- package/dist/__tests__/partial-update.test.js +1009 -0
- package/dist/__tests__/partial-update.test.js.map +1 -0
- package/dist/__tests__/reverse-types.test.d.ts +8 -0
- package/dist/__tests__/reverse-types.test.d.ts.map +1 -0
- package/dist/__tests__/reverse-types.test.js +656 -0
- package/dist/__tests__/reverse-types.test.js.map +1 -0
- package/dist/__tests__/route-definition.test.d.ts +2 -0
- package/dist/__tests__/route-definition.test.d.ts.map +1 -0
- package/dist/__tests__/route-definition.test.js +55 -0
- package/dist/__tests__/route-definition.test.js.map +1 -0
- package/dist/__tests__/router-helpers.test.d.ts +2 -0
- package/dist/__tests__/router-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/router-helpers.test.js +377 -0
- package/dist/__tests__/router-helpers.test.js.map +1 -0
- package/dist/__tests__/router-integration-2.test.d.ts +2 -0
- package/dist/__tests__/router-integration-2.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration-2.test.js +426 -0
- package/dist/__tests__/router-integration-2.test.js.map +1 -0
- package/dist/__tests__/router-integration.test.d.ts +2 -0
- package/dist/__tests__/router-integration.test.d.ts.map +1 -0
- package/dist/__tests__/router-integration.test.js +1051 -0
- package/dist/__tests__/router-integration.test.js.map +1 -0
- package/dist/__tests__/search-params.test.d.ts +5 -0
- package/dist/__tests__/search-params.test.d.ts.map +1 -0
- package/dist/__tests__/search-params.test.js +306 -0
- package/dist/__tests__/search-params.test.js.map +1 -0
- package/dist/__tests__/segment-system.test.d.ts +2 -0
- package/dist/__tests__/segment-system.test.d.ts.map +1 -0
- package/dist/__tests__/segment-system.test.js +627 -0
- package/dist/__tests__/segment-system.test.js.map +1 -0
- package/dist/__tests__/static-handler-types.test.d.ts +8 -0
- package/dist/__tests__/static-handler-types.test.d.ts.map +1 -0
- package/dist/__tests__/static-handler-types.test.js +63 -0
- package/dist/__tests__/static-handler-types.test.js.map +1 -0
- package/dist/__tests__/urls.test.d.ts +2 -0
- package/dist/__tests__/urls.test.d.ts.map +1 -0
- package/dist/__tests__/urls.test.js +421 -0
- package/dist/__tests__/urls.test.js.map +1 -0
- package/dist/__tests__/use-mount.test.d.ts +2 -0
- package/dist/__tests__/use-mount.test.d.ts.map +1 -0
- package/dist/__tests__/use-mount.test.js +35 -0
- package/dist/__tests__/use-mount.test.js.map +1 -0
- package/dist/bin/rango.d.ts +2 -0
- package/dist/bin/rango.d.ts.map +1 -0
- package/dist/bin/rango.js.map +1 -0
- package/dist/browser/event-controller.d.ts +191 -0
- package/dist/browser/event-controller.d.ts.map +1 -0
- package/dist/browser/event-controller.js +559 -0
- package/dist/browser/event-controller.js.map +1 -0
- package/dist/browser/index.d.ts +2 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +14 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/link-interceptor.d.ts +38 -0
- package/dist/browser/link-interceptor.d.ts.map +1 -0
- package/dist/browser/link-interceptor.js +99 -0
- package/dist/browser/link-interceptor.js.map +1 -0
- package/dist/browser/logging.d.ts +10 -0
- package/dist/browser/logging.d.ts.map +1 -0
- package/dist/browser/logging.js +29 -0
- package/dist/browser/logging.js.map +1 -0
- package/dist/browser/lru-cache.d.ts +17 -0
- package/dist/browser/lru-cache.d.ts.map +1 -0
- package/dist/browser/lru-cache.js +50 -0
- package/dist/browser/lru-cache.js.map +1 -0
- package/dist/browser/merge-segment-loaders.d.ts +39 -0
- package/dist/browser/merge-segment-loaders.d.ts.map +1 -0
- package/dist/browser/merge-segment-loaders.js +102 -0
- package/dist/browser/merge-segment-loaders.js.map +1 -0
- package/dist/browser/navigation-bridge.d.ts +102 -0
- package/dist/browser/navigation-bridge.d.ts.map +1 -0
- package/dist/browser/navigation-bridge.js +708 -0
- package/dist/browser/navigation-bridge.js.map +1 -0
- package/dist/browser/navigation-client.d.ts +25 -0
- package/dist/browser/navigation-client.d.ts.map +1 -0
- package/dist/browser/navigation-client.js +157 -0
- package/dist/browser/navigation-client.js.map +1 -0
- package/dist/browser/navigation-store.d.ts +101 -0
- package/dist/browser/navigation-store.d.ts.map +1 -0
- package/dist/browser/navigation-store.js +625 -0
- package/dist/browser/navigation-store.js.map +1 -0
- package/dist/browser/partial-update.d.ts +75 -0
- package/dist/browser/partial-update.d.ts.map +1 -0
- package/dist/browser/partial-update.js +426 -0
- package/dist/browser/partial-update.js.map +1 -0
- package/dist/browser/react/Link.d.ts +86 -0
- package/dist/browser/react/Link.d.ts.map +1 -0
- package/dist/browser/react/Link.js +128 -0
- package/dist/browser/react/Link.js.map +1 -0
- package/dist/browser/react/NavigationProvider.d.ts +63 -0
- package/dist/browser/react/NavigationProvider.d.ts.map +1 -0
- package/dist/browser/react/NavigationProvider.js +216 -0
- package/dist/browser/react/NavigationProvider.js.map +1 -0
- package/dist/browser/react/ScrollRestoration.d.ts +75 -0
- package/dist/browser/react/ScrollRestoration.d.ts.map +1 -0
- package/dist/browser/react/ScrollRestoration.js +57 -0
- package/dist/browser/react/ScrollRestoration.js.map +1 -0
- package/dist/browser/react/context.d.ts +46 -0
- package/dist/browser/react/context.d.ts.map +1 -0
- package/dist/browser/react/context.js +10 -0
- package/dist/browser/react/context.js.map +1 -0
- package/dist/browser/react/index.d.ts +11 -0
- package/dist/browser/react/index.d.ts.map +1 -0
- package/dist/browser/react/index.js +22 -0
- package/dist/browser/react/index.js.map +1 -0
- package/dist/browser/react/location-state-shared.d.ts +63 -0
- package/dist/browser/react/location-state-shared.d.ts.map +1 -0
- package/dist/browser/react/location-state-shared.js +81 -0
- package/dist/browser/react/location-state-shared.js.map +1 -0
- package/dist/browser/react/location-state.d.ts +23 -0
- package/dist/browser/react/location-state.d.ts.map +1 -0
- package/dist/browser/react/location-state.js +29 -0
- package/dist/browser/react/location-state.js.map +1 -0
- package/dist/browser/react/mount-context.d.ts +24 -0
- package/dist/browser/react/mount-context.d.ts.map +1 -0
- package/dist/browser/react/mount-context.js +24 -0
- package/dist/browser/react/mount-context.js.map +1 -0
- package/dist/browser/react/use-action.d.ts +64 -0
- package/dist/browser/react/use-action.d.ts.map +1 -0
- package/dist/browser/react/use-action.js +134 -0
- package/dist/browser/react/use-action.js.map +1 -0
- package/dist/browser/react/use-client-cache.d.ts +41 -0
- package/dist/browser/react/use-client-cache.d.ts.map +1 -0
- package/dist/browser/react/use-client-cache.js +39 -0
- package/dist/browser/react/use-client-cache.js.map +1 -0
- package/dist/browser/react/use-handle.d.ts +31 -0
- package/dist/browser/react/use-handle.d.ts.map +1 -0
- package/dist/browser/react/use-handle.js +144 -0
- package/dist/browser/react/use-handle.js.map +1 -0
- package/dist/browser/react/use-href.d.ts +33 -0
- package/dist/browser/react/use-href.d.ts.map +1 -0
- package/dist/browser/react/use-href.js +39 -0
- package/dist/browser/react/use-href.js.map +1 -0
- package/dist/browser/react/use-link-status.d.ts +37 -0
- package/dist/browser/react/use-link-status.d.ts.map +1 -0
- package/dist/browser/react/use-link-status.js +99 -0
- package/dist/browser/react/use-link-status.js.map +1 -0
- package/dist/browser/react/use-mount.d.ts +25 -0
- package/dist/browser/react/use-mount.d.ts.map +1 -0
- package/dist/browser/react/use-mount.js +30 -0
- package/dist/browser/react/use-mount.js.map +1 -0
- package/dist/browser/react/use-navigation.d.ts +27 -0
- package/dist/browser/react/use-navigation.d.ts.map +1 -0
- package/dist/browser/react/use-navigation.js +87 -0
- package/dist/browser/react/use-navigation.js.map +1 -0
- package/dist/browser/react/use-segments.d.ts +38 -0
- package/dist/browser/react/use-segments.d.ts.map +1 -0
- package/dist/browser/react/use-segments.js +130 -0
- package/dist/browser/react/use-segments.js.map +1 -0
- package/dist/browser/request-controller.d.ts +26 -0
- package/dist/browser/request-controller.d.ts.map +1 -0
- package/dist/browser/request-controller.js +147 -0
- package/dist/browser/request-controller.js.map +1 -0
- package/dist/browser/rsc-router.d.ts +129 -0
- package/dist/browser/rsc-router.d.ts.map +1 -0
- package/dist/browser/rsc-router.js +195 -0
- package/dist/browser/rsc-router.js.map +1 -0
- package/dist/browser/scroll-restoration.d.ts +93 -0
- package/dist/browser/scroll-restoration.d.ts.map +1 -0
- package/dist/browser/scroll-restoration.js +321 -0
- package/dist/browser/scroll-restoration.js.map +1 -0
- package/dist/browser/segment-structure-assert.d.ts +17 -0
- package/dist/browser/segment-structure-assert.d.ts.map +1 -0
- package/dist/browser/segment-structure-assert.js +59 -0
- package/dist/browser/segment-structure-assert.js.map +1 -0
- package/dist/browser/server-action-bridge.d.ts +26 -0
- package/dist/browser/server-action-bridge.d.ts.map +1 -0
- package/dist/browser/server-action-bridge.js +668 -0
- package/dist/browser/server-action-bridge.js.map +1 -0
- package/dist/browser/shallow.d.ts +12 -0
- package/dist/browser/shallow.d.ts.map +1 -0
- package/dist/browser/shallow.js +34 -0
- package/dist/browser/shallow.js.map +1 -0
- package/dist/browser/types.d.ts +369 -0
- package/dist/browser/types.d.ts.map +1 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/build/__tests__/generate-cli.test.d.ts +2 -0
- package/dist/build/__tests__/generate-cli.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-cli.test.js +237 -0
- package/dist/build/__tests__/generate-cli.test.js.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/generate-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-manifest.test.js +119 -0
- package/dist/build/__tests__/generate-manifest.test.js.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts +2 -0
- package/dist/build/__tests__/generate-route-types.test.d.ts.map +1 -0
- package/dist/build/__tests__/generate-route-types.test.js +620 -0
- package/dist/build/__tests__/generate-route-types.test.js.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts +2 -0
- package/dist/build/__tests__/per-router-manifest.test.d.ts.map +1 -0
- package/dist/build/__tests__/per-router-manifest.test.js +308 -0
- package/dist/build/__tests__/per-router-manifest.test.js.map +1 -0
- package/dist/build/generate-manifest.d.ts +81 -0
- package/dist/build/generate-manifest.d.ts.map +1 -0
- package/dist/build/generate-manifest.js +276 -0
- package/dist/build/generate-manifest.js.map +1 -0
- package/dist/build/generate-route-types.d.ts +115 -0
- package/dist/build/generate-route-types.d.ts.map +1 -0
- package/dist/build/generate-route-types.js +740 -0
- package/dist/build/generate-route-types.js.map +1 -0
- package/dist/build/index.d.ts +21 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +21 -0
- package/dist/build/index.js.map +1 -0
- package/dist/build/route-trie.d.ts +71 -0
- package/dist/build/route-trie.d.ts.map +1 -0
- package/dist/build/route-trie.js +175 -0
- package/dist/build/route-trie.js.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts +2 -0
- package/dist/cache/__tests__/cache-scope.test.d.ts.map +1 -0
- package/dist/cache/__tests__/cache-scope.test.js +208 -0
- package/dist/cache/__tests__/cache-scope.test.js.map +1 -0
- package/dist/cache/__tests__/document-cache.test.d.ts +2 -0
- package/dist/cache/__tests__/document-cache.test.d.ts.map +1 -0
- package/dist/cache/__tests__/document-cache.test.js +345 -0
- package/dist/cache/__tests__/document-cache.test.js.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-segment-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-segment-store.test.js +425 -0
- package/dist/cache/__tests__/memory-segment-store.test.js.map +1 -0
- package/dist/cache/__tests__/memory-store.test.d.ts +2 -0
- package/dist/cache/__tests__/memory-store.test.d.ts.map +1 -0
- package/dist/cache/__tests__/memory-store.test.js +367 -0
- package/dist/cache/__tests__/memory-store.test.js.map +1 -0
- package/dist/cache/cache-scope.d.ts +102 -0
- package/dist/cache/cache-scope.d.ts.map +1 -0
- package/dist/cache/cache-scope.js +440 -0
- package/dist/cache/cache-scope.js.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts +2 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.d.ts.map +1 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js +330 -0
- package/dist/cache/cf/__tests__/cf-cache-store.test.js.map +1 -0
- package/dist/cache/cf/cf-cache-store.d.ts +165 -0
- package/dist/cache/cf/cf-cache-store.d.ts.map +1 -0
- package/dist/cache/cf/cf-cache-store.js +242 -0
- package/dist/cache/cf/cf-cache-store.js.map +1 -0
- package/dist/cache/cf/index.d.ts +14 -0
- package/dist/cache/cf/index.d.ts.map +1 -0
- package/dist/cache/cf/index.js +17 -0
- package/dist/cache/cf/index.js.map +1 -0
- package/dist/cache/document-cache.d.ts +64 -0
- package/dist/cache/document-cache.d.ts.map +1 -0
- package/dist/cache/document-cache.js +228 -0
- package/dist/cache/document-cache.js.map +1 -0
- package/dist/cache/index.d.ts +19 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +21 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/memory-segment-store.d.ts +110 -0
- package/dist/cache/memory-segment-store.d.ts.map +1 -0
- package/dist/cache/memory-segment-store.js +117 -0
- package/dist/cache/memory-segment-store.js.map +1 -0
- package/dist/cache/memory-store.d.ts +41 -0
- package/dist/cache/memory-store.d.ts.map +1 -0
- package/dist/cache/memory-store.js +191 -0
- package/dist/cache/memory-store.js.map +1 -0
- package/dist/cache/types.d.ts +317 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +12 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/client.d.ts +248 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +367 -0
- package/dist/client.js.map +1 -0
- package/dist/client.rsc.d.ts +26 -0
- package/dist/client.rsc.d.ts.map +1 -0
- package/dist/client.rsc.js +46 -0
- package/dist/client.rsc.js.map +1 -0
- package/dist/component-utils.d.ts +36 -0
- package/dist/component-utils.d.ts.map +1 -0
- package/dist/component-utils.js +61 -0
- package/dist/component-utils.js.map +1 -0
- package/dist/components/DefaultDocument.d.ts +13 -0
- package/dist/components/DefaultDocument.d.ts.map +1 -0
- package/dist/components/DefaultDocument.js +15 -0
- package/dist/components/DefaultDocument.js.map +1 -0
- package/dist/debug.d.ts +58 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +157 -0
- package/dist/debug.js.map +1 -0
- package/dist/default-error-boundary.d.ts +11 -0
- package/dist/default-error-boundary.d.ts.map +1 -0
- package/dist/default-error-boundary.js +45 -0
- package/dist/default-error-boundary.js.map +1 -0
- package/dist/deps/browser.d.ts +2 -0
- package/dist/deps/browser.d.ts.map +1 -0
- package/dist/deps/browser.js +3 -0
- package/dist/deps/browser.js.map +1 -0
- package/dist/deps/html-stream-client.d.ts +2 -0
- package/dist/deps/html-stream-client.d.ts.map +1 -0
- package/dist/deps/html-stream-client.js +3 -0
- package/dist/deps/html-stream-client.js.map +1 -0
- package/dist/deps/html-stream-server.d.ts +2 -0
- package/dist/deps/html-stream-server.d.ts.map +1 -0
- package/dist/deps/html-stream-server.js +3 -0
- package/dist/deps/html-stream-server.js.map +1 -0
- package/dist/deps/rsc.d.ts +2 -0
- package/dist/deps/rsc.d.ts.map +1 -0
- package/dist/deps/rsc.js +4 -0
- package/dist/deps/rsc.js.map +1 -0
- package/dist/deps/ssr.d.ts +2 -0
- package/dist/deps/ssr.d.ts.map +1 -0
- package/dist/deps/ssr.js +3 -0
- package/dist/deps/ssr.js.map +1 -0
- package/dist/errors.d.ts +174 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +241 -0
- package/dist/errors.js.map +1 -0
- package/dist/handle.d.ts +78 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +82 -0
- package/dist/handle.js.map +1 -0
- package/dist/handles/MetaTags.d.ts +14 -0
- package/dist/handles/MetaTags.d.ts.map +1 -0
- package/dist/handles/MetaTags.js +136 -0
- package/dist/handles/MetaTags.js.map +1 -0
- package/dist/handles/index.d.ts +6 -0
- package/dist/handles/index.d.ts.map +1 -0
- package/dist/handles/index.js +6 -0
- package/dist/handles/index.js.map +1 -0
- package/dist/handles/meta.d.ts +39 -0
- package/dist/handles/meta.d.ts.map +1 -0
- package/dist/handles/meta.js +202 -0
- package/dist/handles/meta.js.map +1 -0
- package/dist/host/__tests__/errors.test.d.ts +2 -0
- package/dist/host/__tests__/errors.test.d.ts.map +1 -0
- package/dist/host/__tests__/errors.test.js +76 -0
- package/dist/host/__tests__/errors.test.js.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-comprehensive.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js +732 -0
- package/dist/host/__tests__/pattern-comprehensive.test.js.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts +2 -0
- package/dist/host/__tests__/pattern-matcher.test.d.ts.map +1 -0
- package/dist/host/__tests__/pattern-matcher.test.js +251 -0
- package/dist/host/__tests__/pattern-matcher.test.js.map +1 -0
- package/dist/host/__tests__/router.test.d.ts +2 -0
- package/dist/host/__tests__/router.test.d.ts.map +1 -0
- package/dist/host/__tests__/router.test.js +241 -0
- package/dist/host/__tests__/router.test.js.map +1 -0
- package/dist/host/__tests__/testing.test.d.ts +2 -0
- package/dist/host/__tests__/testing.test.d.ts.map +1 -0
- package/dist/host/__tests__/testing.test.js +64 -0
- package/dist/host/__tests__/testing.test.js.map +1 -0
- package/dist/host/__tests__/utils.test.d.ts +2 -0
- package/dist/host/__tests__/utils.test.d.ts.map +1 -0
- package/dist/host/__tests__/utils.test.js +29 -0
- package/dist/host/__tests__/utils.test.js.map +1 -0
- package/dist/host/cookie-handler.d.ts +34 -0
- package/dist/host/cookie-handler.d.ts.map +1 -0
- package/dist/host/cookie-handler.js +124 -0
- package/dist/host/cookie-handler.js.map +1 -0
- package/dist/host/errors.d.ts +56 -0
- package/dist/host/errors.d.ts.map +1 -0
- package/dist/host/errors.js +79 -0
- package/dist/host/errors.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +32 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pattern-matcher.d.ts +36 -0
- package/dist/host/pattern-matcher.d.ts.map +1 -0
- package/dist/host/pattern-matcher.js +172 -0
- package/dist/host/pattern-matcher.js.map +1 -0
- package/dist/host/router.d.ts +26 -0
- package/dist/host/router.d.ts.map +1 -0
- package/dist/host/router.js +218 -0
- package/dist/host/router.js.map +1 -0
- package/dist/host/testing.d.ts +36 -0
- package/dist/host/testing.d.ts.map +1 -0
- package/dist/host/testing.js +55 -0
- package/dist/host/testing.js.map +1 -0
- package/dist/host/types.d.ts +115 -0
- package/dist/host/types.d.ts.map +1 -0
- package/dist/host/types.js +7 -0
- package/dist/host/types.js.map +1 -0
- package/dist/host/utils.d.ts +21 -0
- package/dist/host/utils.d.ts.map +1 -0
- package/dist/host/utils.js +23 -0
- package/dist/host/utils.js.map +1 -0
- package/dist/href-client.d.ts +131 -0
- package/dist/href-client.d.ts.map +1 -0
- package/dist/href-client.js +64 -0
- package/dist/href-client.js.map +1 -0
- package/dist/href-context.d.ts +29 -0
- package/dist/href-context.d.ts.map +1 -0
- package/dist/href-context.js +21 -0
- package/dist/href-context.js.map +1 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/index.rsc.d.ts +32 -0
- package/dist/index.rsc.d.ts.map +1 -0
- package/dist/index.rsc.js +40 -0
- package/dist/index.rsc.js.map +1 -0
- package/dist/internal-debug.d.ts +2 -0
- package/dist/internal-debug.d.ts.map +1 -0
- package/dist/internal-debug.js +5 -0
- package/dist/internal-debug.js.map +1 -0
- package/dist/loader.d.ts +14 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +20 -0
- package/dist/loader.js.map +1 -0
- package/dist/loader.rsc.d.ts +19 -0
- package/dist/loader.rsc.d.ts.map +1 -0
- package/dist/loader.rsc.js +99 -0
- package/dist/loader.rsc.js.map +1 -0
- package/dist/network-error-thrower.d.ts +17 -0
- package/dist/network-error-thrower.d.ts.map +1 -0
- package/dist/network-error-thrower.js +14 -0
- package/dist/network-error-thrower.js.map +1 -0
- package/dist/outlet-context.d.ts +13 -0
- package/dist/outlet-context.d.ts.map +1 -0
- package/dist/outlet-context.js +3 -0
- package/dist/outlet-context.js.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts +2 -0
- package/dist/prerender/__tests__/param-hash.test.d.ts.map +1 -0
- package/dist/prerender/__tests__/param-hash.test.js +148 -0
- package/dist/prerender/__tests__/param-hash.test.js.map +1 -0
- package/dist/prerender/param-hash.d.ts +16 -0
- package/dist/prerender/param-hash.d.ts.map +1 -0
- package/dist/prerender/param-hash.js +36 -0
- package/dist/prerender/param-hash.js.map +1 -0
- package/dist/prerender/store.d.ts +38 -0
- package/dist/prerender/store.d.ts.map +1 -0
- package/dist/prerender/store.js +61 -0
- package/dist/prerender/store.js.map +1 -0
- package/dist/prerender.d.ts +66 -0
- package/dist/prerender.d.ts.map +1 -0
- package/dist/prerender.js +57 -0
- package/dist/prerender.js.map +1 -0
- package/dist/reverse.d.ts +196 -0
- package/dist/reverse.d.ts.map +1 -0
- package/dist/reverse.js +78 -0
- package/dist/reverse.js.map +1 -0
- package/dist/root-error-boundary.d.ts +33 -0
- package/dist/root-error-boundary.d.ts.map +1 -0
- package/dist/root-error-boundary.js +165 -0
- package/dist/root-error-boundary.js.map +1 -0
- package/dist/route-content-wrapper.d.ts +46 -0
- package/dist/route-content-wrapper.d.ts.map +1 -0
- package/dist/route-content-wrapper.js +77 -0
- package/dist/route-content-wrapper.js.map +1 -0
- package/dist/route-definition.d.ts +421 -0
- package/dist/route-definition.d.ts.map +1 -0
- package/dist/route-definition.js +868 -0
- package/dist/route-definition.js.map +1 -0
- package/dist/route-map-builder.d.ts +155 -0
- package/dist/route-map-builder.d.ts.map +1 -0
- package/dist/route-map-builder.js +237 -0
- package/dist/route-map-builder.js.map +1 -0
- package/dist/route-types.d.ts +165 -0
- package/dist/route-types.d.ts.map +1 -0
- package/dist/route-types.js +7 -0
- package/dist/route-types.js.map +1 -0
- package/dist/router/__tests__/handler-context.test.d.ts +2 -0
- package/dist/router/__tests__/handler-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/handler-context.test.js +65 -0
- package/dist/router/__tests__/handler-context.test.js.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts +2 -0
- package/dist/router/__tests__/loader-cycle-detection.test.d.ts.map +1 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js +221 -0
- package/dist/router/__tests__/loader-cycle-detection.test.js.map +1 -0
- package/dist/router/__tests__/match-context.test.d.ts +2 -0
- package/dist/router/__tests__/match-context.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-context.test.js +92 -0
- package/dist/router/__tests__/match-context.test.js.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts +2 -0
- package/dist/router/__tests__/match-pipelines.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-pipelines.test.js +417 -0
- package/dist/router/__tests__/match-pipelines.test.js.map +1 -0
- package/dist/router/__tests__/match-result.test.d.ts +2 -0
- package/dist/router/__tests__/match-result.test.d.ts.map +1 -0
- package/dist/router/__tests__/match-result.test.js +457 -0
- package/dist/router/__tests__/match-result.test.js.map +1 -0
- package/dist/router/__tests__/on-error.test.d.ts +2 -0
- package/dist/router/__tests__/on-error.test.d.ts.map +1 -0
- package/dist/router/__tests__/on-error.test.js +678 -0
- package/dist/router/__tests__/on-error.test.js.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts +2 -0
- package/dist/router/__tests__/pattern-matching.test.d.ts.map +1 -0
- package/dist/router/__tests__/pattern-matching.test.js +629 -0
- package/dist/router/__tests__/pattern-matching.test.js.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts +2 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.d.ts.map +1 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js +155 -0
- package/dist/router/__tests__/segment-resolution-parallel-loading.test.js.map +1 -0
- package/dist/router/error-handling.d.ts +77 -0
- package/dist/router/error-handling.d.ts.map +1 -0
- package/dist/router/error-handling.js +202 -0
- package/dist/router/error-handling.js.map +1 -0
- package/dist/router/handler-context.d.ts +20 -0
- package/dist/router/handler-context.d.ts.map +1 -0
- package/dist/router/handler-context.js +198 -0
- package/dist/router/handler-context.js.map +1 -0
- package/dist/router/intercept-resolution.d.ts +66 -0
- package/dist/router/intercept-resolution.d.ts.map +1 -0
- package/dist/router/intercept-resolution.js +246 -0
- package/dist/router/intercept-resolution.js.map +1 -0
- package/dist/router/loader-resolution.d.ts +64 -0
- package/dist/router/loader-resolution.d.ts.map +1 -0
- package/dist/router/loader-resolution.js +284 -0
- package/dist/router/loader-resolution.js.map +1 -0
- package/dist/router/logging.d.ts +15 -0
- package/dist/router/logging.d.ts.map +1 -0
- package/dist/router/logging.js +99 -0
- package/dist/router/logging.js.map +1 -0
- package/dist/router/manifest.d.ts +22 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +181 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/router/match-api.d.ts +35 -0
- package/dist/router/match-api.d.ts.map +1 -0
- package/dist/router/match-api.js +406 -0
- package/dist/router/match-api.js.map +1 -0
- package/dist/router/match-context.d.ts +206 -0
- package/dist/router/match-context.d.ts.map +1 -0
- package/dist/router/match-context.js +17 -0
- package/dist/router/match-context.js.map +1 -0
- package/dist/router/match-middleware/background-revalidation.d.ts +127 -0
- package/dist/router/match-middleware/background-revalidation.d.ts.map +1 -0
- package/dist/router/match-middleware/background-revalidation.js +75 -0
- package/dist/router/match-middleware/background-revalidation.js.map +1 -0
- package/dist/router/match-middleware/cache-lookup.d.ts +112 -0
- package/dist/router/match-middleware/cache-lookup.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-lookup.js +257 -0
- package/dist/router/match-middleware/cache-lookup.js.map +1 -0
- package/dist/router/match-middleware/cache-store.d.ts +113 -0
- package/dist/router/match-middleware/cache-store.d.ts.map +1 -0
- package/dist/router/match-middleware/cache-store.js +108 -0
- package/dist/router/match-middleware/cache-store.js.map +1 -0
- package/dist/router/match-middleware/index.d.ts +81 -0
- package/dist/router/match-middleware/index.d.ts.map +1 -0
- package/dist/router/match-middleware/index.js +80 -0
- package/dist/router/match-middleware/index.js.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts +117 -0
- package/dist/router/match-middleware/intercept-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/intercept-resolution.js +134 -0
- package/dist/router/match-middleware/intercept-resolution.js.map +1 -0
- package/dist/router/match-middleware/segment-resolution.d.ts +99 -0
- package/dist/router/match-middleware/segment-resolution.d.ts.map +1 -0
- package/dist/router/match-middleware/segment-resolution.js +53 -0
- package/dist/router/match-middleware/segment-resolution.js.map +1 -0
- package/dist/router/match-pipelines.d.ts +147 -0
- package/dist/router/match-pipelines.d.ts.map +1 -0
- package/dist/router/match-pipelines.js +82 -0
- package/dist/router/match-pipelines.js.map +1 -0
- package/dist/router/match-result.d.ts +126 -0
- package/dist/router/match-result.d.ts.map +1 -0
- package/dist/router/match-result.js +93 -0
- package/dist/router/match-result.js.map +1 -0
- package/dist/router/metrics.d.ts +20 -0
- package/dist/router/metrics.d.ts.map +1 -0
- package/dist/router/metrics.js +47 -0
- package/dist/router/metrics.js.map +1 -0
- package/dist/router/middleware.d.ts +249 -0
- package/dist/router/middleware.d.ts.map +1 -0
- package/dist/router/middleware.js +434 -0
- package/dist/router/middleware.js.map +1 -0
- package/dist/router/middleware.test.d.ts +2 -0
- package/dist/router/middleware.test.d.ts.map +1 -0
- package/dist/router/middleware.test.js +816 -0
- package/dist/router/middleware.test.js.map +1 -0
- package/dist/router/pattern-matching.d.ts +149 -0
- package/dist/router/pattern-matching.d.ts.map +1 -0
- package/dist/router/pattern-matching.js +349 -0
- package/dist/router/pattern-matching.js.map +1 -0
- package/dist/router/revalidation.d.ts +44 -0
- package/dist/router/revalidation.d.ts.map +1 -0
- package/dist/router/revalidation.js +147 -0
- package/dist/router/revalidation.js.map +1 -0
- package/dist/router/router-context.d.ts +135 -0
- package/dist/router/router-context.d.ts.map +1 -0
- package/dist/router/router-context.js +36 -0
- package/dist/router/router-context.js.map +1 -0
- package/dist/router/segment-resolution.d.ts +127 -0
- package/dist/router/segment-resolution.d.ts.map +1 -0
- package/dist/router/segment-resolution.js +919 -0
- package/dist/router/segment-resolution.js.map +1 -0
- package/dist/router/trie-matching.d.ts +40 -0
- package/dist/router/trie-matching.d.ts.map +1 -0
- package/dist/router/trie-matching.js +127 -0
- package/dist/router/trie-matching.js.map +1 -0
- package/dist/router/types.d.ts +136 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +7 -0
- package/dist/router/types.js.map +1 -0
- package/dist/router.d.ts +753 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.gen.d.ts +6 -0
- package/dist/router.gen.d.ts.map +1 -0
- package/dist/router.gen.js +6 -0
- package/dist/router.gen.js.map +1 -0
- package/dist/router.js +1304 -0
- package/dist/router.js.map +1 -0
- package/dist/rsc/__tests__/helpers.test.d.ts +2 -0
- package/dist/rsc/__tests__/helpers.test.d.ts.map +1 -0
- package/dist/rsc/__tests__/helpers.test.js +140 -0
- package/dist/rsc/__tests__/helpers.test.js.map +1 -0
- package/dist/rsc/handler.d.ts +45 -0
- package/dist/rsc/handler.d.ts.map +1 -0
- package/dist/rsc/handler.js +1172 -0
- package/dist/rsc/handler.js.map +1 -0
- package/dist/rsc/helpers.d.ts +16 -0
- package/dist/rsc/helpers.d.ts.map +1 -0
- package/dist/rsc/helpers.js +55 -0
- package/dist/rsc/helpers.js.map +1 -0
- package/dist/rsc/index.d.ts +22 -0
- package/dist/rsc/index.d.ts.map +1 -0
- package/dist/rsc/index.js +23 -0
- package/dist/rsc/index.js.map +1 -0
- package/dist/rsc/nonce.d.ts +9 -0
- package/dist/rsc/nonce.d.ts.map +1 -0
- package/dist/rsc/nonce.js +18 -0
- package/dist/rsc/nonce.js.map +1 -0
- package/dist/rsc/types.d.ts +206 -0
- package/dist/rsc/types.d.ts.map +1 -0
- package/dist/rsc/types.js +8 -0
- package/dist/rsc/types.js.map +1 -0
- package/dist/search-params.d.ts +103 -0
- package/dist/search-params.d.ts.map +1 -0
- package/dist/search-params.js +74 -0
- package/dist/search-params.js.map +1 -0
- package/dist/segment-system.d.ts +75 -0
- package/dist/segment-system.d.ts.map +1 -0
- package/dist/segment-system.js +336 -0
- package/dist/segment-system.js.map +1 -0
- package/dist/server/context.d.ts +245 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +197 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/fetchable-loader-store.d.ts +18 -0
- package/dist/server/fetchable-loader-store.d.ts.map +1 -0
- package/dist/server/fetchable-loader-store.js +18 -0
- package/dist/server/fetchable-loader-store.js.map +1 -0
- package/dist/server/handle-store.d.ts +85 -0
- package/dist/server/handle-store.d.ts.map +1 -0
- package/dist/server/handle-store.js +142 -0
- package/dist/server/handle-store.js.map +1 -0
- package/dist/server/loader-registry.d.ts +55 -0
- package/dist/server/loader-registry.d.ts.map +1 -0
- package/dist/server/loader-registry.js +132 -0
- package/dist/server/loader-registry.js.map +1 -0
- package/dist/server/request-context.d.ts +226 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +290 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/root-layout.d.ts +4 -0
- package/dist/server/root-layout.d.ts.map +1 -0
- package/dist/server/root-layout.js +5 -0
- package/dist/server/root-layout.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +20 -0
- package/dist/server.js.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts +2 -0
- package/dist/ssr/__tests__/ssr-handler.test.d.ts.map +1 -0
- package/dist/ssr/__tests__/ssr-handler.test.js +132 -0
- package/dist/ssr/__tests__/ssr-handler.test.js.map +1 -0
- package/dist/ssr/index.d.ts +98 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +158 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/static-handler.d.ts +50 -0
- package/dist/static-handler.d.ts.map +1 -0
- package/dist/static-handler.gen.d.ts +5 -0
- package/dist/static-handler.gen.d.ts.map +1 -0
- package/dist/static-handler.gen.js +5 -0
- package/dist/static-handler.gen.js.map +1 -0
- package/dist/static-handler.js +29 -0
- package/dist/static-handler.js.map +1 -0
- package/dist/theme/ThemeProvider.d.ts +20 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +240 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/ThemeScript.d.ts +48 -0
- package/dist/theme/ThemeScript.d.ts.map +1 -0
- package/dist/theme/ThemeScript.js +13 -0
- package/dist/theme/ThemeScript.js.map +1 -0
- package/dist/theme/__tests__/theme.test.d.ts +2 -0
- package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
- package/dist/theme/__tests__/theme.test.js +103 -0
- package/dist/theme/__tests__/theme.test.js.map +1 -0
- package/dist/theme/constants.d.ts +29 -0
- package/dist/theme/constants.d.ts.map +1 -0
- package/dist/theme/constants.js +48 -0
- package/dist/theme/constants.js.map +1 -0
- package/dist/theme/index.d.ts +31 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +36 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-context.d.ts +40 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +60 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-script.d.ts +27 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +147 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/dist/theme/types.d.ts +163 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +11 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme/use-theme.d.ts +12 -0
- package/dist/theme/use-theme.d.ts.map +1 -0
- package/dist/theme/use-theme.js +40 -0
- package/dist/theme/use-theme.js.map +1 -0
- package/dist/types.d.ts +1479 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/urls.d.ts +441 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.gen.d.ts +8 -0
- package/dist/urls.gen.d.ts.map +1 -0
- package/dist/urls.gen.js +8 -0
- package/dist/urls.gen.js.map +1 -0
- package/dist/urls.js +443 -0
- package/dist/urls.js.map +1 -0
- package/dist/use-loader.d.ts +127 -0
- package/dist/use-loader.d.ts.map +1 -0
- package/dist/use-loader.js +237 -0
- package/dist/use-loader.js.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts +2 -0
- package/dist/vite/__tests__/ast-handler-extract.test.d.ts.map +1 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js +294 -0
- package/dist/vite/__tests__/ast-handler-extract.test.js.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-id-utils.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-id-utils.test.js +224 -0
- package/dist/vite/__tests__/expose-id-utils.test.js.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-internal-ids.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js +647 -0
- package/dist/vite/__tests__/expose-internal-ids.test.js.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts +2 -0
- package/dist/vite/__tests__/expose-router-id.test.d.ts.map +1 -0
- package/dist/vite/__tests__/expose-router-id.test.js +39 -0
- package/dist/vite/__tests__/expose-router-id.test.js.map +1 -0
- package/dist/vite/ast-handler-extract.d.ts +49 -0
- package/dist/vite/ast-handler-extract.d.ts.map +1 -0
- package/dist/vite/ast-handler-extract.js +249 -0
- package/dist/vite/ast-handler-extract.js.map +1 -0
- package/dist/vite/expose-action-id.d.ts +19 -0
- package/dist/vite/expose-action-id.d.ts.map +1 -0
- package/dist/vite/expose-action-id.js +250 -0
- package/dist/vite/expose-action-id.js.map +1 -0
- package/dist/vite/expose-id-utils.d.ts +69 -0
- package/dist/vite/expose-id-utils.d.ts.map +1 -0
- package/dist/vite/expose-id-utils.js +289 -0
- package/dist/vite/expose-id-utils.js.map +1 -0
- package/dist/vite/expose-internal-ids.d.ts +22 -0
- package/dist/vite/expose-internal-ids.d.ts.map +1 -0
- package/dist/vite/expose-internal-ids.js +886 -0
- package/dist/vite/expose-internal-ids.js.map +1 -0
- package/dist/vite/index.d.ts +149 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +1 -1
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/index.named-routes.gen.ts +103 -0
- package/dist/vite/package-resolution.d.ts +43 -0
- package/dist/vite/package-resolution.d.ts.map +1 -0
- package/dist/vite/package-resolution.js +112 -0
- package/dist/vite/package-resolution.js.map +1 -0
- package/dist/vite/virtual-entries.d.ts +25 -0
- package/dist/vite/virtual-entries.d.ts.map +1 -0
- package/dist/vite/virtual-entries.js +110 -0
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +14 -15
- package/skills/hooks/SKILL.md +95 -18
- package/skills/loader/SKILL.md +14 -0
- package/src/client.tsx +1 -0
- package/src/loader-store.ts +293 -32
- package/src/use-loader.tsx +211 -33
package/skills/hooks/SKILL.md
CHANGED
|
@@ -231,6 +231,82 @@ So the search/list pattern still works — two components calling
|
|
|
231
231
|
own result; they do not collapse to last-write-wins through a shared
|
|
232
232
|
store.
|
|
233
233
|
|
|
234
|
+
**Scoping refetch with a `key`**:
|
|
235
|
+
|
|
236
|
+
Pass a `key` to partition the shared refresh store. Only hooks using the
|
|
237
|
+
**same** `key` refresh together when one of them calls `load()`. This is a
|
|
238
|
+
client-side refresh identity only — it never changes the request sent to the
|
|
239
|
+
server, and is unrelated to the server `cache({ key })` option and to
|
|
240
|
+
`revalidate()`.
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
// Two independent dashboards using the same loader. Without a key, one
|
|
244
|
+
// dashboard's load() would flip the other's spinner and value. With a key,
|
|
245
|
+
// they refresh independently.
|
|
246
|
+
function Dashboard({ id }: { id: string }) {
|
|
247
|
+
const { data, load } = useLoader(StatsLoader, { key: `dashboard:${id}` });
|
|
248
|
+
return <button onClick={() => load()}>Refresh {data.total}</button>;
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The `key` widens sharing in two ways the default cannot:
|
|
253
|
+
|
|
254
|
+
- **Parameterized GETs share.** `useFetchLoader(SearchLoader, { key: q })`
|
|
255
|
+
with the same `q` in two components share one result and refresh together —
|
|
256
|
+
a keyed `load({ params: { q } })` broadcasts to the group instead of staying
|
|
257
|
+
local. (Mutations — non-GET or `body` — stay local even with a key.)
|
|
258
|
+
- **Unregistered loaders share.** A `key` makes `useFetchLoader` of a loader
|
|
259
|
+
that is **not** registered on the route share too, letting unrelated
|
|
260
|
+
components opt into a common refresh group.
|
|
261
|
+
|
|
262
|
+
Lifecycle: a keyed read of an unregistered loader is reference-counted — its
|
|
263
|
+
shared value lives as long as at least one component using that key is mounted.
|
|
264
|
+
A persistent component (e.g. a header) keeps the value across navigations; a
|
|
265
|
+
route-scoped component's value is reclaimed when it unmounts. Registered-loader
|
|
266
|
+
reads (keyed or not) reset on navigation from fresh route data, as before.
|
|
267
|
+
|
|
268
|
+
**Refreshing multiple loaders together (`refreshGroup` + `useRefreshLoaders`)**:
|
|
269
|
+
|
|
270
|
+
`key` groups readers of one loader. To refresh **different** loaders together,
|
|
271
|
+
tag them with the same `refreshGroup` and trigger them with `useRefreshLoaders`:
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
function Profile() {
|
|
275
|
+
const { data } = useLoader(ProfileLoader, {
|
|
276
|
+
key: userId,
|
|
277
|
+
refreshGroup: "account",
|
|
278
|
+
});
|
|
279
|
+
return <span>{data.name}</span>;
|
|
280
|
+
}
|
|
281
|
+
function Orders() {
|
|
282
|
+
const { data } = useLoader(OrdersLoader, {
|
|
283
|
+
key: userId,
|
|
284
|
+
refreshGroup: "account",
|
|
285
|
+
});
|
|
286
|
+
return <span>{data.count} orders</span>;
|
|
287
|
+
}
|
|
288
|
+
function RefreshButton() {
|
|
289
|
+
const refreshAccount = useRefreshLoaders("account");
|
|
290
|
+
return <button onClick={() => refreshAccount()}>Refresh</button>;
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`refreshAccount()` re-runs every currently-mounted member with a **plain GET**
|
|
295
|
+
against the current route URL — no params, no body, no mutation methods, because
|
|
296
|
+
a group spans loaders with different shapes. It returns a promise that resolves
|
|
297
|
+
when all members settle and **rejects with an `AggregateError`** if any fail;
|
|
298
|
+
group refresh never render-throws, so handle failures at the await site
|
|
299
|
+
(`await refreshAccount().catch(...)`). Each failing member also exposes its error
|
|
300
|
+
via its own read's `error`.
|
|
301
|
+
|
|
302
|
+
Sharing within a group is opt-in via `key`: members that share a `key` share one
|
|
303
|
+
value (and one fetch); a grouped reader **without** a `key` gets its own private
|
|
304
|
+
bucket, so a group refresh updates only that read and never leaks into unrelated
|
|
305
|
+
unkeyed reads of the same loader. A bucket may belong to several groups at once
|
|
306
|
+
(different reads can tag the same keyed bucket with different group names).
|
|
307
|
+
Keep parameterized loaders on the single-loader `key` — a plain-GET group refresh
|
|
308
|
+
sends no params.
|
|
309
|
+
|
|
234
310
|
**Load options**:
|
|
235
311
|
|
|
236
312
|
```tsx
|
|
@@ -798,21 +874,22 @@ See `/links` for the full URL generation guide. `ctx.reverse()` is server-only;
|
|
|
798
874
|
|
|
799
875
|
## Hook Summary
|
|
800
876
|
|
|
801
|
-
| Hook
|
|
802
|
-
|
|
|
803
|
-
| `useParams()`
|
|
804
|
-
| `usePathname()`
|
|
805
|
-
| `useSearchParams()`
|
|
806
|
-
| `useHref()`
|
|
807
|
-
| `useMount()`
|
|
808
|
-
| `useReverse()`
|
|
809
|
-
| `useNavigation()`
|
|
810
|
-
| `useRouter()`
|
|
811
|
-
| `useSegments()`
|
|
812
|
-
| `useLinkStatus()`
|
|
813
|
-
| `useLoader()`
|
|
814
|
-
| `useFetchLoader()`
|
|
815
|
-
| `
|
|
816
|
-
| `
|
|
817
|
-
| `
|
|
818
|
-
| `
|
|
877
|
+
| Hook | Purpose | Returns |
|
|
878
|
+
| --------------------- | --------------------------------- | ------------------------------------------------------------------ |
|
|
879
|
+
| `useParams()` | Route params | `Readonly<T>` (default `Record<string, string>`) or selected value |
|
|
880
|
+
| `usePathname()` | Current pathname | `string` |
|
|
881
|
+
| `useSearchParams()` | URL search params | `ReadonlyURLSearchParams` |
|
|
882
|
+
| `useHref()` | Mount-aware href | `(path) => string` |
|
|
883
|
+
| `useMount()` | Current include() mount path | `string` |
|
|
884
|
+
| `useReverse()` | Local reverse for imported routes | `(name, params?, search?) => string` |
|
|
885
|
+
| `useNavigation()` | Reactive navigation state | state, location, isStreaming |
|
|
886
|
+
| `useRouter()` | Stable router actions | push, replace, refresh, prefetch, back, forward |
|
|
887
|
+
| `useSegments()` | URL path & segment IDs | path, segmentIds, location |
|
|
888
|
+
| `useLinkStatus()` | Link pending state | { pending } |
|
|
889
|
+
| `useLoader()` | Loader data (strict) | data, isLoading, error |
|
|
890
|
+
| `useFetchLoader()` | Loader with on-demand fetch | data, load, isLoading |
|
|
891
|
+
| `useRefreshLoaders()` | Refresh a cross-loader group | `(group) => () => Promise<void>` |
|
|
892
|
+
| `useHandle()` | Accumulated handle data | T (handle type) |
|
|
893
|
+
| `useAction()` | Server action state | state, error, result |
|
|
894
|
+
| `useLocationState()` | History state (persists or flash) | T \| undefined |
|
|
895
|
+
| `useClientCache()` | Cache control | { clear } |
|
package/skills/loader/SKILL.md
CHANGED
|
@@ -91,6 +91,20 @@ path("/product/:slug", ProductPage, { name: "product" }, () => [
|
|
|
91
91
|
]);
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
> **Client refresh `key` vs. server `cache({ key })` vs. `revalidate()`.** Three
|
|
95
|
+
> different "what refreshes" knobs that are easy to confuse:
|
|
96
|
+
>
|
|
97
|
+
> - `useLoader(Loader, { key })` / `useFetchLoader(Loader, { key })` — a
|
|
98
|
+
> **client** refresh identity. It groups which mounted reads of one loader
|
|
99
|
+
> refresh together when one calls `load()`. It never touches the server
|
|
100
|
+
> request. For refreshing **different** loaders together, tag them with
|
|
101
|
+
> `{ refreshGroup }` and call `useRefreshLoaders(name)()` (plain GET only).
|
|
102
|
+
> See the hooks skill ("Scoping refetch with a `key`" and "Refreshing multiple
|
|
103
|
+
> loaders together").
|
|
104
|
+
> - `cache({ key })` — a **server** cache identity (storage hit/miss/ttl/swr).
|
|
105
|
+
> - `revalidate()` — which **server** segments/loaders recompute during
|
|
106
|
+
> navigation and action refreshes.
|
|
107
|
+
|
|
94
108
|
DSL loaders are the **live data layer** — they resolve fresh on every
|
|
95
109
|
request, even when the route is inside a `cache()` boundary. The router
|
|
96
110
|
excludes them from the segment cache at storage time and re-resolves them
|
package/src/client.tsx
CHANGED
package/src/loader-store.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LoaderStore — shared subscription model for `useLoader` / `useFetchLoader`.
|
|
3
3
|
*
|
|
4
|
-
* Each
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
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`.
|
|
8
13
|
*
|
|
9
14
|
* Mutations that come in for an old request id (e.g. a slow response that
|
|
10
15
|
* resolves after a newer load() was issued, or after a navigation cleared the
|
|
@@ -12,6 +17,18 @@
|
|
|
12
17
|
* "latest" slot; `clear` bumps it too so pre-navigation in-flight loads cannot
|
|
13
18
|
* commit into the new route's context.
|
|
14
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
|
+
*
|
|
15
32
|
* The store is intentionally module-level: each browser tab is its own JS
|
|
16
33
|
* realm, so there is no cross-request pollution. Server renders never mutate
|
|
17
34
|
* the store — the hook falls back to `OutletContext.loaderData`.
|
|
@@ -32,51 +49,273 @@ const EMPTY_SNAPSHOT: LoaderEntry = Object.freeze({
|
|
|
32
49
|
requestId: 0,
|
|
33
50
|
});
|
|
34
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Options for `subscribe`.
|
|
54
|
+
*/
|
|
55
|
+
export interface SubscribeOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Family id (`loader.$$id`) this bucket belongs to. `clearFamily` uses it to
|
|
58
|
+
* reach every keyed bucket of the same loader. Defaults to the bucket key.
|
|
59
|
+
*/
|
|
60
|
+
loaderId?: string;
|
|
61
|
+
/**
|
|
62
|
+
* When true, this subscription is from a reader with no route context (keyed
|
|
63
|
+
* `useFetchLoader` of an unregistered loader). Such buckets have no
|
|
64
|
+
* route-context reset trigger and are reference-counted instead. A bucket
|
|
65
|
+
* becomes sticky for the rest of its life as soon as any non-ephemeral
|
|
66
|
+
* subscriber attaches, and from then on resets via `clearFamily`.
|
|
67
|
+
*/
|
|
68
|
+
ephemeral?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Cross-loader refresh group name. Tags this bucket so `refreshGroup(name)`
|
|
71
|
+
* can refresh it alongside buckets of other loaders. Group membership follows
|
|
72
|
+
* subscriber presence: a bucket leaves its group when its last subscriber
|
|
73
|
+
* unsubscribes.
|
|
74
|
+
*/
|
|
75
|
+
group?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Plain-GET refresh thunk used by `refreshGroup`. Provided alongside `group`.
|
|
78
|
+
* Refreshes this bucket in place (no params/body) and rejects on failure.
|
|
79
|
+
*/
|
|
80
|
+
refetch?: () => Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
|
|
35
83
|
interface InternalEntry {
|
|
36
84
|
snapshot: LoaderEntry;
|
|
37
85
|
listeners: Set<() => void>;
|
|
38
86
|
/** Monotonically increasing. Bumped by reserveRequestId() and clear(). */
|
|
39
87
|
latestRequestId: number;
|
|
88
|
+
/** Family id (loader.$$id) this bucket belongs to. */
|
|
89
|
+
loaderId: string;
|
|
90
|
+
/**
|
|
91
|
+
* True once any non-ephemeral subscriber has attached. Sticky buckets are
|
|
92
|
+
* never reference-count-dropped; they reset via clearFamily().
|
|
93
|
+
*/
|
|
94
|
+
sticky: boolean;
|
|
95
|
+
/** A deferred refcount-drop microtask is scheduled and not yet cancelled. */
|
|
96
|
+
pendingClear: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* The last subscriber left while a load() was in flight. Drop the bucket once
|
|
99
|
+
* that request settles, if it is still subscriberless.
|
|
100
|
+
*/
|
|
101
|
+
clearWhenSettled: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Cross-loader refresh groups this bucket belongs to, mapped to the number of
|
|
104
|
+
* current subscribers that requested each group. A bucket can be in several
|
|
105
|
+
* groups at once (different subscribers may tag the same shared bucket with
|
|
106
|
+
* different group names); refcounting keeps membership independent of
|
|
107
|
+
* subscribe/unsubscribe order.
|
|
108
|
+
*/
|
|
109
|
+
groups: Map<string, number>;
|
|
110
|
+
/** Plain-GET refresh thunk for `refreshGroup`, set while in any group. */
|
|
111
|
+
refetch: (() => Promise<void>) | undefined;
|
|
40
112
|
}
|
|
41
113
|
|
|
42
114
|
export class LoaderStore {
|
|
43
115
|
private readonly entries = new Map<string, InternalEntry>();
|
|
116
|
+
/** loader.$$id -> set of bucket keys, so clearFamily() can reach every bucket. */
|
|
117
|
+
private readonly families = new Map<string, Set<string>>();
|
|
118
|
+
/** refresh group name -> set of bucket keys, for refreshGroup(). */
|
|
119
|
+
private readonly groups = new Map<string, Set<string>>();
|
|
44
120
|
|
|
45
|
-
private getOrCreate(
|
|
46
|
-
let e = this.entries.get(
|
|
121
|
+
private getOrCreate(bucketKey: string): InternalEntry {
|
|
122
|
+
let e = this.entries.get(bucketKey);
|
|
47
123
|
if (!e) {
|
|
48
124
|
e = {
|
|
49
125
|
snapshot: EMPTY_SNAPSHOT,
|
|
50
126
|
listeners: new Set(),
|
|
51
127
|
latestRequestId: 0,
|
|
128
|
+
loaderId: bucketKey,
|
|
129
|
+
sticky: false,
|
|
130
|
+
pendingClear: false,
|
|
131
|
+
clearWhenSettled: false,
|
|
132
|
+
groups: new Map(),
|
|
133
|
+
refetch: undefined,
|
|
52
134
|
};
|
|
53
|
-
this.entries.set(
|
|
135
|
+
this.entries.set(bucketKey, e);
|
|
54
136
|
}
|
|
55
137
|
return e;
|
|
56
138
|
}
|
|
57
139
|
|
|
140
|
+
private registerFamily(loaderId: string, bucketKey: string): void {
|
|
141
|
+
let fam = this.families.get(loaderId);
|
|
142
|
+
if (!fam) {
|
|
143
|
+
fam = new Set();
|
|
144
|
+
this.families.set(loaderId, fam);
|
|
145
|
+
}
|
|
146
|
+
fam.add(bucketKey);
|
|
147
|
+
}
|
|
148
|
+
|
|
58
149
|
/**
|
|
59
|
-
* Subscribe to entry changes for `
|
|
60
|
-
* Returns an unsubscribe function.
|
|
150
|
+
* Subscribe to entry changes for `bucketKey`.
|
|
151
|
+
* Returns an unsubscribe function. A sticky bucket's entry is kept around even
|
|
61
152
|
* after the last subscriber leaves so that an in-flight `load()` can still
|
|
62
|
-
* commit if the consumer remounts.
|
|
153
|
+
* commit if the consumer remounts. An ephemeral bucket is dropped once its
|
|
154
|
+
* last subscriber leaves (deferred, see maybeScheduleRefcountClear).
|
|
63
155
|
*/
|
|
64
|
-
subscribe(
|
|
65
|
-
|
|
156
|
+
subscribe(
|
|
157
|
+
bucketKey: string,
|
|
158
|
+
cb: () => void,
|
|
159
|
+
options?: SubscribeOptions,
|
|
160
|
+
): () => void {
|
|
161
|
+
const e = this.getOrCreate(bucketKey);
|
|
162
|
+
const loaderId = options?.loaderId ?? bucketKey;
|
|
163
|
+
e.loaderId = loaderId;
|
|
164
|
+
this.registerFamily(loaderId, bucketKey);
|
|
165
|
+
if (options?.ephemeral !== true) e.sticky = true;
|
|
166
|
+
const group = options?.group;
|
|
167
|
+
if (group !== undefined) {
|
|
168
|
+
this.addToGroup(group, bucketKey, e, options?.refetch);
|
|
169
|
+
}
|
|
170
|
+
// A fresh subscriber means the bucket is wanted again: cancel any pending
|
|
171
|
+
// refcount-drop and the settle-then-drop intent.
|
|
172
|
+
e.pendingClear = false;
|
|
173
|
+
e.clearWhenSettled = false;
|
|
66
174
|
e.listeners.add(cb);
|
|
67
175
|
return () => {
|
|
68
176
|
e.listeners.delete(cb);
|
|
177
|
+
// Group membership is refcounted per subscriber so refreshGroup() never
|
|
178
|
+
// fetches for an unmounted reader, and a bucket shared by subscribers in
|
|
179
|
+
// different groups stays in each group until ALL of that group's
|
|
180
|
+
// subscribers have left (order-independent).
|
|
181
|
+
if (group !== undefined) this.releaseGroup(group, bucketKey, e);
|
|
182
|
+
this.maybeScheduleRefcountClear(bucketKey, e);
|
|
69
183
|
};
|
|
70
184
|
}
|
|
71
185
|
|
|
186
|
+
private addToGroup(
|
|
187
|
+
group: string,
|
|
188
|
+
bucketKey: string,
|
|
189
|
+
e: InternalEntry,
|
|
190
|
+
refetch: (() => Promise<void>) | undefined,
|
|
191
|
+
): void {
|
|
192
|
+
e.groups.set(group, (e.groups.get(group) ?? 0) + 1);
|
|
193
|
+
// One thunk per bucket — every subscriber of a bucket provides an
|
|
194
|
+
// equivalent plain-GET refresh, so keeping the latest is fine.
|
|
195
|
+
if (refetch) e.refetch = refetch;
|
|
196
|
+
let members = this.groups.get(group);
|
|
197
|
+
if (!members) {
|
|
198
|
+
members = new Set();
|
|
199
|
+
this.groups.set(group, members);
|
|
200
|
+
}
|
|
201
|
+
members.add(bucketKey);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private releaseGroup(
|
|
205
|
+
group: string,
|
|
206
|
+
bucketKey: string,
|
|
207
|
+
e: InternalEntry,
|
|
208
|
+
): void {
|
|
209
|
+
const next = (e.groups.get(group) ?? 0) - 1;
|
|
210
|
+
if (next > 0) {
|
|
211
|
+
e.groups.set(group, next);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
e.groups.delete(group);
|
|
215
|
+
const members = this.groups.get(group);
|
|
216
|
+
if (members) {
|
|
217
|
+
members.delete(bucketKey);
|
|
218
|
+
if (members.size === 0) this.groups.delete(group);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Remove a bucket from every group it belongs to (used when it is dropped). */
|
|
223
|
+
private removeFromAllGroups(bucketKey: string, e: InternalEntry): void {
|
|
224
|
+
for (const group of e.groups.keys()) {
|
|
225
|
+
const members = this.groups.get(group);
|
|
226
|
+
if (members) {
|
|
227
|
+
members.delete(bucketKey);
|
|
228
|
+
if (members.size === 0) this.groups.delete(group);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
e.groups.clear();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Refresh every currently-mounted bucket in a cross-loader refresh group with
|
|
236
|
+
* a plain GET (no params/body). Buckets are deduped by key, so multiple reads
|
|
237
|
+
* of one bucket trigger a single fetch. Resolves when all refreshes settle;
|
|
238
|
+
* rejects with an `AggregateError` of the failures if any member fails — each
|
|
239
|
+
* failing member also records its error on its own snapshot.
|
|
240
|
+
*/
|
|
241
|
+
async refreshGroup(group: string): Promise<void> {
|
|
242
|
+
const members = this.groups.get(group);
|
|
243
|
+
if (!members || members.size === 0) return;
|
|
244
|
+
const thunks: Array<() => Promise<void>> = [];
|
|
245
|
+
for (const bucketKey of members) {
|
|
246
|
+
const e = this.entries.get(bucketKey);
|
|
247
|
+
if (!e || e.listeners.size === 0 || !e.refetch) continue;
|
|
248
|
+
thunks.push(e.refetch);
|
|
249
|
+
}
|
|
250
|
+
if (thunks.length === 0) return;
|
|
251
|
+
const results = await Promise.allSettled(thunks.map((t) => t()));
|
|
252
|
+
const reasons = results
|
|
253
|
+
.filter((r): r is PromiseRejectedResult => r.status === "rejected")
|
|
254
|
+
.map((r) => r.reason);
|
|
255
|
+
if (reasons.length > 0) {
|
|
256
|
+
throw new AggregateError(
|
|
257
|
+
reasons,
|
|
258
|
+
`refreshGroup("${group}") had ${reasons.length} failure(s)`,
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Schedule a deferred drop for an ad-hoc (never-sticky) bucket whose last
|
|
265
|
+
* subscriber just left. Deferred to a microtask so a StrictMode / transition
|
|
266
|
+
* remount that resubscribes in the same tick cancels it.
|
|
267
|
+
*/
|
|
268
|
+
private maybeScheduleRefcountClear(
|
|
269
|
+
bucketKey: string,
|
|
270
|
+
e: InternalEntry,
|
|
271
|
+
): void {
|
|
272
|
+
if (e.listeners.size > 0) return;
|
|
273
|
+
// Sticky buckets persist for remount; they reset via clearFamily().
|
|
274
|
+
if (e.sticky) return;
|
|
275
|
+
if (e.pendingClear) return;
|
|
276
|
+
e.pendingClear = true;
|
|
277
|
+
queueMicrotask(() => {
|
|
278
|
+
if (!e.pendingClear) return; // cancelled by a resubscribe
|
|
279
|
+
e.pendingClear = false;
|
|
280
|
+
if (e.listeners.size > 0) return; // resubscribed before the microtask ran
|
|
281
|
+
if (e.snapshot.isLoading) {
|
|
282
|
+
// Don't drop mid-flight; let the request commit, then drop.
|
|
283
|
+
e.clearWhenSettled = true;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
this.dropBucket(bucketKey);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Remove a bucket entry entirely and prune it from its family/group indexes. */
|
|
291
|
+
private dropBucket(bucketKey: string): void {
|
|
292
|
+
const e = this.entries.get(bucketKey);
|
|
293
|
+
if (!e) return;
|
|
294
|
+
this.removeFromAllGroups(bucketKey, e);
|
|
295
|
+
this.entries.delete(bucketKey);
|
|
296
|
+
const fam = this.families.get(e.loaderId);
|
|
297
|
+
if (fam) {
|
|
298
|
+
fam.delete(bucketKey);
|
|
299
|
+
if (fam.size === 0) this.families.delete(e.loaderId);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Drop an ephemeral bucket that settled with no subscribers left. */
|
|
304
|
+
private dropIfSettled(bucketKey: string, e: InternalEntry): void {
|
|
305
|
+
if (e.clearWhenSettled && e.listeners.size === 0) {
|
|
306
|
+
e.clearWhenSettled = false;
|
|
307
|
+
this.dropBucket(bucketKey);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
72
311
|
/**
|
|
73
|
-
* Returns the current snapshot for `
|
|
74
|
-
* — subscribers rely on this to avoid spurious re-renders.
|
|
312
|
+
* Returns the current snapshot for `bucketKey`. Stable reference between
|
|
313
|
+
* mutations — subscribers rely on this to avoid spurious re-renders.
|
|
75
314
|
* Returns `EMPTY_SNAPSHOT` (a singleton) when the entry has never been
|
|
76
315
|
* mutated or has been cleared.
|
|
77
316
|
*/
|
|
78
|
-
getSnapshot(
|
|
79
|
-
return this.entries.get(
|
|
317
|
+
getSnapshot(bucketKey: string): LoaderEntry {
|
|
318
|
+
return this.entries.get(bucketKey)?.snapshot ?? EMPTY_SNAPSHOT;
|
|
80
319
|
}
|
|
81
320
|
|
|
82
321
|
/**
|
|
@@ -89,8 +328,8 @@ export class LoaderStore {
|
|
|
89
328
|
* — the latter matters for `throwOnError: false` consumers, which would
|
|
90
329
|
* otherwise keep showing the stale error throughout the retry.
|
|
91
330
|
*/
|
|
92
|
-
reserveRequestId(
|
|
93
|
-
const e = this.getOrCreate(
|
|
331
|
+
reserveRequestId(bucketKey: string): number {
|
|
332
|
+
const e = this.getOrCreate(bucketKey);
|
|
94
333
|
e.latestRequestId++;
|
|
95
334
|
return e.latestRequestId;
|
|
96
335
|
}
|
|
@@ -101,8 +340,8 @@ export class LoaderStore {
|
|
|
101
340
|
* error during the new request. Gated on `requestId === latestRequestId`
|
|
102
341
|
* for symmetry with the other mutators.
|
|
103
342
|
*/
|
|
104
|
-
beginRequest(
|
|
105
|
-
const e = this.entries.get(
|
|
343
|
+
beginRequest(bucketKey: string, requestId: number): void {
|
|
344
|
+
const e = this.entries.get(bucketKey);
|
|
106
345
|
if (!e || requestId !== e.latestRequestId) return;
|
|
107
346
|
if (e.snapshot.isLoading && e.snapshot.error === null) return;
|
|
108
347
|
e.snapshot = Object.freeze({
|
|
@@ -119,8 +358,8 @@ export class LoaderStore {
|
|
|
119
358
|
* (a newer `load()` was issued or `clear()` ran). Clearing `error` is
|
|
120
359
|
* intentional: a successful refetch should hide the previous failure.
|
|
121
360
|
*/
|
|
122
|
-
finishData<T>(
|
|
123
|
-
const e = this.entries.get(
|
|
361
|
+
finishData<T>(bucketKey: string, requestId: number, value: T): void {
|
|
362
|
+
const e = this.entries.get(bucketKey);
|
|
124
363
|
if (!e || requestId !== e.latestRequestId) return;
|
|
125
364
|
e.snapshot = Object.freeze({
|
|
126
365
|
value,
|
|
@@ -129,6 +368,7 @@ export class LoaderStore {
|
|
|
129
368
|
requestId,
|
|
130
369
|
});
|
|
131
370
|
this.notify(e);
|
|
371
|
+
this.dropIfSettled(bucketKey, e);
|
|
132
372
|
}
|
|
133
373
|
|
|
134
374
|
/**
|
|
@@ -136,8 +376,8 @@ export class LoaderStore {
|
|
|
136
376
|
* showing previous data while displaying the error if they choose. No-op
|
|
137
377
|
* if `requestId` is not the latest.
|
|
138
378
|
*/
|
|
139
|
-
finishError(
|
|
140
|
-
const e = this.entries.get(
|
|
379
|
+
finishError(bucketKey: string, requestId: number, error: Error): void {
|
|
380
|
+
const e = this.entries.get(bucketKey);
|
|
141
381
|
if (!e || requestId !== e.latestRequestId) return;
|
|
142
382
|
e.snapshot = Object.freeze({
|
|
143
383
|
value: e.snapshot.value,
|
|
@@ -146,6 +386,7 @@ export class LoaderStore {
|
|
|
146
386
|
requestId,
|
|
147
387
|
});
|
|
148
388
|
this.notify(e);
|
|
389
|
+
this.dropIfSettled(bucketKey, e);
|
|
149
390
|
}
|
|
150
391
|
|
|
151
392
|
/**
|
|
@@ -153,8 +394,8 @@ export class LoaderStore {
|
|
|
153
394
|
* load() finishes after a new one started — its `setLoading(false)` would
|
|
154
395
|
* otherwise hide the new request's spinner.
|
|
155
396
|
*/
|
|
156
|
-
setLoading(
|
|
157
|
-
const e = this.entries.get(
|
|
397
|
+
setLoading(bucketKey: string, requestId: number, isLoading: boolean): void {
|
|
398
|
+
const e = this.entries.get(bucketKey);
|
|
158
399
|
if (!e || requestId !== e.latestRequestId) return;
|
|
159
400
|
if (e.snapshot.isLoading === isLoading) return;
|
|
160
401
|
e.snapshot = Object.freeze({
|
|
@@ -165,13 +406,13 @@ export class LoaderStore {
|
|
|
165
406
|
}
|
|
166
407
|
|
|
167
408
|
/**
|
|
168
|
-
* Reset
|
|
169
|
-
* promise is still pending will fail its gate when it resolves
|
|
170
|
-
* dropped — prevents pre-navigation loads from clobbering the new
|
|
171
|
-
* context.
|
|
409
|
+
* Reset a single bucket entry. Bumps `latestRequestId` so any in-flight
|
|
410
|
+
* `load()` whose promise is still pending will fail its gate when it resolves
|
|
411
|
+
* and be dropped — prevents pre-navigation loads from clobbering the new
|
|
412
|
+
* route's context. The entry itself is kept (sticky-bucket semantics).
|
|
172
413
|
*/
|
|
173
|
-
clear(
|
|
174
|
-
const e = this.entries.get(
|
|
414
|
+
clear(bucketKey: string): void {
|
|
415
|
+
const e = this.entries.get(bucketKey);
|
|
175
416
|
if (!e) return;
|
|
176
417
|
e.latestRequestId++;
|
|
177
418
|
if (e.snapshot === EMPTY_SNAPSHOT) return;
|
|
@@ -179,6 +420,24 @@ export class LoaderStore {
|
|
|
179
420
|
this.notify(e);
|
|
180
421
|
}
|
|
181
422
|
|
|
423
|
+
/**
|
|
424
|
+
* Reset every sticky bucket belonging to `loaderId`. Called on navigation /
|
|
425
|
+
* route-context change: all route-registered reads of the loader (keyed or
|
|
426
|
+
* not) drop back to seeding from fresh `loaderData`. Ephemeral buckets are
|
|
427
|
+
* intentionally left alone — they are governed by subscriber refcount, so a
|
|
428
|
+
* persistent keyed reader outside the outlet keeps its value across a
|
|
429
|
+
* navigation rather than blanking out.
|
|
430
|
+
*/
|
|
431
|
+
clearFamily(loaderId: string): void {
|
|
432
|
+
const fam = this.families.get(loaderId);
|
|
433
|
+
if (!fam) return;
|
|
434
|
+
for (const bucketKey of fam) {
|
|
435
|
+
const e = this.entries.get(bucketKey);
|
|
436
|
+
if (!e || !e.sticky) continue;
|
|
437
|
+
this.clear(bucketKey);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
182
441
|
private notify(e: InternalEntry): void {
|
|
183
442
|
for (const cb of e.listeners) cb();
|
|
184
443
|
}
|
|
@@ -190,6 +449,8 @@ export class LoaderStore {
|
|
|
190
449
|
*/
|
|
191
450
|
reset(): void {
|
|
192
451
|
this.entries.clear();
|
|
452
|
+
this.families.clear();
|
|
453
|
+
this.groups.clear();
|
|
193
454
|
}
|
|
194
455
|
}
|
|
195
456
|
|