@rangojs/router 0.0.0-experimental.debug-cache-2383ca26 → 0.0.0-experimental.df7974ff
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -35
- 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 +130 -47
- 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 +1884 -537
- 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/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/dist/vite/virtual-entries.js +110 -0
- package/dist/vite/virtual-entries.js.map +1 -0
- package/package.json +7 -5
- package/skills/breadcrumbs/SKILL.md +3 -1
- package/skills/cache-guide/SKILL.md +32 -0
- package/skills/caching/SKILL.md +8 -0
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +54 -20
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +45 -0
- package/skills/layout/SKILL.md +24 -0
- package/skills/links/SKILL.md +237 -17
- package/skills/loader/SKILL.md +123 -46
- package/skills/middleware/SKILL.md +36 -3
- package/skills/migrate-nextjs/SKILL.md +562 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/parallel/SKILL.md +68 -0
- package/skills/prerender/SKILL.md +110 -68
- package/skills/rango/SKILL.md +26 -22
- package/skills/response-routes/SKILL.md +8 -0
- package/skills/route/SKILL.md +79 -0
- package/skills/router-setup/SKILL.md +87 -2
- package/skills/server-actions/SKILL.md +739 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/typesafety/SKILL.md +19 -1
- package/skills/view-transitions/SKILL.md +212 -0
- package/src/__internal.ts +1 -1
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +44 -4
- package/src/browser/navigation-bridge.ts +156 -10
- package/src/browser/navigation-client.ts +128 -53
- package/src/browser/navigation-store.ts +68 -9
- package/src/browser/partial-update.ts +84 -16
- package/src/browser/prefetch/cache.ts +129 -21
- package/src/browser/prefetch/fetch.ts +156 -18
- package/src/browser/prefetch/queue.ts +92 -29
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +53 -13
- package/src/browser/react/Link.tsx +72 -8
- package/src/browser/react/NavigationProvider.tsx +82 -21
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +51 -7
- package/src/browser/react/index.ts +3 -0
- package/src/browser/react/use-handle.ts +9 -58
- package/src/browser/react/use-navigation.ts +22 -2
- package/src/browser/react/use-params.ts +17 -4
- package/src/browser/react/use-reverse.ts +99 -0
- package/src/browser/react/use-router.ts +29 -9
- package/src/browser/react/use-segments.ts +11 -8
- package/src/browser/rsc-router.tsx +60 -9
- package/src/browser/scroll-restoration.ts +38 -33
- package/src/browser/segment-reconciler.ts +36 -14
- package/src/browser/server-action-bridge.ts +8 -6
- package/src/browser/types.ts +46 -5
- package/src/build/generate-manifest.ts +6 -6
- package/src/build/generate-route-types.ts +3 -0
- package/src/build/route-trie.ts +52 -25
- package/src/build/route-types/include-resolution.ts +8 -1
- package/src/build/route-types/router-processing.ts +211 -72
- package/src/build/route-types/scan-filter.ts +8 -1
- package/src/cache/cache-scope.ts +20 -19
- package/src/cache/cf/cf-cache-store.ts +5 -7
- package/src/cache/taint.ts +55 -0
- package/src/client.rsc.tsx +3 -0
- package/src/client.tsx +89 -231
- package/src/context-var.ts +72 -2
- package/src/handle.ts +40 -0
- package/src/href-client.ts +4 -1
- package/src/index.rsc.ts +6 -1
- package/src/index.ts +49 -6
- package/src/outlet-context.ts +1 -1
- package/src/prerender/store.ts +5 -4
- package/src/prerender.ts +138 -77
- package/src/response-utils.ts +28 -0
- package/src/reverse.ts +62 -15
- package/src/route-definition/dsl-helpers.ts +210 -35
- package/src/route-definition/helpers-types.ts +73 -20
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +9 -1
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-types.ts +18 -0
- package/src/router/content-negotiation.ts +100 -1
- package/src/router/handler-context.ts +77 -38
- package/src/router/intercept-resolution.ts +9 -4
- package/src/router/lazy-includes.ts +6 -6
- package/src/router/loader-resolution.ts +159 -21
- package/src/router/manifest.ts +22 -13
- package/src/router/match-api.ts +128 -192
- package/src/router/match-handlers.ts +1 -0
- package/src/router/match-middleware/cache-lookup.ts +28 -8
- package/src/router/match-middleware/segment-resolution.ts +53 -0
- package/src/router/match-result.ts +101 -4
- package/src/router/middleware-types.ts +20 -33
- package/src/router/middleware.ts +56 -12
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +101 -17
- package/src/router/prerender-match.ts +110 -10
- package/src/router/preview-match.ts +30 -102
- package/src/router/request-classification.ts +310 -0
- package/src/router/revalidation.ts +15 -1
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-interfaces.ts +36 -4
- package/src/router/router-options.ts +37 -11
- package/src/router/segment-resolution/fresh.ts +88 -9
- package/src/router/segment-resolution/helpers.ts +29 -24
- package/src/router/segment-resolution/revalidation.ts +219 -108
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/trie-matching.ts +18 -13
- package/src/router/types.ts +1 -0
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +55 -7
- package/src/rsc/handler.ts +478 -374
- package/src/rsc/helpers.ts +69 -41
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +5 -1
- package/src/rsc/progressive-enhancement.ts +18 -2
- package/src/rsc/response-route-handler.ts +14 -1
- package/src/rsc/rsc-rendering.ts +20 -1
- package/src/rsc/server-action.ts +12 -0
- package/src/rsc/ssr-setup.ts +2 -2
- package/src/rsc/types.ts +15 -1
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +71 -70
- package/src/server/context.ts +76 -4
- package/src/server/handle-store.ts +19 -0
- package/src/server/loader-registry.ts +9 -8
- package/src/server/request-context.ts +185 -57
- package/src/ssr/index.tsx +8 -1
- package/src/static-handler.ts +18 -6
- package/src/types/cache-types.ts +4 -4
- package/src/types/handler-context.ts +47 -56
- package/src/types/loader-types.ts +41 -15
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-entry.ts +12 -1
- package/src/types/segments.ts +18 -1
- package/src/urls/include-helper.ts +24 -14
- package/src/urls/path-helper-types.ts +39 -6
- package/src/urls/path-helper.ts +47 -12
- package/src/urls/pattern-types.ts +12 -0
- package/src/urls/response-types.ts +18 -16
- package/src/use-loader.tsx +77 -5
- package/src/vite/debug.ts +184 -0
- package/src/vite/discovery/bundle-postprocess.ts +30 -33
- package/src/vite/discovery/discover-routers.ts +36 -4
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +175 -74
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +13 -4
- package/src/vite/index.ts +4 -0
- package/src/vite/plugin-types.ts +60 -5
- package/src/vite/plugins/cjs-to-esm.ts +5 -0
- package/src/vite/plugins/client-ref-dedup.ts +16 -0
- package/src/vite/plugins/client-ref-hashing.ts +16 -4
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
- package/src/vite/plugins/expose-action-id.ts +52 -28
- package/src/vite/plugins/expose-id-utils.ts +12 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -3
- package/src/vite/plugins/expose-internal-ids.ts +563 -316
- package/src/vite/plugins/performance-tracks.ts +96 -0
- package/src/vite/plugins/refresh-cmd.ts +88 -26
- package/src/vite/plugins/use-cache-transform.ts +56 -43
- package/src/vite/plugins/version-injector.ts +37 -11
- package/src/vite/rango.ts +63 -11
- package/src/vite/router-discovery.ts +732 -86
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/package-resolution.ts +41 -1
- package/src/vite/utils/prerender-utils.ts +38 -5
- package/src/vite/utils/shared-utils.ts +3 -2
|
@@ -0,0 +1,739 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: server-actions
|
|
3
|
+
description: Define and call server actions (`"use server"`) — forms, useActionState, useOptimistic, validation, error handling, redirects, revalidation
|
|
4
|
+
argument-hint: "[action]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Server Actions with `"use server"`
|
|
8
|
+
|
|
9
|
+
Server actions are async functions that run on the server and are callable from
|
|
10
|
+
the client. They are React's RSC mutation primitive — Rango uses them as-is
|
|
11
|
+
with no framework wrapper. All standard React hooks (`useActionState`,
|
|
12
|
+
`useFormStatus`, `useOptimistic`, `useTransition`) work directly.
|
|
13
|
+
|
|
14
|
+
## When to Use Actions vs Loaders
|
|
15
|
+
|
|
16
|
+
| Need | Use |
|
|
17
|
+
| ---------------------------------- | -------------------------------------------- |
|
|
18
|
+
| Mutate state and revalidate UI | Server action |
|
|
19
|
+
| Read live data on every navigation | `createLoader()` + `useLoader()` |
|
|
20
|
+
| Read on demand from the client | Fetchable loader + `useFetchLoader()` |
|
|
21
|
+
| Submit a form and show the result | Action + `useActionState` |
|
|
22
|
+
| File upload | Action with `FormData` (or fetchable loader) |
|
|
23
|
+
|
|
24
|
+
Use loaders and route handlers for reads. Use actions for writes. After an
|
|
25
|
+
action runs, the matched route tree can partially re-render so handlers and
|
|
26
|
+
loaders that opt into revalidation see the new state — see "Revalidation"
|
|
27
|
+
below.
|
|
28
|
+
|
|
29
|
+
## Revalidation Model
|
|
30
|
+
|
|
31
|
+
Actions mutate state; route handlers and loaders read the latest state. After
|
|
32
|
+
an action finishes, Rango performs a server-side revalidation render for the
|
|
33
|
+
matched route so the UI receives fresh segment output and loader data.
|
|
34
|
+
|
|
35
|
+
The main control point is `revalidate(({ actionId }) => ...)` on the segment
|
|
36
|
+
that owns the data. This applies to `path()` handlers, `layout()` handlers,
|
|
37
|
+
`parallel()` slots, `intercept()` routes, and loader registrations:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// urls.tsx — path/layout/parallel/intercept/loader/revalidate are passed in by urls()
|
|
41
|
+
import { urls } from "@rangojs/router";
|
|
42
|
+
|
|
43
|
+
export const urlpatterns = urls(({ path, loader, revalidate }) => [
|
|
44
|
+
// The loader belongs to the route that consumes its data — nest it inside
|
|
45
|
+
// the owning path() so the segment owns its data dependency.
|
|
46
|
+
path("/cart", CartPage, { name: "cart" }, () => [
|
|
47
|
+
revalidate(
|
|
48
|
+
({ actionId }) => actionId?.startsWith("src/actions/cart.ts#") ?? false,
|
|
49
|
+
),
|
|
50
|
+
loader(CartLoader, () => [
|
|
51
|
+
revalidate(
|
|
52
|
+
({ actionId }) => actionId?.startsWith("src/actions/cart.ts#") ?? false,
|
|
53
|
+
),
|
|
54
|
+
]),
|
|
55
|
+
]),
|
|
56
|
+
]);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For module-level `"use server"` files, the `actionId` passed to every
|
|
60
|
+
server-side `revalidate()` predicate is path-bearing in the server/RSC
|
|
61
|
+
environment in both dev and production: `src/actions/cart.ts#addToCart`. This
|
|
62
|
+
is intentional so path, layout, parallel, intercept, and loader revalidation
|
|
63
|
+
predicates can filter by action file, directory, or export name.
|
|
64
|
+
|
|
65
|
+
Actions and the follow-up revalidation render share one request context.
|
|
66
|
+
Values written in the action with `ctx.set(MyVar, value)` or `ctx.set("key",
|
|
67
|
+
value)` are visible to downstream route middleware, handlers, loaders, and
|
|
68
|
+
`revalidate()` callbacks through `context.get(MyVar)` / `context.get("key")`:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// app/context.ts
|
|
72
|
+
import { createVar } from "@rangojs/router";
|
|
73
|
+
|
|
74
|
+
export const ChangedTenant = createVar<string>();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// app/actions/tenant.ts
|
|
79
|
+
"use server";
|
|
80
|
+
|
|
81
|
+
import { getRequestContext } from "@rangojs/router";
|
|
82
|
+
import { ChangedTenant } from "../context";
|
|
83
|
+
|
|
84
|
+
export async function switchTenant(tenantId: string) {
|
|
85
|
+
const ctx = getRequestContext();
|
|
86
|
+
ctx.set(ChangedTenant, tenantId);
|
|
87
|
+
await db.tenants.touch(tenantId);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// urls.tsx
|
|
93
|
+
import { urls } from "@rangojs/router";
|
|
94
|
+
import { ChangedTenant } from "./context";
|
|
95
|
+
|
|
96
|
+
export const urlpatterns = urls(({ path, revalidate }) => [
|
|
97
|
+
path("/dashboard/:tenantId", DashboardPage, { name: "dashboard" }, () => [
|
|
98
|
+
revalidate(
|
|
99
|
+
({ actionId, context }) =>
|
|
100
|
+
actionId?.startsWith("src/actions/tenant.ts#") &&
|
|
101
|
+
context.get(ChangedTenant) === context.params.tenantId,
|
|
102
|
+
),
|
|
103
|
+
]),
|
|
104
|
+
]);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Client and SSR-facing action references keep hashed IDs in production for
|
|
108
|
+
security and hydration compatibility. Do path matching inside server-side
|
|
109
|
+
`revalidate()` predicates, not from client action metadata. Inline actions
|
|
110
|
+
declared inside RSC components also keep hashed IDs; if you need path-based
|
|
111
|
+
revalidation, export the action from a module-level `"use server"` file.
|
|
112
|
+
|
|
113
|
+
## Defining an Action
|
|
114
|
+
|
|
115
|
+
Two equivalent patterns. Prefer the file-level form for anything reusable.
|
|
116
|
+
|
|
117
|
+
### File-level (`"use server"` at the top of a module)
|
|
118
|
+
|
|
119
|
+
Every exported async function becomes a callable server action.
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// app/actions/cart.ts
|
|
123
|
+
"use server";
|
|
124
|
+
|
|
125
|
+
import { cookies } from "@rangojs/router";
|
|
126
|
+
|
|
127
|
+
export async function addToCart(productId: string): Promise<void> {
|
|
128
|
+
const userId = cookies().get("user-id")?.value;
|
|
129
|
+
await db.cart.insert({ userId, productId });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function removeFromCart(productId: string): Promise<void> {
|
|
133
|
+
const userId = cookies().get("user-id")?.value;
|
|
134
|
+
await db.cart.delete({ userId, productId });
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Inline (`"use server"` inside a server component)
|
|
139
|
+
|
|
140
|
+
Define a one-off action where it is used. Captured variables are serialized,
|
|
141
|
+
so keep them small and serializable.
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
// Server component (handler)
|
|
145
|
+
import type { Handler } from "@rangojs/router";
|
|
146
|
+
|
|
147
|
+
const SettingsPage: Handler<"settings"> = (ctx) => {
|
|
148
|
+
const userId = ctx.get("user").id;
|
|
149
|
+
|
|
150
|
+
async function updateName(formData: FormData) {
|
|
151
|
+
"use server";
|
|
152
|
+
await db.users.update(userId, { name: formData.get("name") as string });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<form action={updateName}>
|
|
157
|
+
<input name="name" />
|
|
158
|
+
<button type="submit">Save</button>
|
|
159
|
+
</form>
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Calling Actions from the Client
|
|
165
|
+
|
|
166
|
+
Three patterns, in order of how much state you need to preserve:
|
|
167
|
+
|
|
168
|
+
### 1. Plain `<form action={...}>` — fire-and-forget
|
|
169
|
+
|
|
170
|
+
Submits as `FormData`. Works without JavaScript (progressive enhancement).
|
|
171
|
+
The page revalidates after the action returns.
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
"use client";
|
|
175
|
+
import { addToCart } from "../actions/cart";
|
|
176
|
+
|
|
177
|
+
export function AddToCartForm({ productId }: { productId: string }) {
|
|
178
|
+
return (
|
|
179
|
+
<form action={addToCart.bind(null, productId)}>
|
|
180
|
+
<button type="submit">Add to cart</button>
|
|
181
|
+
</form>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 2. `useActionState` — preserve return value + pending state
|
|
187
|
+
|
|
188
|
+
Standard React 19 hook. The action receives `(prevState, formData)` and its
|
|
189
|
+
return value becomes the new `state`. The form input values are preserved by
|
|
190
|
+
the browser on validation errors as long as you re-render the same form
|
|
191
|
+
element with `defaultValue` (not `value`).
|
|
192
|
+
|
|
193
|
+
Define the state shape next to the action so the client and server share
|
|
194
|
+
one type:
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// app/actions/profile.ts
|
|
198
|
+
"use server";
|
|
199
|
+
|
|
200
|
+
export type ProfileFormState = {
|
|
201
|
+
errors?: Record<string, string>;
|
|
202
|
+
values?: { name: string };
|
|
203
|
+
} | null;
|
|
204
|
+
|
|
205
|
+
export async function saveProfile(
|
|
206
|
+
_prev: ProfileFormState,
|
|
207
|
+
formData: FormData,
|
|
208
|
+
): Promise<ProfileFormState> {
|
|
209
|
+
const name = (formData.get("name") as string)?.trim() ?? "";
|
|
210
|
+
if (!name) {
|
|
211
|
+
return { errors: { name: "Name is required" }, values: { name } };
|
|
212
|
+
}
|
|
213
|
+
await db.users.update({ name });
|
|
214
|
+
return null; // success
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
"use client";
|
|
220
|
+
import { useActionState } from "react";
|
|
221
|
+
import { saveProfile, type ProfileFormState } from "../actions/profile";
|
|
222
|
+
|
|
223
|
+
export function ProfileForm({ initial }: { initial: { name: string } }) {
|
|
224
|
+
const [state, formAction, isPending] = useActionState<
|
|
225
|
+
ProfileFormState,
|
|
226
|
+
FormData
|
|
227
|
+
>(saveProfile, null);
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<form action={formAction}>
|
|
231
|
+
<input
|
|
232
|
+
name="name"
|
|
233
|
+
defaultValue={state?.values?.name ?? initial.name}
|
|
234
|
+
aria-invalid={!!state?.errors?.name}
|
|
235
|
+
/>
|
|
236
|
+
{state?.errors?.name && <p role="alert">{state.errors.name}</p>}
|
|
237
|
+
<button type="submit" disabled={isPending}>
|
|
238
|
+
{isPending ? "Saving…" : "Save"}
|
|
239
|
+
</button>
|
|
240
|
+
</form>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Why `defaultValue`, not `value`** — on validation error the form re-renders.
|
|
246
|
+
With `value` the inputs reset; with `defaultValue` (and a stable form key) the
|
|
247
|
+
browser keeps user input. Re-echo the submitted values in `state.values` so
|
|
248
|
+
they survive a full no-JS re-render too.
|
|
249
|
+
|
|
250
|
+
### 3. `useOptimistic` — instant UI before the action settles
|
|
251
|
+
|
|
252
|
+
For reactive UI like quantity controls, like buttons, or todo toggles.
|
|
253
|
+
Combine with `startTransition` so the optimistic update is part of the same
|
|
254
|
+
transition as the action call.
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
"use client";
|
|
258
|
+
import { useOptimistic, startTransition } from "react";
|
|
259
|
+
import { updateQuantity } from "../actions/cart";
|
|
260
|
+
|
|
261
|
+
export function QuantityControl({
|
|
262
|
+
productId,
|
|
263
|
+
initialQuantity,
|
|
264
|
+
}: {
|
|
265
|
+
productId: string;
|
|
266
|
+
initialQuantity: number;
|
|
267
|
+
}) {
|
|
268
|
+
const [optimistic, setOptimistic] = useOptimistic(
|
|
269
|
+
initialQuantity,
|
|
270
|
+
(_current, next: number) => next,
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
function change(delta: number) {
|
|
274
|
+
const next = Math.max(0, optimistic + delta);
|
|
275
|
+
startTransition(async () => {
|
|
276
|
+
setOptimistic(next);
|
|
277
|
+
await updateQuantity(productId, delta);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<div>
|
|
283
|
+
<button onClick={() => change(-1)}>-</button>
|
|
284
|
+
<span>{optimistic}</span>
|
|
285
|
+
<button onClick={() => change(1)}>+</button>
|
|
286
|
+
</div>
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
`useOptimistic` resets to the real value once the surrounding transition
|
|
292
|
+
settles and React re-renders with the post-action loader data.
|
|
293
|
+
|
|
294
|
+
### `useFormStatus` — pending state in nested children
|
|
295
|
+
|
|
296
|
+
When the submit button is in a separate component from the form, use
|
|
297
|
+
`useFormStatus()` instead of threading `isPending` down via props.
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
"use client";
|
|
301
|
+
import { useFormStatus } from "react-dom";
|
|
302
|
+
|
|
303
|
+
export function SubmitButton({ children }: { children: React.ReactNode }) {
|
|
304
|
+
const { pending } = useFormStatus();
|
|
305
|
+
return (
|
|
306
|
+
<button type="submit" disabled={pending}>
|
|
307
|
+
{pending ? "Working…" : children}
|
|
308
|
+
</button>
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
`useFormStatus` only reports the form it is rendered inside — it does not
|
|
314
|
+
observe other forms.
|
|
315
|
+
|
|
316
|
+
## Validation with Zod
|
|
317
|
+
|
|
318
|
+
Validate on the server, return structured errors via `useActionState`. Keep
|
|
319
|
+
the schema next to the action so client and server agree on the shape.
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
// app/actions/signup.ts
|
|
323
|
+
"use server";
|
|
324
|
+
|
|
325
|
+
import { z } from "zod";
|
|
326
|
+
import { redirect } from "@rangojs/router";
|
|
327
|
+
|
|
328
|
+
const SignupSchema = z.object({
|
|
329
|
+
email: z.string().email("Enter a valid email"),
|
|
330
|
+
password: z.string().min(8, "At least 8 characters"),
|
|
331
|
+
name: z.string().min(1, "Required"),
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
export type SignupState = {
|
|
335
|
+
errors?: Partial<Record<keyof z.infer<typeof SignupSchema>, string>>;
|
|
336
|
+
values?: Partial<z.infer<typeof SignupSchema>>;
|
|
337
|
+
} | null;
|
|
338
|
+
|
|
339
|
+
export async function signup(
|
|
340
|
+
_prev: SignupState,
|
|
341
|
+
formData: FormData,
|
|
342
|
+
): Promise<SignupState> {
|
|
343
|
+
const raw = {
|
|
344
|
+
email: formData.get("email") as string,
|
|
345
|
+
password: formData.get("password") as string,
|
|
346
|
+
name: formData.get("name") as string,
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const parsed = SignupSchema.safeParse(raw);
|
|
350
|
+
if (!parsed.success) {
|
|
351
|
+
const errors: Record<string, string> = {};
|
|
352
|
+
for (const issue of parsed.error.issues) {
|
|
353
|
+
const key = String(issue.path[0]);
|
|
354
|
+
errors[key] ??= issue.message; // first error per field
|
|
355
|
+
}
|
|
356
|
+
// Echo back values (omit password) so the form preserves user input.
|
|
357
|
+
const { password: _drop, ...safeValues } = raw;
|
|
358
|
+
return { errors, values: safeValues };
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
await db.users.create(parsed.data);
|
|
362
|
+
throw redirect("/welcome");
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The form reads `state.errors` field-by-field and re-uses `state.values` as
|
|
367
|
+
`defaultValue`s (see `useActionState` example above). Never echo back
|
|
368
|
+
secrets like passwords.
|
|
369
|
+
|
|
370
|
+
For schemas shared with a `useFetchLoader()` JSON body, parse the same way:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
const parsed = SignupSchema.safeParse(ctx.body);
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Revalidation After an Action
|
|
377
|
+
|
|
378
|
+
When an action mutates data, the matched route tree may need to partially
|
|
379
|
+
re-render so the UI updates. Rango runs the action, then evaluates
|
|
380
|
+
`revalidate()` on matched segments and loaders. Each path, layout, parallel,
|
|
381
|
+
intercept, or loader rule decides whether that piece re-renders/re-resolves.
|
|
382
|
+
|
|
383
|
+
The `actionId` arrives as part of the revalidation context — match it to
|
|
384
|
+
scope re-runs to specific actions.
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// urls.tsx — inside the urls() callback. Nest each loader inside the path(),
|
|
388
|
+
// layout(), or parallel() that owns its data so the route tree mirrors the
|
|
389
|
+
// data dependencies.
|
|
390
|
+
urls(({ path, loader, revalidate }) => [
|
|
391
|
+
path("/", HomePage, { name: "home" }, () => [
|
|
392
|
+
// Loader data re-runs by default after any action. Opt out with revalidate(() => false).
|
|
393
|
+
loader(StaticHomepageLoader, () => [revalidate(() => false)]),
|
|
394
|
+
]),
|
|
395
|
+
|
|
396
|
+
// Re-render the cart page handler AND re-resolve its loader after cart actions
|
|
397
|
+
path("/cart", CartPage, { name: "cart" }, () => [
|
|
398
|
+
revalidate(
|
|
399
|
+
({ actionId }) => actionId?.startsWith("src/actions/cart.ts#") ?? false,
|
|
400
|
+
),
|
|
401
|
+
loader(CartLoader, () => [
|
|
402
|
+
revalidate(
|
|
403
|
+
({ actionId }) => actionId?.startsWith("src/actions/cart.ts#") ?? false,
|
|
404
|
+
),
|
|
405
|
+
]),
|
|
406
|
+
]),
|
|
407
|
+
|
|
408
|
+
// Re-run after any action under src/actions/account/
|
|
409
|
+
path("/account", AccountPage, { name: "account" }, () => [
|
|
410
|
+
loader(AccountLoader, () => [
|
|
411
|
+
revalidate(
|
|
412
|
+
({ actionId }) => actionId?.startsWith("src/actions/account/") ?? false,
|
|
413
|
+
),
|
|
414
|
+
]),
|
|
415
|
+
]),
|
|
416
|
+
]);
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
`actionId` is stable per action. For actions exported from a module-level
|
|
420
|
+
`"use server"` file, the ID is prefixed with the source file path
|
|
421
|
+
(`src/actions/cart.ts#addToCart`), so substring matching by file path is the
|
|
422
|
+
recommended scope. **Inline `"use server"` actions** (declared inside an RSC
|
|
423
|
+
component) intentionally keep their hashed IDs — file paths are withheld
|
|
424
|
+
from the client for security. If you need file-path-based revalidation
|
|
425
|
+
predicates, define the action in a module-level `"use server"` file rather
|
|
426
|
+
than inline. See `/loader` for the full revalidation contract (deferred
|
|
427
|
+
returns, soft suggestions).
|
|
428
|
+
|
|
429
|
+
### Cross-segment dependencies
|
|
430
|
+
|
|
431
|
+
If a loader reads `ctx.get()` data set by an outer layout/handler, that
|
|
432
|
+
outer segment must also re-run after the action — otherwise the loader sees
|
|
433
|
+
stale context. Share the same `revalidate` predicate on both producer and
|
|
434
|
+
consumer:
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
const revalidateCart = ({ actionId }) =>
|
|
438
|
+
actionId?.startsWith("src/actions/cart.ts#") ?? false;
|
|
439
|
+
|
|
440
|
+
urls(({ path, layout, loader, revalidate }) => [
|
|
441
|
+
layout(CartLayout, () => [
|
|
442
|
+
revalidate(revalidateCart), // producer reruns
|
|
443
|
+
path("/cart", CartPage, { name: "cart" }, () => [
|
|
444
|
+
loader(CartItemsLoader, () => [revalidate(revalidateCart)]), // consumer reruns
|
|
445
|
+
]),
|
|
446
|
+
]),
|
|
447
|
+
]);
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
See `/middleware` for the full cross-segment revalidation contract.
|
|
451
|
+
|
|
452
|
+
## Redirects
|
|
453
|
+
|
|
454
|
+
`redirect()` works inside actions. Both `return redirect(...)` and
|
|
455
|
+
`throw redirect(...)` are supported and behave the same way for the
|
|
456
|
+
client. Throwing is clearer when the redirect is conditional.
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
"use server";
|
|
460
|
+
|
|
461
|
+
import { redirect, cookies } from "@rangojs/router";
|
|
462
|
+
import { FlashMessage } from "../location-states";
|
|
463
|
+
|
|
464
|
+
export async function login(_prev: unknown, formData: FormData) {
|
|
465
|
+
const email = formData.get("email") as string;
|
|
466
|
+
const session = await authenticate(email);
|
|
467
|
+
if (!session) return { error: "Invalid credentials" };
|
|
468
|
+
|
|
469
|
+
cookies().set("session", session.token, { httpOnly: true, path: "/" });
|
|
470
|
+
throw redirect("/dashboard", {
|
|
471
|
+
state: FlashMessage({ text: "Welcome back!" }),
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
Redirects from actions render the **target** route tree's matched segments
|
|
477
|
+
(paths, layouts, parallels, intercepts) and re-resolve its loaders, not the
|
|
478
|
+
source page's — the target is what the user sees next. See `/hooks
|
|
479
|
+
useLocationState` for reading flash state on the target page.
|
|
480
|
+
|
|
481
|
+
## Error Handling
|
|
482
|
+
|
|
483
|
+
### Validation errors — return them as state
|
|
484
|
+
|
|
485
|
+
Recoverable errors (form validation, business rules) should be returned via
|
|
486
|
+
`useActionState`. The form re-renders with the error and the user can fix
|
|
487
|
+
it. Throwing for a validation error escalates to an error boundary, which
|
|
488
|
+
is usually too aggressive.
|
|
489
|
+
|
|
490
|
+
### Unexpected errors — let them throw
|
|
491
|
+
|
|
492
|
+
Throw for genuinely exceptional conditions (network failure, DB outage,
|
|
493
|
+
auth violation). The nearest `errorBoundary()` in the route tree catches
|
|
494
|
+
them.
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
import { errorBoundary } from "@rangojs/router";
|
|
498
|
+
|
|
499
|
+
layout(CheckoutLayout, () => [
|
|
500
|
+
errorBoundary(({ error, reset }) => (
|
|
501
|
+
<div>
|
|
502
|
+
<p>Checkout failed: {error.message}</p>
|
|
503
|
+
<button onClick={reset}>Try again</button>
|
|
504
|
+
</div>
|
|
505
|
+
)),
|
|
506
|
+
path("/checkout", CheckoutPage, { name: "checkout" }),
|
|
507
|
+
]);
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Not found from an action
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
import { notFound } from "@rangojs/router";
|
|
514
|
+
|
|
515
|
+
export async function deletePost(id: string): Promise<void> {
|
|
516
|
+
"use server";
|
|
517
|
+
const post = await db.posts.find(id);
|
|
518
|
+
if (!post) notFound("Post not found"); // hits notFoundBoundary
|
|
519
|
+
await db.posts.delete(id);
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Authorization in actions
|
|
524
|
+
|
|
525
|
+
Route middleware does **not** wrap action execution — only global
|
|
526
|
+
middleware (`router.use()`) does. Auth checks must therefore live in
|
|
527
|
+
`router.use()` or inside the action itself. Don't rely on a route-level
|
|
528
|
+
`middleware()` to gate action access.
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
// router.tsx — global guard wraps action + render
|
|
532
|
+
const router = createRouter()
|
|
533
|
+
.use(authInit)
|
|
534
|
+
.use("/admin/*", requireAdmin) // protects actions on /admin too
|
|
535
|
+
.routes(urlpatterns);
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
// Or check inside the action body
|
|
540
|
+
"use server";
|
|
541
|
+
import { getRequestContext, redirect, notFound } from "@rangojs/router";
|
|
542
|
+
|
|
543
|
+
export class ForbiddenError extends Error {
|
|
544
|
+
constructor() {
|
|
545
|
+
super("You do not have permission to perform this action.");
|
|
546
|
+
this.name = "ForbiddenError";
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export async function deleteOrder(orderId: string) {
|
|
551
|
+
const ctx = getRequestContext();
|
|
552
|
+
const user = ctx.get("user");
|
|
553
|
+
if (!user) throw redirect("/login"); // unauthenticated → bounce to login
|
|
554
|
+
|
|
555
|
+
const order = await db.orders.get(orderId);
|
|
556
|
+
if (!order) notFound("Order not found"); // → notFoundBoundary
|
|
557
|
+
if (order.userId !== user.id) throw new ForbiddenError(); // → errorBoundary
|
|
558
|
+
|
|
559
|
+
await db.orders.delete(orderId);
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
> **Don't `throw new Response("Unauthorized", { status: 401 })`** — non-redirect
|
|
564
|
+
> Responses thrown from actions are treated as errors and routed to the nearest
|
|
565
|
+
> `errorBoundary()`, not returned as real HTTP responses (the dev build warns
|
|
566
|
+
> when you do this). Use `redirect()` to send unauthenticated users to a login
|
|
567
|
+
> page, `notFound()` for missing resources, and a domain error class for
|
|
568
|
+
> forbidden access so the boundary can render an appropriate UI. For
|
|
569
|
+
> recoverable cases, return `{ error: "..." }` via `useActionState` instead of
|
|
570
|
+
> throwing.
|
|
571
|
+
|
|
572
|
+
## Action Context
|
|
573
|
+
|
|
574
|
+
Actions can read the request context with `getRequestContext()`. This gives
|
|
575
|
+
the same context-variable, header, and reverse APIs that handlers and
|
|
576
|
+
middleware use.
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
"use server";
|
|
580
|
+
import { getRequestContext, cookies, headers } from "@rangojs/router";
|
|
581
|
+
|
|
582
|
+
export async function trackEvent(name: string) {
|
|
583
|
+
const ctx = getRequestContext();
|
|
584
|
+
const user = ctx.get("user"); // set by global middleware
|
|
585
|
+
const ua = headers().get("user-agent");
|
|
586
|
+
const url = ctx.reverse("dashboard"); // type-safe URL by route name
|
|
587
|
+
await analytics.record({ name, userId: user?.id, ua, url });
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
State written via `ctx.set(...)` or `cookies().set(...)` during an action
|
|
592
|
+
is visible to downstream route middleware, segment handlers (path/layout/
|
|
593
|
+
parallel/intercept), loaders, and `revalidate()` callbacks during the
|
|
594
|
+
post-action revalidation render — actions and revalidation share the same
|
|
595
|
+
request scope.
|
|
596
|
+
|
|
597
|
+
### Constraints
|
|
598
|
+
|
|
599
|
+
| Constraint | Why |
|
|
600
|
+
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
601
|
+
| Actions cannot return or throw a non-redirect `Response` | Return values go through RSC Flight serialization. A thrown non-redirect `Response` is treated as a regular error and hits the nearest `errorBoundary()` (dev warns). Use `redirect()`, `notFound()`, or domain errors. |
|
|
602
|
+
| Route DSL `middleware()` does not wrap actions | Actions execute before route middleware. Only global `router.use()` middleware (and its scoped variants) wrap action execution. |
|
|
603
|
+
| `useFetchLoader()` is for reads, not writes | Actions are the mutation primitive; loaders are for data fetching. |
|
|
604
|
+
|
|
605
|
+
Cookies/headers set in **global** `router.use()` middleware DO propagate to
|
|
606
|
+
action responses (the same merge path as a normal render). The constraint
|
|
607
|
+
specific to **per-fetchable-loader** middleware (`createLoader(fn, {
|
|
608
|
+
middleware })` on a POST request) is that it cannot set cookies — set them
|
|
609
|
+
in the loader body instead. See `/middleware` for the full middleware
|
|
610
|
+
contract.
|
|
611
|
+
|
|
612
|
+
## File Uploads
|
|
613
|
+
|
|
614
|
+
Forms with `enctype="multipart/form-data"` (or any file input) submit to
|
|
615
|
+
actions as `FormData`. Stream the file directly — don't buffer if the
|
|
616
|
+
runtime supports streaming.
|
|
617
|
+
|
|
618
|
+
Write the action with the `(prevState, formData) => newState` signature so
|
|
619
|
+
it can be passed straight to `<form action={uploadAvatar}>` (PE-compatible)
|
|
620
|
+
**and** to `useActionState` without a client-side wrapper:
|
|
621
|
+
|
|
622
|
+
```typescript
|
|
623
|
+
// app/actions/avatar.ts
|
|
624
|
+
"use server";
|
|
625
|
+
|
|
626
|
+
import { getRequestContext } from "@rangojs/router";
|
|
627
|
+
|
|
628
|
+
export type AvatarUploadState = { url?: string; error?: string } | null;
|
|
629
|
+
|
|
630
|
+
export async function uploadAvatar(
|
|
631
|
+
_prev: AvatarUploadState,
|
|
632
|
+
formData: FormData,
|
|
633
|
+
): Promise<AvatarUploadState> {
|
|
634
|
+
const file = formData.get("avatar") as File | null;
|
|
635
|
+
if (!file || file.size === 0) return { error: "No file selected" };
|
|
636
|
+
if (file.size > 5_000_000) return { error: "File too large (max 5MB)" };
|
|
637
|
+
|
|
638
|
+
const ctx = getRequestContext();
|
|
639
|
+
const key = `avatars/${crypto.randomUUID()}-${file.name}`;
|
|
640
|
+
await ctx.env.BUCKET.put(key, file.stream());
|
|
641
|
+
return { url: `/r2/${key}` };
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
```tsx
|
|
646
|
+
"use client";
|
|
647
|
+
import { useActionState } from "react";
|
|
648
|
+
import { uploadAvatar, type AvatarUploadState } from "../actions/avatar";
|
|
649
|
+
|
|
650
|
+
export function AvatarUpload() {
|
|
651
|
+
const [state, action, pending] = useActionState<AvatarUploadState, FormData>(
|
|
652
|
+
uploadAvatar,
|
|
653
|
+
null,
|
|
654
|
+
);
|
|
655
|
+
return (
|
|
656
|
+
<form action={action}>
|
|
657
|
+
<input type="file" name="avatar" accept="image/*" />
|
|
658
|
+
<button disabled={pending}>{pending ? "Uploading…" : "Upload"}</button>
|
|
659
|
+
{state?.error && <p role="alert">{state.error}</p>}
|
|
660
|
+
{state?.url && <img src={state.url} alt="" />}
|
|
661
|
+
</form>
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Wrapping the action in a client-side inline function (`useActionState(async
|
|
667
|
+
(_prev, fd) => uploadAvatar(fd), null)`) breaks PE: that closure isn't a
|
|
668
|
+
server reference, so the form has no real `action` URL when JS hasn't
|
|
669
|
+
loaded. Keep the action's signature `(_prev, formData)` and pass it
|
|
670
|
+
directly.
|
|
671
|
+
|
|
672
|
+
For client-side upload progress or cancellation, use a fetchable loader
|
|
673
|
+
with `useFetchLoader()` instead — see `/hooks useFetchLoader`.
|
|
674
|
+
|
|
675
|
+
## Tracking Action State Without `useActionState`
|
|
676
|
+
|
|
677
|
+
Use `useAction()` from `@rangojs/router/client` to track an action's
|
|
678
|
+
state from outside a form (e.g. an action triggered by `onClick`).
|
|
679
|
+
|
|
680
|
+
```tsx
|
|
681
|
+
"use client";
|
|
682
|
+
import { useAction } from "@rangojs/router/client";
|
|
683
|
+
import { addToCart } from "../actions/cart";
|
|
684
|
+
|
|
685
|
+
function AddButton({ productId }: { productId: string }) {
|
|
686
|
+
const { state, error } = useAction(addToCart);
|
|
687
|
+
return (
|
|
688
|
+
<>
|
|
689
|
+
<button
|
|
690
|
+
onClick={() => addToCart(productId)}
|
|
691
|
+
disabled={state === "loading"}
|
|
692
|
+
>
|
|
693
|
+
{state === "loading" ? "Adding…" : "Add"}
|
|
694
|
+
</button>
|
|
695
|
+
{error && <p role="alert">{error.message}</p>}
|
|
696
|
+
</>
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
`useActionState` and `useAction` are complementary — use `useActionState`
|
|
702
|
+
for `<form action={...}>` flows, `useAction` for imperative button clicks
|
|
703
|
+
or to observe an action triggered elsewhere on the page.
|
|
704
|
+
|
|
705
|
+
## Progressive Enhancement
|
|
706
|
+
|
|
707
|
+
`<form action={serverAction}>` works without JavaScript: the form posts as a
|
|
708
|
+
normal HTTP request, the action runs, and the page re-renders server-side.
|
|
709
|
+
For PE to work, write actions that accept `FormData` directly (not curried
|
|
710
|
+
or wrapped):
|
|
711
|
+
|
|
712
|
+
```tsx
|
|
713
|
+
// Works with no-JS submission
|
|
714
|
+
<form action={submitName}>
|
|
715
|
+
<input name="name" />
|
|
716
|
+
<button>Submit</button>
|
|
717
|
+
</form>
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
```typescript
|
|
721
|
+
"use server";
|
|
722
|
+
export async function submitName(formData: FormData) {
|
|
723
|
+
const name = formData.get("name") as string;
|
|
724
|
+
await db.entries.add({ name });
|
|
725
|
+
}
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
`useActionState` and `useOptimistic` only enhance the experience once JS is
|
|
729
|
+
loaded — without JS, the underlying action still runs and the page still
|
|
730
|
+
re-renders. Don't rely on client-only state for required form behavior.
|
|
731
|
+
|
|
732
|
+
## Cross-references
|
|
733
|
+
|
|
734
|
+
- `/hooks` — `useAction`, `useFetchLoader`, `useLocationState` (flash state)
|
|
735
|
+
- `/loader` — read patterns, fetchable loaders, revalidation rule semantics
|
|
736
|
+
- `/middleware` — action vs render scope, revalidation contracts
|
|
737
|
+
- `/links` — `ctx.reverse()` and `getRequestContext().reverse()` from actions
|
|
738
|
+
- `/migrate-react-router` — `action()` → `"use server"` mapping
|
|
739
|
+
- `/migrate-nextjs` — Next.js server action parity
|