@rangojs/router 0.0.0-experimental.32 → 0.0.0-experimental.3232cd17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/README.md +198 -44
- package/dist/bin/rango.js +287 -105
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3248 -1117
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +73 -21
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +107 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +245 -21
- package/skills/caching/SKILL.md +302 -6
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +270 -30
- package/skills/host-router/SKILL.md +82 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +294 -30
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +97 -5
- package/skills/router-setup/SKILL.md +90 -5
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +120 -0
- package/skills/typesafety/SKILL.md +329 -27
- package/skills/use-cache/SKILL.md +36 -5
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +67 -40
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +86 -147
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +148 -19
- package/src/browser/navigation-client.ts +187 -67
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/partial-update.ts +123 -94
- package/src/browser/prefetch/cache.ts +214 -36
- package/src/browser/prefetch/fetch.ts +260 -38
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +126 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +93 -11
- package/src/browser/react/NavigationProvider.tsx +115 -34
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +46 -11
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +52 -1
- package/src/browser/rsc-router.tsx +215 -76
- package/src/browser/scroll-restoration.ts +46 -39
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -50
- package/src/browser/types.ts +95 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +278 -96
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +149 -43
- package/src/cache/cache-scope.ts +148 -81
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2550 -93
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +78 -27
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +52 -26
- package/src/index.ts +100 -38
- package/src/internal-debug.ts +2 -4
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +437 -274
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +113 -37
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +52 -10
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -17
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +45 -22
- package/src/router/handler-context.ts +83 -41
- package/src/router/intercept-resolution.ts +25 -23
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +213 -30
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +120 -204
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +27 -6
- package/src/router/match-middleware/cache-lookup.ts +205 -249
- package/src/router/match-middleware/cache-store.ts +45 -32
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +104 -40
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +173 -143
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +190 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +6 -28
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +242 -75
- package/src/router/segment-resolution/helpers.ts +63 -24
- package/src/router/segment-resolution/loader-cache.ts +41 -37
- package/src/router/segment-resolution/revalidation.ts +456 -372
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +4 -1
- package/src/router/segment-wrappers.ts +2 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +134 -43
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -383
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +30 -3
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +56 -54
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -67
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +25 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +272 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +309 -61
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +338 -126
- package/src/ssr/index.tsx +23 -15
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +233 -81
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +37 -14
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +192 -99
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +51 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +187 -69
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/plugins/expose-action-id.ts +49 -98
- package/src/vite/plugins/expose-id-utils.ts +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +41 -20
- package/src/vite/plugins/virtual-entries.ts +2 -17
- package/src/vite/rango.ts +257 -289
- package/src/vite/router-discovery.ts +930 -140
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +27 -29
- package/src/vite/utils/shared-utils.ts +92 -42
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { Handle } from "../handle.js";
|
|
3
|
+
import type { HandlePush } from "../defer.js";
|
|
3
4
|
import type { ContextVar } from "../context-var.js";
|
|
4
5
|
import type { MiddlewareFn } from "../router/middleware.js";
|
|
5
6
|
import type { Theme } from "../theme/types.js";
|
|
@@ -19,6 +20,8 @@ import type {
|
|
|
19
20
|
ResolvedRouteMap,
|
|
20
21
|
} from "./route-config.js";
|
|
21
22
|
import type { LoaderDefinition } from "./loader-types.js";
|
|
23
|
+
import type { UseItems, HandlerUseItem } from "../route-types.js";
|
|
24
|
+
import type { RequestScope } from "./request-scope.js";
|
|
22
25
|
|
|
23
26
|
// Re-export MiddlewareFn for internal/advanced use
|
|
24
27
|
export type { MiddlewareFn } from "../router/middleware.js";
|
|
@@ -41,7 +44,7 @@ export type { MiddlewareFn } from "../router/middleware.js";
|
|
|
41
44
|
*/
|
|
42
45
|
export type ScopedRouteMap<
|
|
43
46
|
TPrefix extends string,
|
|
44
|
-
TMap =
|
|
47
|
+
TMap = Rango.GeneratedRouteMap,
|
|
45
48
|
> = {
|
|
46
49
|
[K in keyof TMap as K extends `${TPrefix}.${infer Rest}`
|
|
47
50
|
? Rest
|
|
@@ -105,14 +108,6 @@ type StrictLocalParamsWithExtras<TEntry> =
|
|
|
105
108
|
? Record<string, string>
|
|
106
109
|
: ExtractParamsFromEntry<TEntry, {}> & Record<string, string>;
|
|
107
110
|
|
|
108
|
-
// HandlerContext.reverse is the only reverse surface with runtime param autofill
|
|
109
|
-
// from the current matched request. Middleware/loaders/request context do not
|
|
110
|
-
// have the same local-route guarantees, so they keep plain ScopedReverseFunction.
|
|
111
|
-
//
|
|
112
|
-
// When a handler has an explicit local route map, enforce that local route
|
|
113
|
-
// params declared by that map are present while still allowing extra mount
|
|
114
|
-
// params to be passed through. Global names remain autofill-friendly because
|
|
115
|
-
// parent include() params are often unknown at the module definition site.
|
|
116
111
|
type StrictLocalAutofillGlobalReverseFunction<TLocalRoutes, TGlobalRoutes> =
|
|
117
112
|
ScopedReverseFunction<TLocalRoutes, TGlobalRoutes> & {
|
|
118
113
|
<TName extends keyof TGlobalRoutes & string>(
|
|
@@ -135,7 +130,7 @@ export type Handler<
|
|
|
135
130
|
| Record<string, any> = {},
|
|
136
131
|
TRouteMap extends {} = DefaultHandlerRouteMap,
|
|
137
132
|
TEnv = DefaultEnv,
|
|
138
|
-
> = (
|
|
133
|
+
> = ((
|
|
139
134
|
ctx: HandlerContext<
|
|
140
135
|
T extends `.${infer Local}`
|
|
141
136
|
? Local extends keyof TRouteMap
|
|
@@ -160,7 +155,10 @@ export type Handler<
|
|
|
160
155
|
: ExtractSearchFromEntry<DefaultHandlerRouteMap, T>,
|
|
161
156
|
TRouteMap extends DefaultHandlerRouteMap ? never : TRouteMap
|
|
162
157
|
>,
|
|
163
|
-
) => ReactNode | Promise<ReactNode> | Response | Promise<Response
|
|
158
|
+
) => ReactNode | Promise<ReactNode> | Response | Promise<Response>) & {
|
|
159
|
+
/** Composable default DSL items merged when the handler is mounted. */
|
|
160
|
+
use?: () => UseItems<HandlerUseItem>;
|
|
161
|
+
};
|
|
164
162
|
|
|
165
163
|
/**
|
|
166
164
|
* Context passed to handlers (Hono-inspired type-safe context)
|
|
@@ -170,7 +168,7 @@ export type Handler<
|
|
|
170
168
|
* - Cleaned route URL (`url`, `searchParams`, `pathname` — no `_rsc*` params)
|
|
171
169
|
* - Original request (`request` — raw transport URL, headers, method, body)
|
|
172
170
|
* - Platform bindings (env.DB, env.KV, env.SECRETS)
|
|
173
|
-
* - Middleware variables (
|
|
171
|
+
* - Middleware variables (`get("user")`, `get("permissions")`)
|
|
174
172
|
* - Getter/setter for variables (get('user'), set('user', ...))
|
|
175
173
|
*
|
|
176
174
|
* @example
|
|
@@ -178,8 +176,7 @@ export type Handler<
|
|
|
178
176
|
* const handler = (ctx: HandlerContext<{ slug: string }, AppEnv>) => {
|
|
179
177
|
* ctx.params.slug // Route param (string)
|
|
180
178
|
* ctx.env.DB // Binding (D1Database)
|
|
181
|
-
* ctx.
|
|
182
|
-
* ctx.get('user') // Alternative getter
|
|
179
|
+
* ctx.get('user') // Variable (User | undefined)
|
|
183
180
|
* ctx.set('user', {...}) // Setter
|
|
184
181
|
* ctx.url // Clean URL (no _rsc* params)
|
|
185
182
|
* ctx.searchParams // Clean params (no _rsc* params)
|
|
@@ -192,7 +189,7 @@ export type HandlerContext<
|
|
|
192
189
|
TEnv = DefaultEnv,
|
|
193
190
|
TSearch extends SearchSchema = {},
|
|
194
191
|
TRouteMap = never,
|
|
195
|
-
> = {
|
|
192
|
+
> = RequestScope<TEnv> & {
|
|
196
193
|
/**
|
|
197
194
|
* Route parameters extracted from the URL pattern.
|
|
198
195
|
* Type-safe when using Handler<"/path/:param"> or Handler<{ param: string }>.
|
|
@@ -207,51 +204,19 @@ export type HandlerContext<
|
|
|
207
204
|
*/
|
|
208
205
|
build: boolean;
|
|
209
206
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* for cases where you need original headers, method, or body.
|
|
207
|
+
* True when running in Vite dev mode, false during production build or
|
|
208
|
+
* live request rendering. Use this to branch on runtime mode without
|
|
209
|
+
* changing build semantics (e.g., skip expensive operations in dev).
|
|
214
210
|
*/
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Query parameters from the URL (system params like `_rsc*` are filtered).
|
|
218
|
-
* Always a standard URLSearchParams instance.
|
|
219
|
-
*/
|
|
220
|
-
searchParams: URLSearchParams;
|
|
211
|
+
dev: boolean;
|
|
221
212
|
/**
|
|
222
213
|
* Typed search parameters parsed from URL query string via the route's
|
|
223
214
|
* search schema. Empty object when no schema is defined.
|
|
224
215
|
*/
|
|
225
216
|
search: {} extends TSearch ? {} : ResolveSearchSchema<TSearch>;
|
|
226
|
-
/**
|
|
227
|
-
* The pathname portion of the request URL.
|
|
228
|
-
*/
|
|
229
|
-
pathname: string;
|
|
230
|
-
/**
|
|
231
|
-
* The full URL object (with internal `_rsc*` params stripped).
|
|
232
|
-
* Use this for application logic — routing, link generation, display.
|
|
233
|
-
*/
|
|
234
|
-
url: URL;
|
|
235
|
-
/**
|
|
236
|
-
* The original request URL with all parameters intact, including
|
|
237
|
-
* internal `_rsc*` transport params. Use `ctx.url` for application
|
|
238
|
-
* logic — this is only needed for advanced cases like debugging
|
|
239
|
-
* or custom cache keying.
|
|
240
|
-
*/
|
|
241
|
-
originalUrl: URL;
|
|
242
|
-
/**
|
|
243
|
-
* Platform bindings (DB, KV, secrets, etc.).
|
|
244
|
-
* Access resources like `ctx.env.DB`, `ctx.env.KV`.
|
|
245
|
-
*/
|
|
246
|
-
env: TEnv;
|
|
247
|
-
/**
|
|
248
|
-
* Middleware-injected variables.
|
|
249
|
-
* Access values like `ctx.var.user`, `ctx.var.permissions`.
|
|
250
|
-
*/
|
|
251
|
-
var: DefaultVars;
|
|
252
217
|
/**
|
|
253
218
|
* Type-safe getter for middleware variables.
|
|
254
|
-
*
|
|
219
|
+
* Preferred way to read middleware-injected variables.
|
|
255
220
|
*
|
|
256
221
|
* @example
|
|
257
222
|
* ```typescript
|
|
@@ -272,8 +237,16 @@ export type HandlerContext<
|
|
|
272
237
|
* ```
|
|
273
238
|
*/
|
|
274
239
|
set: {
|
|
275
|
-
<T>(
|
|
276
|
-
|
|
240
|
+
<T>(
|
|
241
|
+
contextVar: ContextVar<T>,
|
|
242
|
+
value: T,
|
|
243
|
+
options?: { cache?: boolean },
|
|
244
|
+
): void;
|
|
245
|
+
} & (<K extends keyof DefaultVars>(
|
|
246
|
+
key: K,
|
|
247
|
+
value: DefaultVars[K],
|
|
248
|
+
options?: { cache?: boolean },
|
|
249
|
+
) => void);
|
|
277
250
|
/**
|
|
278
251
|
* Response headers. Headers set here are merged into the final response.
|
|
279
252
|
*
|
|
@@ -289,19 +262,29 @@ export type HandlerContext<
|
|
|
289
262
|
/**
|
|
290
263
|
* Access loader data or push handle data.
|
|
291
264
|
*
|
|
265
|
+
* Available in route handlers, layout handlers, middleware, server actions,
|
|
266
|
+
* and server components rendered within the request context.
|
|
267
|
+
*
|
|
292
268
|
* For loaders: Returns a promise that resolves to the loader data.
|
|
293
269
|
* Loaders are executed in parallel and memoized per request.
|
|
270
|
+
* Prefer DSL `loader()` + client `useLoader()` over `ctx.use(Loader)` —
|
|
271
|
+
* DSL loaders are always fresh and cache-safe. Use `ctx.use(Loader)` only
|
|
272
|
+
* when you need loader data in the handler itself (e.g., to set context
|
|
273
|
+
* variables or make routing decisions).
|
|
294
274
|
*
|
|
295
275
|
* For handles: Returns a push function to add data for this segment.
|
|
296
276
|
* Handle data accumulates across all matched route segments.
|
|
297
277
|
* Push accepts: direct value, Promise, or async callback (executed immediately).
|
|
278
|
+
* Or call `.defer()` to reserve the slot now and resolve it later (e.g. from a
|
|
279
|
+
* deep async component), with a timeout safety net — see {@link HandlePush}.
|
|
298
280
|
*
|
|
299
281
|
* @example
|
|
300
282
|
* ```typescript
|
|
301
|
-
* // Loader
|
|
302
|
-
* route("
|
|
303
|
-
* const
|
|
304
|
-
*
|
|
283
|
+
* // Loader escape hatch — use when handler needs the data directly
|
|
284
|
+
* route("product", async (ctx) => {
|
|
285
|
+
* const { product } = await ctx.use(ProductLoader);
|
|
286
|
+
* ctx.set(Product, product); // make available to children
|
|
287
|
+
* return <ProductPage />;
|
|
305
288
|
* });
|
|
306
289
|
*
|
|
307
290
|
* // Handle usage - direct value
|
|
@@ -327,6 +310,13 @@ export type HandlerContext<
|
|
|
327
310
|
* });
|
|
328
311
|
* return <ProductPage />;
|
|
329
312
|
* });
|
|
313
|
+
*
|
|
314
|
+
* // Handle usage - deferred (reserve the slot now, resolve from a deep component)
|
|
315
|
+
* route("product", (ctx) => {
|
|
316
|
+
* const resolve = ctx.use(Breadcrumbs).defer({ timeoutMs: 5000, else: null });
|
|
317
|
+
* loadCrumb(ctx.params.id).then(resolve); // resolver is push-equal
|
|
318
|
+
* return <ProductPage />; // auto-resolves to `else` on timeout
|
|
319
|
+
* });
|
|
330
320
|
* ```
|
|
331
321
|
*/
|
|
332
322
|
use: {
|
|
@@ -335,7 +325,7 @@ export type HandlerContext<
|
|
|
335
325
|
): Promise<T>;
|
|
336
326
|
<TData, TAccumulated = TData[]>(
|
|
337
327
|
handle: Handle<TData, TAccumulated>,
|
|
338
|
-
):
|
|
328
|
+
): HandlePush<TData>;
|
|
339
329
|
};
|
|
340
330
|
/**
|
|
341
331
|
* Current theme (from cookie or default).
|
|
@@ -432,6 +422,8 @@ export type InternalHandlerContext<
|
|
|
432
422
|
> = HandlerContext<TParams, TEnv, TSearch> & {
|
|
433
423
|
/** @internal Stub response for collecting headers/cookies. */
|
|
434
424
|
res: Response;
|
|
425
|
+
/** @internal Shared variable backing store for ctx.get()/ctx.set(). */
|
|
426
|
+
_variables: Record<string, any>;
|
|
435
427
|
/** Prerender-only control flow helper, attached when the runtime context supports it. */
|
|
436
428
|
passthrough?: () => unknown;
|
|
437
429
|
/** Current segment ID for handle data attribution. */
|
|
@@ -440,6 +432,18 @@ export type InternalHandlerContext<
|
|
|
440
432
|
_responseType?: string;
|
|
441
433
|
/** Route name for cache key scoping (prevents cross-route collisions). */
|
|
442
434
|
_routeName?: string;
|
|
435
|
+
/**
|
|
436
|
+
* @internal Loader-cache override table: loaderId -> memoized data promise.
|
|
437
|
+
* A single stable ctx.use interceptor consults this instead of chaining one
|
|
438
|
+
* wrapper per cached loader (avoids O(N) dispatch). See loader-cache.ts.
|
|
439
|
+
*/
|
|
440
|
+
_loaderCacheOverrides?: Map<string, Promise<any>>;
|
|
441
|
+
/**
|
|
442
|
+
* @internal ctx.use captured before the loader-cache interceptor was installed.
|
|
443
|
+
* The cache-miss execute runs the loader through this, bypassing the override
|
|
444
|
+
* table (so a loader cannot await its own in-flight memoized promise).
|
|
445
|
+
*/
|
|
446
|
+
_loaderCacheOriginalUse?: (item: any) => any;
|
|
443
447
|
};
|
|
444
448
|
|
|
445
449
|
/**
|
|
@@ -481,13 +485,16 @@ export type RevalidateParams<TParams = GenericParams, TEnv = any> = Parameters<
|
|
|
481
485
|
* **Return Types:**
|
|
482
486
|
* - `boolean` - Hard decision: immediately returns this value (short-circuits)
|
|
483
487
|
* - `{ defaultShouldRevalidate: boolean }` - Soft decision: updates suggestion for next revalidator
|
|
488
|
+
* - `void` / `null` / `undefined` - Defer to the current suggestion (no opinion); the
|
|
489
|
+
* loop continues to the next revalidator without changing the running default
|
|
484
490
|
*
|
|
485
491
|
* **Execution Flow:**
|
|
486
492
|
* 1. Start with built-in `defaultShouldRevalidate` (true if params changed)
|
|
487
493
|
* 2. Execute global revalidators first, then route-specific
|
|
488
494
|
* 3. Hard decision (boolean): stop immediately and use that value
|
|
489
495
|
* 4. Soft decision (object): update suggestion and continue to next revalidator
|
|
490
|
-
* 5.
|
|
496
|
+
* 5. Defer (`void` / `null` / `undefined`): leave suggestion unchanged and continue
|
|
497
|
+
* 6. If no hard decision was returned: use the final running suggestion
|
|
491
498
|
*
|
|
492
499
|
* @param args.currentParams - Previous route params (generic by default, can be narrowed)
|
|
493
500
|
* @param args.currentUrl - Previous URL
|
|
@@ -499,7 +506,8 @@ export type RevalidateParams<TParams = GenericParams, TEnv = any> = Parameters<
|
|
|
499
506
|
* @param args.formData - Form data from action (future support)
|
|
500
507
|
* @param args.formMethod - HTTP method from action (future support)
|
|
501
508
|
*
|
|
502
|
-
* @returns Hard decision (boolean)
|
|
509
|
+
* @returns Hard decision (boolean), soft suggestion (object), or defer
|
|
510
|
+
* (`void` / `null` / `undefined`) to keep the running suggestion as-is.
|
|
503
511
|
*
|
|
504
512
|
* @example
|
|
505
513
|
* ```typescript
|
|
@@ -519,31 +527,175 @@ export type RevalidateParams<TParams = GenericParams, TEnv = any> = Parameters<
|
|
|
519
527
|
* })
|
|
520
528
|
* ```
|
|
521
529
|
*/
|
|
530
|
+
/**
|
|
531
|
+
* A reference to a server action, used by `isAction()` in a revalidate predicate.
|
|
532
|
+
*
|
|
533
|
+
* Either a directly imported action (`import { addToCart }`) or a namespace
|
|
534
|
+
* import of an action module (`import * as CartActions`). Matching resolves the
|
|
535
|
+
* action's build-injected id (`path#export`) — the same identity the router uses
|
|
536
|
+
* for `actionId` — so a renamed or moved action breaks at compile time instead
|
|
537
|
+
* of silently failing to match.
|
|
538
|
+
*/
|
|
539
|
+
export type ActionRef =
|
|
540
|
+
| ((...args: never[]) => unknown)
|
|
541
|
+
| Record<string, unknown>;
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Revalidation function called during client-side navigation to decide whether
|
|
545
|
+
* a segment (layout, route, parallel slot, or loader) should be re-rendered.
|
|
546
|
+
*
|
|
547
|
+
* Return `true` to re-render, `false` to skip (keep client's current version),
|
|
548
|
+
* `{ defaultShouldRevalidate: boolean }` to update the running suggestion for
|
|
549
|
+
* downstream revalidators, or nothing (`void` / `null` / `undefined`) to defer
|
|
550
|
+
* to the current suggestion without changing it.
|
|
551
|
+
*
|
|
552
|
+
* Two idioms cover almost every case; they differ only in what an _unrelated_
|
|
553
|
+
* action does. Match actions by reference with `ctx.isAction()` (rename-safe)
|
|
554
|
+
* rather than `actionId?.includes("...")` (a renamed or moved action silently
|
|
555
|
+
* stops matching). Because `isAction` returns a raw boolean, combine it with
|
|
556
|
+
* `|| undefined` to defer or leave it bare to suppress.
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```ts
|
|
560
|
+
* import * as CartActions from "./actions/cart";
|
|
561
|
+
*
|
|
562
|
+
* // Idiom A — "mine, else defer": re-render on my actions, otherwise return
|
|
563
|
+
* // undefined so the segment's default decision still applies (and downstream
|
|
564
|
+
* // revalidators get a say).
|
|
565
|
+
* revalidate((ctx) => ctx.isAction(CartActions) || undefined)
|
|
566
|
+
*
|
|
567
|
+
* // Idiom B — "mine only": re-render on my actions and suppress everything
|
|
568
|
+
* // else (isAction returns a raw boolean, so an unrelated action yields false).
|
|
569
|
+
* revalidate((ctx) => ctx.isAction(CartActions))
|
|
570
|
+
*
|
|
571
|
+
* // Always re-render when params change (default behavior made explicit)
|
|
572
|
+
* revalidate(({ defaultShouldRevalidate }) => defaultShouldRevalidate)
|
|
573
|
+
* ```
|
|
574
|
+
*/
|
|
522
575
|
export type ShouldRevalidateFn<TParams = GenericParams, TEnv = any> = (args: {
|
|
576
|
+
/** Route params from the page being navigated away from. */
|
|
523
577
|
currentParams: TParams;
|
|
578
|
+
/** Full URL of the page being navigated away from. */
|
|
524
579
|
currentUrl: URL;
|
|
580
|
+
/** Route params for the navigation target. */
|
|
525
581
|
nextParams: TParams;
|
|
582
|
+
/** Full URL of the navigation target. */
|
|
526
583
|
nextUrl: URL;
|
|
584
|
+
/**
|
|
585
|
+
* The router's default revalidation decision for this segment.
|
|
586
|
+
* `true` when params changed or the segment is new to the client.
|
|
587
|
+
* Return this when you want default behavior plus your own conditions.
|
|
588
|
+
*/
|
|
527
589
|
defaultShouldRevalidate: boolean;
|
|
590
|
+
/** Full handler context — access to `ctx.use()`, `ctx.env`, `ctx.params`, etc. */
|
|
528
591
|
context: HandlerContext<TParams, TEnv>;
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
592
|
+
|
|
593
|
+
// ── Segment metadata (which segment is being evaluated) ──────────────
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* The type of segment being revalidated. `"loader"` is passed to revalidate
|
|
597
|
+
* functions attached to a `loader(Fn, () => [revalidate(...)])` registration.
|
|
598
|
+
*/
|
|
599
|
+
segmentType: "layout" | "route" | "parallel" | "loader";
|
|
600
|
+
/** Layout name (e.g., `"root"`, `"shop"`, `"auth"`). Only set for layout segments. */
|
|
601
|
+
layoutName?: string;
|
|
602
|
+
/** Slot name (e.g., `"@sidebar"`, `"@modal"`). Only set for parallel segments. */
|
|
603
|
+
slotName?: string;
|
|
604
|
+
|
|
605
|
+
// ── Action context (populated when revalidation is triggered by a server action) ──
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Identifier of the server action that triggered revalidation.
|
|
609
|
+
* `undefined` during normal navigation (no action involved).
|
|
610
|
+
*
|
|
611
|
+
* Format: `"src/<path>#<exportName>"` — the file path is the source path
|
|
612
|
+
* relative to the project root, followed by `#` and the exported function name.
|
|
613
|
+
*
|
|
614
|
+
* This is stable and can be used for path-based matching to revalidate
|
|
615
|
+
* when any action in a module or directory fires. Prefer `|| undefined`
|
|
616
|
+
* (defer to the segment default / downstream revalidators) over `?? false`
|
|
617
|
+
* (hard short-circuit that suppresses the default and ends the chain):
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```ts
|
|
621
|
+
* // Match a specific action
|
|
622
|
+
* revalidate(({ actionId }) => actionId === "src/actions/cart.ts#addToCart" || undefined)
|
|
623
|
+
*
|
|
624
|
+
* // Match any action in the cart module
|
|
625
|
+
* revalidate(({ actionId }) => actionId?.includes("cart") || undefined)
|
|
626
|
+
*
|
|
627
|
+
* // Match any action under src/apps/store/actions/
|
|
628
|
+
* revalidate(({ actionId }) => actionId?.startsWith("src/apps/store/actions/") || undefined)
|
|
629
|
+
* ```
|
|
630
|
+
*/
|
|
631
|
+
actionId?: string;
|
|
632
|
+
/**
|
|
633
|
+
* Typed, rename-safe action matching. Returns `true` when the action that
|
|
634
|
+
* triggered this revalidation is one of the given references — or, for a
|
|
635
|
+
* namespace import (`import * as CartActions`), any export of that module —
|
|
636
|
+
* and `false` otherwise (including plain navigation with no action).
|
|
637
|
+
*
|
|
638
|
+
* Called with NO arguments it answers "is this request an action at all?":
|
|
639
|
+
* `true` for any action, `false` on plain navigation. Use the bare form when
|
|
640
|
+
* you want to revalidate on every action regardless of which one fired.
|
|
641
|
+
*
|
|
642
|
+
* Prefer this over hand-written `actionId` substring matches: it resolves the
|
|
643
|
+
* action's stable `path#export` id from the imported reference, so a rename is
|
|
644
|
+
* a type error in one place instead of silent drift across consumers. It
|
|
645
|
+
* resolves the reference the same way the action boundary derives `actionId`
|
|
646
|
+
* (`$id ?? $$id`), so it matches in both dev and production.
|
|
647
|
+
*
|
|
648
|
+
* Returns a raw boolean, so for the common "revalidate on match, else defer"
|
|
649
|
+
* intent combine with `|| undefined`:
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* ```ts
|
|
653
|
+
* import { addToCart, removeFromCart } from "./actions/cart";
|
|
654
|
+
* import * as CartActions from "./actions/cart";
|
|
655
|
+
*
|
|
656
|
+
* revalidate((ctx) => ctx.isAction() || undefined); // any action
|
|
657
|
+
* revalidate((ctx) => ctx.isAction(addToCart) || undefined); // one action
|
|
658
|
+
* revalidate((ctx) => ctx.isAction(addToCart, removeFromCart) || undefined); // several
|
|
659
|
+
* revalidate((ctx) => ctx.isAction(CartActions) || undefined); // any in the module
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
isAction: (...actions: ActionRef[]) => boolean;
|
|
663
|
+
/** URL where the action was executed (the page the user was on when they triggered the action). */
|
|
664
|
+
actionUrl?: URL;
|
|
665
|
+
/** Return value from the action execution. Can be used to conditionally revalidate based on the action's outcome. */
|
|
666
|
+
actionResult?: any;
|
|
667
|
+
/** FormData from the action request body. Only set for form-based actions (not inline `"use server"` actions). */
|
|
668
|
+
formData?: FormData;
|
|
669
|
+
/** HTTP method: `"GET"` for navigation, `"POST"` for server actions. */
|
|
670
|
+
method?: string;
|
|
671
|
+
|
|
672
|
+
// ── Route identity ───────────────────────────────────────────────────
|
|
673
|
+
|
|
674
|
+
/** Route name of the navigation target. Alias for `toRouteName`. */
|
|
675
|
+
routeName?: DefaultRouteName;
|
|
676
|
+
/**
|
|
677
|
+
* Route name being navigated away from.
|
|
678
|
+
* `undefined` for unnamed internal routes (those without a `name` option).
|
|
679
|
+
*/
|
|
680
|
+
fromRouteName?: DefaultRouteName;
|
|
681
|
+
/**
|
|
682
|
+
* Route name being navigated to.
|
|
683
|
+
* `undefined` for unnamed internal routes (those without a `name` option).
|
|
684
|
+
*/
|
|
685
|
+
toRouteName?: DefaultRouteName;
|
|
686
|
+
|
|
687
|
+
// ── Staleness signal ─────────────────────────────────────────────────
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* `true` when the browser signals that data may be stale — typically because
|
|
691
|
+
* a server action was executed in this or another tab (`_rsc_stale` header).
|
|
692
|
+
*
|
|
693
|
+
* This is NOT segment cache staleness (loaders are never segment-cached).
|
|
694
|
+
* Use this to decide whether loader data should be re-fetched after an
|
|
695
|
+
* action that may have mutated backend state.
|
|
696
|
+
*/
|
|
697
|
+
stale?: boolean;
|
|
698
|
+
}) => boolean | { defaultShouldRevalidate: boolean } | null | void;
|
|
547
699
|
|
|
548
700
|
// MiddlewareFn is imported from "../router/middleware.js" and re-exported
|
|
549
701
|
|
|
@@ -648,7 +800,7 @@ export type Revalidate<
|
|
|
648
800
|
* Middleware function with typed params and environment
|
|
649
801
|
*
|
|
650
802
|
* @template TParams - Params object (defaults to generic)
|
|
651
|
-
* @template TEnv - Environment type (defaults to global
|
|
803
|
+
* @template TEnv - Environment type (defaults to global Rango.Env)
|
|
652
804
|
*
|
|
653
805
|
* Note: Middleware cannot directly use route names for params typing because
|
|
654
806
|
* middleware is defined during router setup, before RegisteredRoutes is populated.
|
|
@@ -656,7 +808,7 @@ export type Revalidate<
|
|
|
656
808
|
*
|
|
657
809
|
* @example
|
|
658
810
|
* ```typescript
|
|
659
|
-
* // Basic middleware (uses global
|
|
811
|
+
* // Basic middleware (uses global Rango.Env via module augmentation)
|
|
660
812
|
* const middleware: Middleware = async (ctx, next) => {
|
|
661
813
|
* ctx.set("user", { id: "123" }); // Type-safe!
|
|
662
814
|
* await next();
|
package/src/types/index.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
// Global namespace (must be imported for side effects: `declare global`)
|
|
2
1
|
export type {
|
|
3
2
|
GetRegisteredRoutes,
|
|
4
3
|
DefaultHandlerRouteMap,
|
|
5
4
|
DefaultReverseRouteMap,
|
|
6
5
|
DefaultEnv,
|
|
7
6
|
} from "./global-namespace.js";
|
|
8
|
-
// Ensure the global namespace declaration is evaluated
|
|
9
7
|
import "./global-namespace.js";
|
|
10
8
|
|
|
11
|
-
// Route configuration
|
|
12
9
|
export type {
|
|
13
10
|
DocumentProps,
|
|
14
11
|
ExtractParams,
|
|
@@ -19,7 +16,6 @@ export type {
|
|
|
19
16
|
ResolvedRouteMap,
|
|
20
17
|
} from "./route-config.js";
|
|
21
18
|
|
|
22
|
-
// Boundaries (error/notFound)
|
|
23
19
|
export type {
|
|
24
20
|
ErrorInfo,
|
|
25
21
|
ErrorBoundaryFallbackProps,
|
|
@@ -32,7 +28,6 @@ export type {
|
|
|
32
28
|
} from "./boundaries.js";
|
|
33
29
|
export { isLoaderDataResult } from "./boundaries.js";
|
|
34
30
|
|
|
35
|
-
// Handler context and related types
|
|
36
31
|
export type {
|
|
37
32
|
MiddlewareFn,
|
|
38
33
|
ScopedRouteMap,
|
|
@@ -42,6 +37,7 @@ export type {
|
|
|
42
37
|
GenericParams,
|
|
43
38
|
RevalidateParams,
|
|
44
39
|
ShouldRevalidateFn,
|
|
40
|
+
ActionRef,
|
|
45
41
|
RouteKeys,
|
|
46
42
|
ExtractRouteParams,
|
|
47
43
|
HandlersForRouteMap,
|
|
@@ -49,7 +45,6 @@ export type {
|
|
|
49
45
|
Middleware,
|
|
50
46
|
} from "./handler-context.js";
|
|
51
47
|
|
|
52
|
-
// Segments
|
|
53
48
|
export type {
|
|
54
49
|
ViewTransitionClass,
|
|
55
50
|
TransitionConfig,
|
|
@@ -60,10 +55,8 @@ export type {
|
|
|
60
55
|
MatchResult,
|
|
61
56
|
} from "./segments.js";
|
|
62
57
|
|
|
63
|
-
// Route entries
|
|
64
58
|
export type { LazyIncludeContext, RouteEntry } from "./route-entry.js";
|
|
65
59
|
|
|
66
|
-
// Loader types
|
|
67
60
|
export type {
|
|
68
61
|
LoaderContext,
|
|
69
62
|
LoaderFn,
|
|
@@ -72,7 +65,6 @@ export type {
|
|
|
72
65
|
LoaderDefinition,
|
|
73
66
|
} from "./loader-types.js";
|
|
74
67
|
|
|
75
|
-
// Cache types
|
|
76
68
|
export type {
|
|
77
69
|
CacheContext,
|
|
78
70
|
CacheOptions,
|
|
@@ -80,7 +72,6 @@ export type {
|
|
|
80
72
|
EntryCacheConfig,
|
|
81
73
|
} from "./cache-types.js";
|
|
82
74
|
|
|
83
|
-
// Error handling types
|
|
84
75
|
export type {
|
|
85
76
|
ErrorPhase,
|
|
86
77
|
OnErrorContext,
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { ContextVar } from "../context-var.js";
|
|
2
|
+
import type { Handle } from "../handle.js";
|
|
2
3
|
import type { MiddlewareFn } from "../router/middleware.js";
|
|
3
4
|
import type { ScopedReverseFunction } from "../reverse.js";
|
|
4
5
|
import type { SearchSchema, ResolveSearchSchema } from "../search-params.js";
|
|
6
|
+
import type { UseItems, LoaderUseItem } from "../route-types.js";
|
|
5
7
|
import type {
|
|
6
8
|
DefaultEnv,
|
|
7
9
|
DefaultReverseRouteMap,
|
|
8
10
|
DefaultVars,
|
|
9
11
|
} from "./global-namespace.js";
|
|
12
|
+
import type { RequestScope } from "./request-scope.js";
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Context passed to loader functions during execution
|
|
@@ -38,7 +41,7 @@ export type LoaderContext<
|
|
|
38
41
|
TEnv = DefaultEnv,
|
|
39
42
|
TBody = unknown,
|
|
40
43
|
TSearch extends SearchSchema = {},
|
|
41
|
-
> = {
|
|
44
|
+
> = RequestScope<TEnv> & {
|
|
42
45
|
params: TParams;
|
|
43
46
|
/**
|
|
44
47
|
* Route params extracted from the URL pattern match (server-side only).
|
|
@@ -47,22 +50,46 @@ export type LoaderContext<
|
|
|
47
50
|
* resource scoping.
|
|
48
51
|
*/
|
|
49
52
|
routeParams: Record<string, string>;
|
|
50
|
-
request: Request;
|
|
51
|
-
searchParams: URLSearchParams;
|
|
52
53
|
search: {} extends TSearch ? {} : ResolveSearchSchema<TSearch>;
|
|
53
|
-
pathname: string;
|
|
54
|
-
url: URL;
|
|
55
|
-
env: TEnv;
|
|
56
|
-
var: DefaultVars;
|
|
57
54
|
get: {
|
|
58
55
|
<T>(contextVar: ContextVar<T>): T | undefined;
|
|
59
56
|
} & (<K extends keyof DefaultVars>(key: K) => DefaultVars[K]);
|
|
60
57
|
/**
|
|
61
|
-
* Access another loader's data
|
|
58
|
+
* Access another loader's data, or read handle data after rendered().
|
|
59
|
+
*
|
|
60
|
+
* For loaders: returns a promise (loaders run in parallel).
|
|
61
|
+
* For handles: returns collected data (only after `await ctx.rendered()`).
|
|
62
|
+
*/
|
|
63
|
+
use: {
|
|
64
|
+
<T, TLoaderParams = any>(
|
|
65
|
+
loader: LoaderDefinition<T, TLoaderParams>,
|
|
66
|
+
): Promise<T>;
|
|
67
|
+
<TData, TAccumulated = TData[]>(
|
|
68
|
+
handle: Handle<TData, TAccumulated>,
|
|
69
|
+
): TAccumulated;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* **Experimental.** Wait for all non-loader segments to settle.
|
|
73
|
+
*
|
|
74
|
+
* After the returned promise resolves, handle data is available via
|
|
75
|
+
* `ctx.use(handle)`. Supported in DSL loaders, including on streaming
|
|
76
|
+
* trees that use `loading()` — the barrier waits for the streaming
|
|
77
|
+
* handlers to finish pushing before it resolves. Throws if called from a
|
|
78
|
+
* handler-invoked loader, or if a handler is already awaiting this loader
|
|
79
|
+
* via `ctx.use()` (that would deadlock — use a loader-to-loader
|
|
80
|
+
* dependency instead).
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const PricesLoader = createLoader(async (ctx) => {
|
|
85
|
+
* "use server";
|
|
86
|
+
* await ctx.rendered();
|
|
87
|
+
* const products = ctx.use(Products); // reads handle data
|
|
88
|
+
* return pricing.getLive(products.map(p => p.id));
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
62
91
|
*/
|
|
63
|
-
|
|
64
|
-
loader: LoaderDefinition<T, TLoaderParams>,
|
|
65
|
-
) => Promise<T>;
|
|
92
|
+
rendered: () => Promise<void>;
|
|
66
93
|
/**
|
|
67
94
|
* HTTP method (GET, POST, PUT, PATCH, DELETE)
|
|
68
95
|
* Available when loader is called via load({ method: "POST", ... })
|
|
@@ -166,11 +193,11 @@ export type LoadOptions =
|
|
|
166
193
|
* return await db.products.findBySlug(slug);
|
|
167
194
|
* });
|
|
168
195
|
*
|
|
169
|
-
* //
|
|
170
|
-
* const
|
|
196
|
+
* // Client usage (preferred — cache-safe, always fresh)
|
|
197
|
+
* const { data } = useLoader(CartLoader);
|
|
171
198
|
*
|
|
172
|
-
* //
|
|
173
|
-
* const cart =
|
|
199
|
+
* // Server escape hatch (handler needs data directly)
|
|
200
|
+
* const cart = await ctx.use(CartLoader);
|
|
174
201
|
* ```
|
|
175
202
|
*/
|
|
176
203
|
export type LoaderDefinition<
|
|
@@ -180,4 +207,6 @@ export type LoaderDefinition<
|
|
|
180
207
|
__brand: "loader";
|
|
181
208
|
$$id: string; // Injected by Vite plugin (exposeInternalIds) - unique identifier
|
|
182
209
|
fn?: LoaderFn<T, TParams, any>; // Optional - server-side only, stored in registry for RSC
|
|
210
|
+
/** Composable default DSL items merged when the loader is mounted. */
|
|
211
|
+
use?: () => UseItems<LoaderUseItem>;
|
|
183
212
|
};
|