@rangojs/router 0.0.0-experimental.eb0645d3 → 0.0.0-experimental.f1468e3c
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 +8 -0
- package/README.md +126 -16
- package/dist/bin/rango.js +319 -95
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +2724 -1053
- package/package.json +68 -14
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +64 -2
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +224 -32
- package/skills/caching/SKILL.md +279 -17
- package/skills/composability/SKILL.md +27 -3
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +4 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +11 -9
- package/skills/hooks/SKILL.md +243 -29
- package/skills/host-router/SKILL.md +83 -23
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +68 -19
- package/skills/layout/SKILL.md +13 -9
- package/skills/links/SKILL.md +190 -23
- package/skills/loader/SKILL.md +235 -9
- package/skills/middleware/SKILL.md +18 -10
- package/skills/migrate-nextjs/SKILL.md +43 -19
- package/skills/migrate-react-router/SKILL.md +8 -2
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +18 -7
- package/skills/prerender/SKILL.md +65 -60
- package/skills/rango/SKILL.md +251 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +115 -48
- package/skills/route/SKILL.md +46 -5
- package/skills/router-setup/SKILL.md +30 -8
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -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 +122 -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 +123 -0
- package/skills/typesafety/SKILL.md +322 -29
- package/skills/use-cache/SKILL.md +57 -14
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +0 -65
- 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/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +192 -150
- 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/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +121 -84
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +115 -67
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +147 -128
- package/src/browser/prefetch/cache.ts +107 -56
- package/src/browser/prefetch/fetch.ts +204 -34
- package/src/browser/prefetch/queue.ts +6 -3
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +30 -7
- package/src/browser/react/NavigationProvider.tsx +283 -118
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/deferred-handle-resolution.ts +75 -0
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -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 +17 -14
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +10 -5
- package/src/browser/react/use-params.ts +11 -11
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- 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 +99 -8
- package/src/browser/rsc-router.tsx +91 -24
- package/src/browser/scroll-restoration.ts +30 -17
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +214 -55
- package/src/browser/types.ts +80 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +60 -35
- package/src/build/generate-route-types.ts +2 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +117 -14
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +117 -23
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +55 -28
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +29 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +224 -41
- package/src/cache/cache-scope.ts +188 -82
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +1989 -378
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +89 -21
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +10 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +9 -17
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +37 -100
- package/src/client.rsc.tsx +44 -21
- package/src/client.tsx +36 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +31 -23
- package/src/handles/MetaTags.tsx +62 -19
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +37 -8
- package/src/handles/is-thenable.ts +19 -0
- package/src/handles/meta.ts +51 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +23 -52
- 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 +96 -12
- package/src/index.ts +94 -14
- package/src/internal-debug.ts +11 -10
- 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/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +61 -6
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +34 -0
- package/src/reverse.ts +65 -40
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +82 -55
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +0 -16
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +44 -23
- package/src/router/handler-context.ts +27 -43
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +10 -47
- package/src/router/loader-resolution.ts +155 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +18 -29
- package/src/router/match-api.ts +9 -24
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +44 -74
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +247 -166
- package/src/router/navigation-snapshot.ts +0 -51
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +85 -94
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prerender-match.ts +104 -65
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +28 -62
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +0 -1
- package/src/router/router-context.ts +3 -28
- package/src/router/router-interfaces.ts +83 -35
- package/src/router/router-options.ts +136 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +97 -84
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +76 -39
- package/src/router/segment-resolution/revalidation.ts +272 -320
- 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 +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +161 -199
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +162 -64
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +0 -5
- package/src/router.ts +110 -55
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +264 -220
- package/src/rsc/helpers.ts +100 -6
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +28 -41
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +117 -11
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +88 -188
- package/src/rsc/rsc-rendering.ts +98 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +281 -117
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +23 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +31 -4
- package/src/segment-system.tsx +254 -143
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +163 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +287 -178
- package/src/ssr/index.tsx +21 -16
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +701 -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 +257 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -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 +357 -0
- package/src/testing/render-route.tsx +581 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -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 +20 -58
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +9 -56
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +29 -12
- package/src/urls/path-helper.ts +17 -106
- package/src/urls/pattern-types.ts +36 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/discover-routers.ts +126 -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 +96 -68
- 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 +44 -0
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +2 -0
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +126 -8
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- 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-stub.ts +1 -21
- package/src/vite/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +39 -25
- package/src/vite/rango.ts +109 -118
- package/src/vite/router-discovery.ts +718 -119
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -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 +54 -39
- package/src/vite/utils/shared-utils.ts +90 -41
- 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/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
package/src/cache/types.ts
CHANGED
|
@@ -12,10 +12,6 @@
|
|
|
12
12
|
import type { ResolvedSegment } from "../types.js";
|
|
13
13
|
import type { RequestContext } from "../server/request-context.js";
|
|
14
14
|
|
|
15
|
-
// ============================================================================
|
|
16
|
-
// Segment Cache Store (low-level storage interface)
|
|
17
|
-
// ============================================================================
|
|
18
|
-
|
|
19
15
|
/**
|
|
20
16
|
* Result from cache get() including data and revalidation status
|
|
21
17
|
*/
|
|
@@ -116,12 +112,6 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
116
112
|
*/
|
|
117
113
|
clear?(): Promise<void>;
|
|
118
114
|
|
|
119
|
-
// ============================================================================
|
|
120
|
-
// Document Cache Methods (optional)
|
|
121
|
-
// ============================================================================
|
|
122
|
-
// These methods are for caching full HTTP responses (document-level caching).
|
|
123
|
-
// Stores that support response caching should implement these methods.
|
|
124
|
-
|
|
125
115
|
/**
|
|
126
116
|
* Get a cached Response by key.
|
|
127
117
|
* Returns the response and whether it should be revalidated (SWR).
|
|
@@ -136,20 +126,16 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
136
126
|
* @param response - Response to cache (will be cloned)
|
|
137
127
|
* @param ttl - Time-to-live in seconds
|
|
138
128
|
* @param swr - Optional stale-while-revalidate window in seconds
|
|
129
|
+
* @param tags - Optional cache tags for invalidation
|
|
139
130
|
*/
|
|
140
131
|
putResponse?(
|
|
141
132
|
key: string,
|
|
142
133
|
response: Response,
|
|
143
134
|
ttl: number,
|
|
144
135
|
swr?: number,
|
|
136
|
+
tags?: string[],
|
|
145
137
|
): Promise<void>;
|
|
146
138
|
|
|
147
|
-
// ============================================================================
|
|
148
|
-
// Function Cache Methods (optional, for "use cache" directive)
|
|
149
|
-
// ============================================================================
|
|
150
|
-
// These methods cache individual function/component return values.
|
|
151
|
-
// Stores that support "use cache" should implement these methods.
|
|
152
|
-
|
|
153
139
|
/**
|
|
154
140
|
* Get a cached function result by key.
|
|
155
141
|
* Returns the serialized value, optional handle data, and staleness flag.
|
|
@@ -167,6 +153,16 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
167
153
|
value: string,
|
|
168
154
|
options?: CacheItemOptions,
|
|
169
155
|
): Promise<void>;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Invalidate every cache entry (segment, response, item) tagged with any of
|
|
159
|
+
* `tags`. Store-level primitive that the public updateTag()/revalidateTag()
|
|
160
|
+
* APIs delegate to. Receives ALL of one invalidation call's tags at once so
|
|
161
|
+
* stores can batch their work (e.g. a single CDN purge request rather than
|
|
162
|
+
* one per tag). Stores that do not support tags simply omit this method.
|
|
163
|
+
* @param tags - The cache tags to invalidate
|
|
164
|
+
*/
|
|
165
|
+
invalidateTags?(tags: string[]): Promise<void>;
|
|
170
166
|
}
|
|
171
167
|
|
|
172
168
|
/**
|
|
@@ -175,18 +171,27 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
175
171
|
export interface CacheItemResult {
|
|
176
172
|
/** RSC-serialized return value */
|
|
177
173
|
value: string;
|
|
178
|
-
/**
|
|
179
|
-
|
|
174
|
+
/** RSC-encoded handle data captured during execution (breadcrumbs, metadata,
|
|
175
|
+
* etc.). Encoded via the Flight codec so Promise/ReactNode handle values
|
|
176
|
+
* survive JSON-serializing stores — see handle-snapshot.ts encodeHandles. */
|
|
177
|
+
handles?: string;
|
|
180
178
|
/** Whether the entry is stale and should be revalidated */
|
|
181
179
|
shouldRevalidate: boolean;
|
|
180
|
+
/**
|
|
181
|
+
* The entry's cache tags (including runtime cacheTag() tags), surfaced on read
|
|
182
|
+
* so a "use cache" HIT can still contribute its tags to the request-scoped tag
|
|
183
|
+
* set used by document-level caching. On a hit the cached function is not
|
|
184
|
+
* re-run, so its runtime tags are only available here, not from re-execution.
|
|
185
|
+
*/
|
|
186
|
+
tags?: string[];
|
|
182
187
|
}
|
|
183
188
|
|
|
184
189
|
/**
|
|
185
190
|
* Options for setItem() for function-level caching ("use cache").
|
|
186
191
|
*/
|
|
187
192
|
export interface CacheItemOptions {
|
|
188
|
-
/**
|
|
189
|
-
handles?:
|
|
193
|
+
/** RSC-encoded handle data to store alongside the value (see encodeHandles). */
|
|
194
|
+
handles?: string;
|
|
190
195
|
/** Time-to-live in seconds */
|
|
191
196
|
ttl?: number;
|
|
192
197
|
/** Stale-while-revalidate window in seconds */
|
|
@@ -227,16 +232,18 @@ export interface SerializedSegmentData {
|
|
|
227
232
|
export interface CachedEntryData {
|
|
228
233
|
/** Serialized segments for this entry */
|
|
229
234
|
segments: SerializedSegmentData[];
|
|
230
|
-
/**
|
|
231
|
-
|
|
235
|
+
/** RSC-encoded handle data keyed by segment ID. Encoded via the Flight codec
|
|
236
|
+
* (see handle-snapshot.ts encodeHandles) so Promise/ReactNode handle values
|
|
237
|
+
* round-trip through JSON-serializing stores instead of being flattened. */
|
|
238
|
+
handles: string;
|
|
232
239
|
/** Expiration timestamp (ms since epoch) */
|
|
233
240
|
expiresAt: number;
|
|
241
|
+
/** Cache tags for invalidation */
|
|
242
|
+
tags?: string[];
|
|
243
|
+
/** Timestamp (ms since epoch) when tags were attached, for distributed invalidation */
|
|
244
|
+
taggedAt?: number;
|
|
234
245
|
}
|
|
235
246
|
|
|
236
|
-
// ============================================================================
|
|
237
|
-
// Cache Configuration
|
|
238
|
-
// ============================================================================
|
|
239
|
-
|
|
240
247
|
/**
|
|
241
248
|
* Default cache options applied to all cache() boundaries.
|
|
242
249
|
* Individual cache() calls can override any of these values.
|
|
@@ -252,91 +259,21 @@ export interface CacheDefaults {
|
|
|
252
259
|
/**
|
|
253
260
|
* Default time-to-live in seconds.
|
|
254
261
|
* After TTL expires, cached entry is considered stale.
|
|
262
|
+
* Must be a finite, non-negative number; an invalid value (NaN/Infinity/
|
|
263
|
+
* negative) falls back to the default at read time.
|
|
255
264
|
*/
|
|
256
265
|
ttl?: number;
|
|
257
266
|
/**
|
|
258
267
|
* Default stale-while-revalidate window in seconds.
|
|
259
268
|
* During SWR window, stale content is served while revalidating in background.
|
|
269
|
+
* Must be a finite, non-negative number; an invalid value (NaN/Infinity/
|
|
270
|
+
* negative) falls back to the default at read time.
|
|
260
271
|
*/
|
|
261
272
|
swr?: number;
|
|
262
273
|
}
|
|
263
274
|
|
|
264
|
-
/**
|
|
265
|
-
* Cache configuration for RSC handler
|
|
266
|
-
*/
|
|
267
|
-
export interface CacheConfig {
|
|
268
|
-
/** Cache store implementation (includes defaults) */
|
|
269
|
-
store: SegmentCacheStore;
|
|
270
|
-
/** Enable/disable caching (default: true) */
|
|
271
|
-
enabled?: boolean;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Cache configuration - can be static or a function receiving env
|
|
276
|
-
*/
|
|
277
|
-
export type CacheConfigOrFactory<TEnv> =
|
|
278
|
-
| CacheConfig
|
|
279
|
-
| ((env: TEnv) => CacheConfig);
|
|
280
|
-
|
|
281
|
-
// ============================================================================
|
|
282
|
-
// Segment Cache Provider (request-level interface)
|
|
283
|
-
// ============================================================================
|
|
284
|
-
|
|
285
275
|
/**
|
|
286
276
|
* Handle data for a single segment
|
|
287
277
|
* Structure: { handleName: [values...] }
|
|
288
278
|
*/
|
|
289
279
|
export type SegmentHandleData = Record<string, unknown[]>;
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Result from cache get() including segments and their handle data
|
|
293
|
-
* Each entry can produce multiple segments (main + parallels)
|
|
294
|
-
*/
|
|
295
|
-
export interface CachedEntryResult {
|
|
296
|
-
/** All segments for this entry (main segment + parallels) */
|
|
297
|
-
segments: ResolvedSegment[];
|
|
298
|
-
/** Handle data keyed by segment ID */
|
|
299
|
-
handles: Record<string, SegmentHandleData>;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Segment cache provider interface
|
|
304
|
-
*
|
|
305
|
-
* Used by router to check/store segment cache during matching.
|
|
306
|
-
* Accessed via request context - if not present, caching is disabled.
|
|
307
|
-
*
|
|
308
|
-
* @internal Not currently implemented - CacheScope is used directly.
|
|
309
|
-
* Reserved for future extensibility.
|
|
310
|
-
*/
|
|
311
|
-
export interface SegmentCacheProvider {
|
|
312
|
-
/** Whether caching is enabled for this request */
|
|
313
|
-
readonly enabled: boolean;
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Get cached segments and restore handles/loaders.
|
|
317
|
-
*
|
|
318
|
-
* Combines cache get with handle replay and loader data restoration.
|
|
319
|
-
* Returns tuple of [segments, segmentIds] if cache hit, null if miss or disabled.
|
|
320
|
-
*
|
|
321
|
-
* @param cacheKey - Cache key to look up
|
|
322
|
-
* @param params - Route params for cache key generation
|
|
323
|
-
* @param loaderPromises - Map to restore loader data into
|
|
324
|
-
* @returns Tuple of [segments, segmentIds] or null if miss
|
|
325
|
-
*/
|
|
326
|
-
restore(
|
|
327
|
-
cacheKey: string,
|
|
328
|
-
params: Record<string, string>,
|
|
329
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
330
|
-
): Promise<[ResolvedSegment[], string[]] | null>;
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Cache entry with automatic handle collection (non-blocking).
|
|
334
|
-
*
|
|
335
|
-
* Schedules caching via waitUntil - handles are collected after they settle.
|
|
336
|
-
* Validates segments have actual components before caching.
|
|
337
|
-
*
|
|
338
|
-
* @param cacheKey - The cache key to store under
|
|
339
|
-
* @param segments - All resolved segments for this entry
|
|
340
|
-
*/
|
|
341
|
-
cacheEntry(cacheKey: string, segments: ResolvedSegment[]): void;
|
|
342
|
-
}
|
package/src/client.rsc.tsx
CHANGED
|
@@ -14,60 +14,81 @@
|
|
|
14
14
|
export {
|
|
15
15
|
Outlet,
|
|
16
16
|
ParallelOutlet,
|
|
17
|
-
OutletProvider,
|
|
18
17
|
useOutlet,
|
|
19
18
|
useLoader,
|
|
20
19
|
ErrorBoundary,
|
|
21
20
|
type ErrorBoundaryProps,
|
|
22
21
|
} from "./client.js";
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
export {
|
|
24
|
+
useFetchLoader,
|
|
25
|
+
useRefreshLoaders,
|
|
26
|
+
type LoadFunction,
|
|
27
|
+
type UseLoaderResult,
|
|
28
|
+
type UseFetchLoaderResult,
|
|
29
|
+
type UseLoaderOptions,
|
|
30
|
+
} from "./use-loader.js";
|
|
31
|
+
|
|
26
32
|
export { createLoader } from "./route-definition.js";
|
|
27
33
|
|
|
28
|
-
//
|
|
34
|
+
// "use client" hooks the default ./client entry exports. They are client
|
|
35
|
+
// references in the RSC graph, identical in kind to useHref/useReverse/
|
|
36
|
+
// useHandle already forwarded below; forward them so the RSC client entry's
|
|
37
|
+
// hook surface matches the default entry. useNavigation/useAction stay omitted
|
|
38
|
+
// (they drive client-only navigation/action state — see note below).
|
|
39
|
+
export { useRouter } from "./browser/react/use-router.js";
|
|
40
|
+
export { usePathname } from "./browser/react/use-pathname.js";
|
|
41
|
+
export { useSearchParams } from "./browser/react/use-search-params.js";
|
|
42
|
+
export { useParams } from "./browser/react/use-params.js";
|
|
43
|
+
// CSP nonce for userland head-script components (analytics/GTM/inline init);
|
|
44
|
+
// forwarded so the RSC client entry's hook surface matches the default entry.
|
|
45
|
+
export { useNonce } from "./browser/react/nonce-context.js";
|
|
46
|
+
export { useMount } from "./browser/react/use-mount.js";
|
|
47
|
+
export {
|
|
48
|
+
useSegments,
|
|
49
|
+
type SegmentsState,
|
|
50
|
+
} from "./browser/react/use-segments.js";
|
|
51
|
+
export {
|
|
52
|
+
useLinkStatus,
|
|
53
|
+
type LinkStatus,
|
|
54
|
+
} from "./browser/react/use-link-status.js";
|
|
55
|
+
export { useScrollRestoration } from "./browser/react/ScrollRestoration.js";
|
|
56
|
+
|
|
29
57
|
export {
|
|
30
58
|
Link,
|
|
31
59
|
type LinkProps,
|
|
32
60
|
type PrefetchStrategy,
|
|
33
61
|
} from "./browser/react/Link.js";
|
|
34
62
|
|
|
35
|
-
// Re-export ScrollRestoration (can be used in server components)
|
|
36
63
|
export {
|
|
37
64
|
ScrollRestoration,
|
|
38
65
|
type ScrollRestorationProps,
|
|
39
66
|
} from "./browser/react/ScrollRestoration.js";
|
|
40
67
|
|
|
41
|
-
// Re-export NavigationProvider (needed for setup)
|
|
42
68
|
export {
|
|
43
69
|
NavigationProvider,
|
|
44
70
|
type NavigationProviderProps,
|
|
45
71
|
} from "./browser/react/NavigationProvider.js";
|
|
46
72
|
|
|
47
|
-
// Re-export href function (can be used in server components)
|
|
48
73
|
export { href } from "./href-client.js";
|
|
49
74
|
|
|
50
|
-
// Mount context re-exports (useMount is client-only, but MountContext can be referenced)
|
|
51
75
|
export { MountContext } from "./browser/react/mount-context.js";
|
|
52
76
|
|
|
53
|
-
//
|
|
54
|
-
// because they use client-side state and should only be used in client components
|
|
77
|
+
// useNavigation and useAction are NOT re-exported here because they use client-side state
|
|
55
78
|
|
|
56
|
-
// Handle API - for accumulating data across route segments
|
|
57
|
-
// Works in both RSC and client contexts
|
|
58
79
|
export { createHandle, isHandle, type Handle } from "./handle.js";
|
|
59
80
|
|
|
60
|
-
// Built-in handles
|
|
61
|
-
// Meta handle works in RSC context
|
|
62
81
|
export { Meta } from "./handles/meta.js";
|
|
63
|
-
// MetaTags is a "use client" component that can be imported from RSC
|
|
64
82
|
export { MetaTags } from "./handles/MetaTags.js";
|
|
65
83
|
export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
|
|
66
|
-
|
|
84
|
+
export {
|
|
85
|
+
Script,
|
|
86
|
+
type ScriptConfig,
|
|
87
|
+
type ScriptAttributes,
|
|
88
|
+
} from "./handles/script.js";
|
|
89
|
+
export { Scripts } from "./handles/Scripts.js";
|
|
67
90
|
export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
|
|
68
91
|
|
|
69
|
-
// Location state - createLocationState works in RSC (just creates definition)
|
|
70
|
-
// useLocationState is NOT exported here as it uses client hooks
|
|
71
92
|
export {
|
|
72
93
|
createLocationState,
|
|
73
94
|
type LocationStateDefinition,
|
|
@@ -75,11 +96,13 @@ export {
|
|
|
75
96
|
type LocationStateOptions,
|
|
76
97
|
} from "./browser/react/location-state-shared.js";
|
|
77
98
|
|
|
78
|
-
// Re-export useHref - it's a "use client" hook
|
|
79
99
|
export { useHref } from "./browser/react/use-href.js";
|
|
80
100
|
|
|
81
|
-
|
|
101
|
+
export { useReverse } from "./browser/react/use-reverse.js";
|
|
102
|
+
|
|
82
103
|
export { useHandle } from "./browser/react/use-handle.js";
|
|
104
|
+
// Type a deferred-aware consumer narrows: an accumulated entry may be a Promise
|
|
105
|
+
// (a `ctx.use(Handle).defer()` slot) until it resolves.
|
|
106
|
+
export type { DeferredHandleEntry } from "./defer.js";
|
|
83
107
|
|
|
84
|
-
// Re-export useLocationState - it's a "use client" hook
|
|
85
108
|
export { useLocationState } from "./browser/react/location-state.js";
|
package/src/client.tsx
CHANGED
|
@@ -111,6 +111,11 @@ function useSlotSegment(
|
|
|
111
111
|
* the parallel segment with that slot name instead of the default content.
|
|
112
112
|
* This is used for parallel routes and intercepting routes.
|
|
113
113
|
*
|
|
114
|
+
* For a named slot, `<Outlet name="@x" />` is equivalent to
|
|
115
|
+
* `<ParallelOutlet name="@x" />` — both run the same resolution + wrapping
|
|
116
|
+
* pipeline. Convention: use bare `<Outlet />` for default content and
|
|
117
|
+
* `<ParallelOutlet name="@x" />` for named slots.
|
|
118
|
+
*
|
|
114
119
|
* @param name - Optional slot name for parallel/intercept content (must start with @)
|
|
115
120
|
*
|
|
116
121
|
* @example
|
|
@@ -163,6 +168,9 @@ export function Outlet({ name }: { name?: `@${string}` } = {}): ReactNode {
|
|
|
163
168
|
* is wrapped in Suspense with the loading component as fallback.
|
|
164
169
|
* This enables streaming and navigation loading states for parallels.
|
|
165
170
|
*
|
|
171
|
+
* Equivalent to `<Outlet name="@x" />` for a named slot; ParallelOutlet
|
|
172
|
+
* requires `name` and is named-slot-only, which reads clearer at the call site.
|
|
173
|
+
*
|
|
166
174
|
* @param name - The slot name (must start with @, e.g., "@modal", "@sidebar")
|
|
167
175
|
*
|
|
168
176
|
* @example
|
|
@@ -186,10 +194,9 @@ export function ParallelOutlet({ name }: { name: `@${string}` }): ReactNode {
|
|
|
186
194
|
}
|
|
187
195
|
|
|
188
196
|
// OutletProvider is defined in outlet-provider.tsx to break a circular
|
|
189
|
-
// dependency between client.tsx and route-content-wrapper.tsx.
|
|
190
|
-
//
|
|
191
|
-
// and
|
|
192
|
-
export { OutletProvider };
|
|
197
|
+
// dependency between client.tsx and route-content-wrapper.tsx. It is imported
|
|
198
|
+
// at the top of this file for local use in Outlet/ParallelOutlet only; it is an
|
|
199
|
+
// internal component and is intentionally not part of the public ./client API.
|
|
193
200
|
|
|
194
201
|
/**
|
|
195
202
|
* Hook to access outlet content programmatically
|
|
@@ -210,10 +217,10 @@ export function useOutlet(): ReactNode {
|
|
|
210
217
|
return context?.content ?? null;
|
|
211
218
|
}
|
|
212
219
|
|
|
213
|
-
// Loader hooks - re-exported from dedicated file
|
|
214
220
|
export {
|
|
215
221
|
useLoader,
|
|
216
222
|
useFetchLoader,
|
|
223
|
+
useRefreshLoaders,
|
|
217
224
|
type LoadFunction,
|
|
218
225
|
type UseLoaderResult,
|
|
219
226
|
type UseFetchLoaderResult,
|
|
@@ -328,79 +335,75 @@ export class ErrorBoundary extends Component<
|
|
|
328
335
|
}
|
|
329
336
|
}
|
|
330
337
|
|
|
331
|
-
// ============================================================================
|
|
332
|
-
// Re-exports from browser/react for convenience
|
|
333
|
-
// These are the most commonly used client-side navigation utilities
|
|
334
|
-
// ============================================================================
|
|
335
|
-
|
|
336
|
-
// Navigation hooks
|
|
337
338
|
export { useNavigation } from "./browser/react/use-navigation.js";
|
|
338
339
|
export { useRouter } from "./browser/react/use-router.js";
|
|
339
340
|
export { usePathname } from "./browser/react/use-pathname.js";
|
|
340
341
|
export { useSearchParams } from "./browser/react/use-search-params.js";
|
|
341
342
|
export { useParams } from "./browser/react/use-params.js";
|
|
343
|
+
// CSP nonce for the active request, for userland components that inject their
|
|
344
|
+
// own <script>/<style> into the document head (analytics, GTM, inline init).
|
|
345
|
+
// Returns the nonce during SSR and undefined in the browser; render the tag
|
|
346
|
+
// server-side so the nonce lands in the SSR HTML and hydration stays clean.
|
|
347
|
+
export { useNonce } from "./browser/react/nonce-context.js";
|
|
342
348
|
export type {
|
|
343
349
|
RouterInstance,
|
|
344
350
|
RouterNavigateOptions,
|
|
345
351
|
ReadonlyURLSearchParams,
|
|
352
|
+
ActionState,
|
|
353
|
+
ActionLifecycleState,
|
|
346
354
|
} from "./browser/types.js";
|
|
347
355
|
|
|
348
|
-
// Action state tracking hook
|
|
349
356
|
export {
|
|
350
357
|
useAction,
|
|
351
358
|
type ServerActionFunction,
|
|
352
359
|
} from "./browser/react/use-action.js";
|
|
353
360
|
|
|
354
|
-
// Segments state hook
|
|
355
361
|
export {
|
|
356
362
|
useSegments,
|
|
357
363
|
type SegmentsState,
|
|
358
364
|
} from "./browser/react/use-segments.js";
|
|
359
365
|
|
|
360
|
-
// Client cache controls hook
|
|
361
|
-
export {
|
|
362
|
-
useClientCache,
|
|
363
|
-
type ClientCacheControls,
|
|
364
|
-
} from "./browser/react/use-client-cache.js";
|
|
365
|
-
|
|
366
|
-
// Provider
|
|
367
366
|
export {
|
|
368
367
|
NavigationProvider,
|
|
369
368
|
type NavigationProviderProps,
|
|
370
369
|
} from "./browser/react/NavigationProvider.js";
|
|
371
370
|
|
|
372
|
-
// Link component
|
|
373
371
|
export {
|
|
374
372
|
Link,
|
|
375
373
|
type LinkProps,
|
|
376
374
|
type PrefetchStrategy,
|
|
377
375
|
type StateOrGetter,
|
|
376
|
+
type LinkState,
|
|
378
377
|
} from "./browser/react/Link.js";
|
|
379
378
|
|
|
380
|
-
// Link status hook
|
|
381
379
|
export {
|
|
382
380
|
useLinkStatus,
|
|
383
381
|
type LinkStatus,
|
|
384
382
|
} from "./browser/react/use-link-status.js";
|
|
385
383
|
|
|
386
|
-
// Scroll restoration
|
|
387
384
|
export {
|
|
388
385
|
ScrollRestoration,
|
|
389
386
|
useScrollRestoration,
|
|
390
387
|
type ScrollRestorationProps,
|
|
391
388
|
} from "./browser/react/ScrollRestoration.js";
|
|
392
389
|
|
|
393
|
-
// Handle data hook (client-side only — createHandle/isHandle are server APIs from the root export)
|
|
394
390
|
export { type Handle } from "./handle.js";
|
|
395
391
|
export { useHandle } from "./browser/react/use-handle.js";
|
|
392
|
+
// Type a deferred-aware consumer narrows: an accumulated entry may be a Promise
|
|
393
|
+
// (a `ctx.use(Handle).defer()` slot) until it resolves.
|
|
394
|
+
export type { DeferredHandleEntry } from "./defer.js";
|
|
396
395
|
|
|
397
|
-
// Built-in handles
|
|
398
396
|
export { Meta } from "./handles/meta.js";
|
|
399
397
|
export { MetaTags } from "./handles/MetaTags.js";
|
|
400
398
|
export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
|
|
399
|
+
export {
|
|
400
|
+
Script,
|
|
401
|
+
type ScriptConfig,
|
|
402
|
+
type ScriptAttributes,
|
|
403
|
+
} from "./handles/script.js";
|
|
404
|
+
export { Scripts } from "./handles/Scripts.js";
|
|
401
405
|
export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
|
|
402
406
|
|
|
403
|
-
// Location state - type-safe navigation state
|
|
404
407
|
export {
|
|
405
408
|
createLocationState,
|
|
406
409
|
useLocationState,
|
|
@@ -409,47 +412,19 @@ export {
|
|
|
409
412
|
type LocationStateOptions,
|
|
410
413
|
} from "./browser/react/location-state.js";
|
|
411
414
|
|
|
412
|
-
//
|
|
413
|
-
export {
|
|
414
|
-
href,
|
|
415
|
-
type ValidPaths,
|
|
416
|
-
type PatternToPath,
|
|
417
|
-
type PathResponse,
|
|
418
|
-
} from "./href-client.js";
|
|
419
|
-
|
|
420
|
-
// Response envelope types for consuming JSON response routes
|
|
421
|
-
export type { ResponseEnvelope, ResponseError } from "./urls.js";
|
|
415
|
+
// Ambient Rango.Path / Rango.PathResponse types (declared in href-client.ts)
|
|
416
|
+
export { href, type PatternToPath } from "./href-client.js";
|
|
422
417
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
*
|
|
426
|
-
* @example
|
|
427
|
-
* ```typescript
|
|
428
|
-
* const result: ResponseEnvelope<Product> = await fetch(url).then(r => r.json());
|
|
429
|
-
* if (isResponseError(result)) {
|
|
430
|
-
* console.log(result.error.message, result.error.code);
|
|
431
|
-
* return;
|
|
432
|
-
* }
|
|
433
|
-
* result.data // fully typed as Product
|
|
434
|
-
* ```
|
|
435
|
-
*/
|
|
436
|
-
export function isResponseError<T>(
|
|
437
|
-
result: import("./urls.js").ResponseEnvelope<T>,
|
|
438
|
-
): result is import("./urls.js").ResponseEnvelope<T> & {
|
|
439
|
-
error: import("./urls.js").ResponseError;
|
|
440
|
-
} {
|
|
441
|
-
return result.error !== undefined;
|
|
442
|
-
}
|
|
418
|
+
// RFC 9457 error type for JSON response routes
|
|
419
|
+
export type { ProblemDetails } from "./urls.js";
|
|
443
420
|
|
|
444
|
-
// Mount context for include() scoped components
|
|
445
421
|
export { useMount } from "./browser/react/use-mount.js";
|
|
446
422
|
export { MountContext } from "./browser/react/mount-context.js";
|
|
447
423
|
|
|
448
|
-
// Mount-aware href hook - auto-prefixes paths with include() mount
|
|
449
424
|
export { useHref } from "./browser/react/use-href.js";
|
|
450
425
|
|
|
451
|
-
|
|
452
|
-
|
|
426
|
+
export { useReverse } from "./browser/react/use-reverse.js";
|
|
427
|
+
|
|
428
|
+
export type { ScopedReverseFunction, LocalReverseFunction } from "./reverse.js";
|
|
453
429
|
|
|
454
|
-
// Loader definition type - for typing loader props in client components
|
|
455
430
|
export type { LoaderDefinition } from "./types.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare preset integration surface for @rangojs/router.
|
|
3
|
+
*
|
|
4
|
+
* Imported via `@rangojs/router/cloudflare`. Cloudflare-only helpers live here
|
|
5
|
+
* so Node/other-platform consumers never pull them in.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
createCloudflareTracing,
|
|
10
|
+
type CloudflareTracingOptions,
|
|
11
|
+
} from "./tracing.js";
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare custom-spans integration.
|
|
3
|
+
*
|
|
4
|
+
* Bridges the router's performance phases (request, middleware, action,
|
|
5
|
+
* loaders, handler, render, ssr) onto Cloudflare Workers custom spans so they show
|
|
6
|
+
* up in the trace waterfall and OpenTelemetry exports next to the platform's
|
|
7
|
+
* automatic spans (KV reads, D1 queries, fetch calls), with correct nesting.
|
|
8
|
+
*
|
|
9
|
+
* Usage (Cloudflare preset only):
|
|
10
|
+
*
|
|
11
|
+
* import { createRouter } from "@rangojs/router";
|
|
12
|
+
* import { createCloudflareTracing } from "@rangojs/router/cloudflare";
|
|
13
|
+
*
|
|
14
|
+
* export const router = createRouter({
|
|
15
|
+
* tracing: createCloudflareTracing(),
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* The runner reads `executionContext.tracing` (the same object as
|
|
19
|
+
* `import { tracing } from "cloudflare:workers"`) at call time. It is therefore
|
|
20
|
+
* dependency-free: no `cloudflare:workers` import and no hard dependency on
|
|
21
|
+
* `@cloudflare/workers-types`, matching the convention in cache/cf. When the
|
|
22
|
+
* worker is not running on a tracing-enabled Cloudflare runtime — Node, dev
|
|
23
|
+
* without a tracing destination, an older runtime — `executionContext.tracing`
|
|
24
|
+
* is undefined and every span call falls through to the work directly, so the
|
|
25
|
+
* request behaves exactly as if tracing were off. Whether spans are actually
|
|
26
|
+
* recorded is governed by the `observability`/tracing block in wrangler config.
|
|
27
|
+
*
|
|
28
|
+
* Span duration note: enterSpan ends a span when its callback's returned value
|
|
29
|
+
* (or promise) settles. For the streaming phases (request/render/ssr) that is at
|
|
30
|
+
* stream CONSTRUCTION, not body-drain. Instrumentation is best-effort and never
|
|
31
|
+
* wraps or buffers the response body, so it cannot regress streaming or latency.
|
|
32
|
+
* A loader/Suspense child that resolves mid-stream therefore keeps a rango.loader
|
|
33
|
+
* span that can extend past its render parent — overlapping spans are valid. Uses
|
|
34
|
+
* only the typed enterSpan API; spans bound work up to stream-handoff, matching
|
|
35
|
+
* the co-emitted perf metric.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import { _getRequestContext } from "../server/request-context.js";
|
|
39
|
+
import {
|
|
40
|
+
type RouterTracingConfig,
|
|
41
|
+
type SpanRunner,
|
|
42
|
+
type TracePhaseToggles,
|
|
43
|
+
NOOP_TRACE_SPAN,
|
|
44
|
+
} from "../router/tracing.js";
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Minimal local view of Cloudflare's `Span`. Declared here (not imported from
|
|
48
|
+
* `@cloudflare/workers-types`) to avoid a hard type dependency.
|
|
49
|
+
*/
|
|
50
|
+
interface CloudflareSpan {
|
|
51
|
+
readonly isTraced: boolean;
|
|
52
|
+
setAttribute(key: string, value?: boolean | number | string): void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Minimal local view of Cloudflare's `Tracing` (only enterSpan is used). */
|
|
56
|
+
interface CloudflareTracing {
|
|
57
|
+
enterSpan<T>(name: string, callback: (span: CloudflareSpan) => T): T;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Options for createCloudflareTracing. */
|
|
61
|
+
export interface CloudflareTracingOptions {
|
|
62
|
+
/** Master switch. Defaults to true. */
|
|
63
|
+
enabled?: boolean;
|
|
64
|
+
/** Per-phase span toggles. Omitted phases default to enabled. */
|
|
65
|
+
spans?: TracePhaseToggles;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Resolve the per-request Cloudflare tracer from the active execution context.
|
|
70
|
+
* Returns undefined off-Cloudflare or when tracing is not enabled for the
|
|
71
|
+
* worker, in which case the caller runs the work without a span.
|
|
72
|
+
*/
|
|
73
|
+
function getRequestTracer(): CloudflareTracing | undefined {
|
|
74
|
+
const executionContext = _getRequestContext()?.executionContext as
|
|
75
|
+
| { tracing?: CloudflareTracing }
|
|
76
|
+
| undefined;
|
|
77
|
+
const tracing = executionContext?.tracing;
|
|
78
|
+
return tracing && typeof tracing.enterSpan === "function"
|
|
79
|
+
? tracing
|
|
80
|
+
: undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const cloudflareSpanRunner: SpanRunner = (name, fn) => {
|
|
84
|
+
const tracer = getRequestTracer();
|
|
85
|
+
if (!tracer) return fn(NOOP_TRACE_SPAN);
|
|
86
|
+
// enterSpan runs the callback now and ends the span when its return value
|
|
87
|
+
// (or returned promise) settles; spans nest by JS async context. fn's param
|
|
88
|
+
// is the narrower TraceSpan, so the wider CloudflareSpan satisfies it directly.
|
|
89
|
+
return tracer.enterSpan(name, fn);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create the tracing config for a Cloudflare router. Pass the result to
|
|
94
|
+
* `createRouter({ tracing })`. Spans are emitted for the request, middleware,
|
|
95
|
+
* action, loaders, handler, render, and ssr phases; pass `spans` to turn
|
|
96
|
+
* individual phases off.
|
|
97
|
+
*
|
|
98
|
+
* @see createOTelTracing (`@rangojs/router`) for the same slot on any platform
|
|
99
|
+
* with an OpenTelemetry SDK.
|
|
100
|
+
*/
|
|
101
|
+
export function createCloudflareTracing(
|
|
102
|
+
options: CloudflareTracingOptions = {},
|
|
103
|
+
): RouterTracingConfig {
|
|
104
|
+
return {
|
|
105
|
+
runner: cloudflareSpanRunner,
|
|
106
|
+
enabled: options.enabled ?? true,
|
|
107
|
+
spans: options.spans,
|
|
108
|
+
};
|
|
109
|
+
}
|