@rangojs/router 0.0.0-experimental.9 → 0.0.0-experimental.98d9a51b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -0
- package/README.md +884 -4
- package/dist/bin/rango.js +1532 -155
- package/dist/vite/index.js +4444 -2235
- package/package.json +69 -62
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +262 -0
- package/skills/caching/SKILL.md +85 -23
- package/skills/composability/SKILL.md +172 -0
- package/skills/debug-manifest/SKILL.md +12 -8
- package/skills/document-cache/SKILL.md +18 -16
- package/skills/fonts/SKILL.md +6 -4
- package/skills/hooks/SKILL.md +333 -71
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +131 -8
- package/skills/layout/SKILL.md +100 -3
- package/skills/links/SKILL.md +74 -15
- package/skills/loader/SKILL.md +388 -38
- package/skills/middleware/SKILL.md +171 -34
- package/skills/mime-routes/SKILL.md +15 -11
- package/skills/parallel/SKILL.md +78 -1
- package/skills/prerender/SKILL.md +405 -45
- package/skills/rango/SKILL.md +85 -21
- package/skills/response-routes/SKILL.md +144 -91
- package/skills/route/SKILL.md +226 -14
- package/skills/router-setup/SKILL.md +123 -30
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +316 -87
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/event-controller.ts +87 -64
- package/src/browser/history-state.ts +80 -0
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +55 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +282 -557
- package/src/browser/navigation-client.ts +169 -73
- package/src/browser/navigation-store.ts +33 -50
- package/src/browser/navigation-transaction.ts +297 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +292 -310
- package/src/browser/prefetch/cache.ts +206 -0
- package/src/browser/prefetch/fetch.ts +145 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +128 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +190 -70
- package/src/browser/react/NavigationProvider.tsx +78 -11
- package/src/browser/react/context.ts +6 -0
- package/src/browser/react/filter-segment-order.ts +11 -0
- package/src/browser/react/index.ts +12 -12
- package/src/browser/react/location-state-shared.ts +95 -53
- package/src/browser/react/location-state.ts +60 -15
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +29 -51
- package/src/browser/react/use-client-cache.ts +5 -3
- package/src/browser/react/use-handle.ts +29 -70
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +22 -63
- package/src/browser/react/use-params.ts +65 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-router.ts +63 -0
- package/src/browser/react/use-search-params.ts +56 -0
- package/src/browser/react/use-segments.ts +80 -97
- package/src/browser/response-adapter.ts +73 -0
- package/src/browser/rsc-router.tsx +106 -27
- package/src/browser/scroll-restoration.ts +117 -44
- package/src/browser/segment-reconciler.ts +216 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +504 -599
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +116 -47
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +82 -21
- package/src/build/generate-route-types.ts +36 -752
- package/src/build/index.ts +6 -5
- package/src/build/route-trie.ts +39 -13
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +98 -0
- package/src/build/route-types/codegen.ts +102 -0
- package/src/build/route-types/include-resolution.ts +411 -0
- package/src/build/route-types/param-extraction.ts +48 -0
- package/src/build/route-types/per-module-writer.ts +128 -0
- package/src/build/route-types/router-processing.ts +479 -0
- package/src/build/route-types/scan-filter.ts +78 -0
- package/src/build/runtime-discovery.ts +231 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-key-utils.ts +44 -0
- package/src/cache/cache-policy.ts +125 -0
- package/src/cache/cache-runtime.ts +338 -0
- package/src/cache/cache-scope.ts +122 -303
- package/src/cache/cf/cf-cache-store.ts +571 -17
- package/src/cache/cf/index.ts +13 -3
- package/src/cache/document-cache.ts +101 -72
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +41 -0
- package/src/cache/index.ts +1 -15
- package/src/cache/memory-segment-store.ts +191 -13
- package/src/cache/profile-registry.ts +73 -0
- package/src/cache/read-through-swr.ts +134 -0
- package/src/cache/segment-codec.ts +256 -0
- package/src/cache/taint.ts +98 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +84 -126
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +86 -0
- package/src/debug.ts +17 -7
- package/src/errors.ts +77 -7
- package/src/handle.ts +15 -10
- package/src/handles/MetaTags.tsx +73 -20
- package/src/handles/breadcrumbs.ts +66 -0
- package/src/handles/index.ts +1 -0
- package/src/handles/meta.ts +30 -13
- package/src/host/cookie-handler.ts +21 -15
- package/src/host/errors.ts +8 -8
- package/src/host/index.ts +4 -7
- package/src/host/pattern-matcher.ts +27 -27
- package/src/host/router.ts +61 -39
- package/src/host/testing.ts +8 -8
- package/src/host/types.ts +15 -7
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +65 -45
- package/src/index.rsc.ts +133 -21
- package/src/index.ts +164 -52
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +25 -143
- package/src/loader.ts +27 -10
- package/src/network-error-thrower.tsx +3 -1
- package/src/outlet-provider.tsx +45 -0
- package/src/prerender/param-hash.ts +4 -2
- package/src/prerender/store.ts +158 -13
- package/src/prerender.ts +333 -26
- package/src/reverse.ts +184 -121
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +934 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +430 -0
- package/src/route-definition/index.ts +52 -0
- package/src/route-definition/redirect.ts +93 -0
- package/src/route-definition.ts +1 -1431
- package/src/route-map-builder.ts +162 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +48 -9
- package/src/router/content-negotiation.ts +116 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +9 -9
- package/src/router/find-match.ts +160 -0
- package/src/router/handler-context.ts +374 -81
- package/src/router/intercept-resolution.ts +26 -16
- package/src/router/lazy-includes.ts +236 -0
- package/src/router/loader-resolution.ts +215 -122
- package/src/router/logging.ts +251 -0
- package/src/router/manifest.ts +85 -32
- package/src/router/match-api.ts +118 -119
- package/src/router/match-context.ts +4 -2
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +80 -93
- package/src/router/match-middleware/cache-lookup.ts +336 -84
- package/src/router/match-middleware/cache-store.ts +43 -24
- package/src/router/match-middleware/intercept-resolution.ts +45 -20
- package/src/router/match-middleware/segment-resolution.ts +17 -8
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +34 -28
- package/src/router/metrics.ts +235 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +222 -0
- package/src/router/middleware.ts +327 -369
- package/src/router/pattern-matching.ts +197 -41
- package/src/router/prerender-match.ts +402 -0
- package/src/router/preview-match.ts +170 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/router-context.ts +40 -21
- package/src/router/router-interfaces.ts +452 -0
- package/src/router/router-options.ts +592 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +570 -0
- package/src/router/segment-resolution/helpers.ts +263 -0
- package/src/router/segment-resolution/loader-cache.ts +198 -0
- package/src/router/segment-resolution/revalidation.ts +1242 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -1315
- package/src/router/segment-wrappers.ts +291 -0
- package/src/router/telemetry-otel.ts +299 -0
- package/src/router/telemetry.ts +300 -0
- package/src/router/timeout.ts +148 -0
- package/src/router/trie-matching.ts +96 -29
- package/src/router/types.ts +16 -9
- package/src/router.ts +595 -1984
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +680 -1027
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +209 -0
- package/src/rsc/manifest-init.ts +86 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +379 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +237 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +348 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +38 -11
- package/src/search-params.ts +230 -0
- package/src/segment-system.tsx +25 -13
- package/src/server/context.ts +173 -48
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +94 -15
- package/src/server/loader-registry.ts +15 -56
- package/src/server/request-context.ts +439 -73
- package/src/server.ts +35 -155
- package/src/ssr/index.tsx +100 -31
- package/src/static-handler.ts +114 -0
- package/src/theme/ThemeProvider.tsx +21 -15
- package/src/theme/ThemeScript.tsx +5 -5
- package/src/theme/constants.ts +5 -2
- package/src/theme/index.ts +4 -14
- package/src/theme/theme-context.ts +4 -30
- package/src/theme/theme-script.ts +21 -18
- package/src/types/boundaries.ts +158 -0
- package/src/types/cache-types.ts +198 -0
- package/src/types/error-types.ts +192 -0
- package/src/types/global-namespace.ts +100 -0
- package/src/types/handler-context.ts +687 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +183 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +109 -0
- package/src/types/segments.ts +148 -0
- package/src/types.ts +1 -1757
- package/src/urls/include-helper.ts +197 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +339 -0
- package/src/urls/path-helper.ts +329 -0
- package/src/urls/pattern-types.ts +95 -0
- package/src/urls/response-types.ts +106 -0
- package/src/urls/type-extraction.ts +372 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -1282
- package/src/use-loader.tsx +85 -77
- package/src/vite/discovery/bundle-postprocess.ts +184 -0
- package/src/vite/discovery/discover-routers.ts +344 -0
- package/src/vite/discovery/prerender-collection.ts +385 -0
- package/src/vite/discovery/route-types-writer.ts +258 -0
- package/src/vite/discovery/self-gen-tracking.ts +47 -0
- package/src/vite/discovery/state.ts +108 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +11 -1963
- package/src/vite/plugin-types.ts +48 -0
- package/src/vite/plugins/cjs-to-esm.ts +93 -0
- package/src/vite/plugins/client-ref-dedup.ts +115 -0
- package/src/vite/plugins/client-ref-hashing.ts +105 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +72 -53
- package/src/vite/plugins/expose-id-utils.ts +287 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +569 -0
- package/src/vite/plugins/refresh-cmd.ts +65 -0
- package/src/vite/plugins/use-cache-transform.ts +323 -0
- package/src/vite/plugins/version-injector.ts +83 -0
- package/src/vite/plugins/version-plugin.ts +254 -0
- package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +27 -14
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +445 -0
- package/src/vite/router-discovery.ts +777 -0
- package/src/vite/utils/ast-handler-extract.ts +517 -0
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +137 -0
- package/src/vite/utils/manifest-utils.ts +70 -0
- package/src/vite/{package-resolution.ts → utils/package-resolution.ts} +25 -29
- package/src/vite/utils/prerender-utils.ts +189 -0
- package/src/vite/utils/shared-utils.ts +169 -0
- package/CLAUDE.md +0 -43
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/request-controller.ts +0 -164
- package/src/cache/memory-store.ts +0 -253
- package/src/href-context.ts +0 -33
- package/src/router.gen.ts +0 -6
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-handle-id.ts +0 -209
- package/src/vite/expose-loader-id.ts +0 -426
- package/src/vite/expose-location-state-id.ts +0 -177
- package/src/vite/expose-prerender-handler-id.ts +0 -429
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
package/src/cache/types.ts
CHANGED
|
@@ -75,14 +75,14 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
75
75
|
* @example Using cookies for locale
|
|
76
76
|
* ```typescript
|
|
77
77
|
* keyGenerator: (ctx, defaultKey) => {
|
|
78
|
-
* const locale =
|
|
78
|
+
* const locale = cookies().get('locale')?.value || 'en';
|
|
79
79
|
* return `${locale}:${defaultKey}`;
|
|
80
80
|
* }
|
|
81
81
|
* ```
|
|
82
82
|
*/
|
|
83
83
|
readonly keyGenerator?: (
|
|
84
84
|
ctx: RequestContext<TEnv>,
|
|
85
|
-
defaultKey: string
|
|
85
|
+
defaultKey: string,
|
|
86
86
|
) => string | Promise<string>;
|
|
87
87
|
|
|
88
88
|
/**
|
|
@@ -98,7 +98,12 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
98
98
|
* @param ttl - Time-to-live in seconds
|
|
99
99
|
* @param swr - Optional stale-while-revalidate window in seconds
|
|
100
100
|
*/
|
|
101
|
-
set(
|
|
101
|
+
set(
|
|
102
|
+
key: string,
|
|
103
|
+
data: CachedEntryData,
|
|
104
|
+
ttl: number,
|
|
105
|
+
swr?: number,
|
|
106
|
+
): Promise<void>;
|
|
102
107
|
|
|
103
108
|
/**
|
|
104
109
|
* Delete a cached entry
|
|
@@ -121,7 +126,9 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
121
126
|
* Get a cached Response by key.
|
|
122
127
|
* Returns the response and whether it should be revalidated (SWR).
|
|
123
128
|
*/
|
|
124
|
-
getResponse?(
|
|
129
|
+
getResponse?(
|
|
130
|
+
key: string,
|
|
131
|
+
): Promise<{ response: Response; shouldRevalidate: boolean } | null>;
|
|
125
132
|
|
|
126
133
|
/**
|
|
127
134
|
* Store a Response with TTL and optional SWR window.
|
|
@@ -130,7 +137,62 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
130
137
|
* @param ttl - Time-to-live in seconds
|
|
131
138
|
* @param swr - Optional stale-while-revalidate window in seconds
|
|
132
139
|
*/
|
|
133
|
-
putResponse?(
|
|
140
|
+
putResponse?(
|
|
141
|
+
key: string,
|
|
142
|
+
response: Response,
|
|
143
|
+
ttl: number,
|
|
144
|
+
swr?: number,
|
|
145
|
+
): Promise<void>;
|
|
146
|
+
|
|
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
|
+
/**
|
|
154
|
+
* Get a cached function result by key.
|
|
155
|
+
* Returns the serialized value, optional handle data, and staleness flag.
|
|
156
|
+
*/
|
|
157
|
+
getItem?(key: string): Promise<CacheItemResult | null>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Store a function result with TTL and optional SWR window.
|
|
161
|
+
* @param key - Cache key (format: use-cache:{functionId}:{serializedArgs})
|
|
162
|
+
* @param value - RSC-serialized return value
|
|
163
|
+
* @param options - TTL, SWR, handle data, and tags
|
|
164
|
+
*/
|
|
165
|
+
setItem?(
|
|
166
|
+
key: string,
|
|
167
|
+
value: string,
|
|
168
|
+
options?: CacheItemOptions,
|
|
169
|
+
): Promise<void>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Result from getItem() for function-level caching ("use cache").
|
|
174
|
+
*/
|
|
175
|
+
export interface CacheItemResult {
|
|
176
|
+
/** RSC-serialized return value */
|
|
177
|
+
value: string;
|
|
178
|
+
/** Handle data captured during execution (breadcrumbs, metadata, etc.) */
|
|
179
|
+
handles?: Record<string, SegmentHandleData>;
|
|
180
|
+
/** Whether the entry is stale and should be revalidated */
|
|
181
|
+
shouldRevalidate: boolean;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Options for setItem() for function-level caching ("use cache").
|
|
186
|
+
*/
|
|
187
|
+
export interface CacheItemOptions {
|
|
188
|
+
/** Handle data to store alongside the value */
|
|
189
|
+
handles?: Record<string, SegmentHandleData>;
|
|
190
|
+
/** Time-to-live in seconds */
|
|
191
|
+
ttl?: number;
|
|
192
|
+
/** Stale-while-revalidate window in seconds */
|
|
193
|
+
swr?: number;
|
|
194
|
+
/** Cache tags for invalidation */
|
|
195
|
+
tags?: string[];
|
|
134
196
|
}
|
|
135
197
|
|
|
136
198
|
/**
|
|
@@ -151,7 +213,10 @@ export interface SerializedSegmentData {
|
|
|
151
213
|
/** RSC-encoded loaderDataPromise (if present) */
|
|
152
214
|
encodedLoaderDataPromise?: string;
|
|
153
215
|
/** Segment metadata (everything except component, layout, loading, and loader data) */
|
|
154
|
-
metadata: Omit<
|
|
216
|
+
metadata: Omit<
|
|
217
|
+
ResolvedSegment,
|
|
218
|
+
"component" | "layout" | "loading" | "loaderData" | "loaderDataPromise"
|
|
219
|
+
>;
|
|
155
220
|
}
|
|
156
221
|
|
|
157
222
|
/**
|
|
@@ -234,7 +299,6 @@ export interface CachedEntryResult {
|
|
|
234
299
|
handles: Record<string, SegmentHandleData>;
|
|
235
300
|
}
|
|
236
301
|
|
|
237
|
-
|
|
238
302
|
/**
|
|
239
303
|
* Segment cache provider interface
|
|
240
304
|
*
|
|
@@ -262,7 +326,7 @@ export interface SegmentCacheProvider {
|
|
|
262
326
|
restore(
|
|
263
327
|
cacheKey: string,
|
|
264
328
|
params: Record<string, string>,
|
|
265
|
-
loaderPromises: Map<string, Promise<any
|
|
329
|
+
loaderPromises: Map<string, Promise<any>>,
|
|
266
330
|
): Promise<[ResolvedSegment[], string[]] | null>;
|
|
267
331
|
|
|
268
332
|
/**
|
|
@@ -276,117 +340,3 @@ export interface SegmentCacheProvider {
|
|
|
276
340
|
*/
|
|
277
341
|
cacheEntry(cacheKey: string, segments: ResolvedSegment[]): void;
|
|
278
342
|
}
|
|
279
|
-
|
|
280
|
-
// ============================================================================
|
|
281
|
-
// Generic Cache Store (for future extensibility)
|
|
282
|
-
// ============================================================================
|
|
283
|
-
// These types support a general-purpose cache interface that can be used
|
|
284
|
-
// for caching arbitrary values (responses, streams, objects). Currently,
|
|
285
|
-
// the segment caching system uses SegmentCacheStore directly, but these
|
|
286
|
-
// types enable future use cases like response caching or data caching.
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Supported cache value types for the generic CacheStore interface.
|
|
290
|
-
* @internal Reserved for future extensibility
|
|
291
|
-
*/
|
|
292
|
-
export type CacheValue =
|
|
293
|
-
| ReadableStream<Uint8Array>
|
|
294
|
-
| Response
|
|
295
|
-
| ArrayBuffer
|
|
296
|
-
| string
|
|
297
|
-
| unknown[] // JSON-serializable array
|
|
298
|
-
| Record<string, unknown>; // JSON-serializable object
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Cache entry returned by match().
|
|
302
|
-
* @internal Reserved for future extensibility
|
|
303
|
-
*/
|
|
304
|
-
export interface CacheEntry<T = CacheValue> {
|
|
305
|
-
/** The cached value */
|
|
306
|
-
value: T;
|
|
307
|
-
/** Optional metadata stored with the entry */
|
|
308
|
-
metadata?: CacheMetadata;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Original value type for reconstruction.
|
|
313
|
-
* @internal Reserved for future extensibility
|
|
314
|
-
*/
|
|
315
|
-
export type CacheValueType =
|
|
316
|
-
| "stream"
|
|
317
|
-
| "response"
|
|
318
|
-
| "arraybuffer"
|
|
319
|
-
| "string"
|
|
320
|
-
| "object";
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Metadata associated with a cache entry.
|
|
324
|
-
* @internal Reserved for future extensibility
|
|
325
|
-
*/
|
|
326
|
-
export interface CacheMetadata {
|
|
327
|
-
/** Timestamp when entry expires (ms since epoch) */
|
|
328
|
-
expiresAt?: number;
|
|
329
|
-
/** Tags for bulk invalidation */
|
|
330
|
-
tags?: string[];
|
|
331
|
-
/** Original value type for reconstruction on read */
|
|
332
|
-
valueType?: CacheValueType;
|
|
333
|
-
/** Response headers (preserved when caching Response) */
|
|
334
|
-
responseHeaders?: Record<string, string>;
|
|
335
|
-
/** Response status (preserved when caching Response) */
|
|
336
|
-
responseStatus?: number;
|
|
337
|
-
/** Custom metadata */
|
|
338
|
-
[key: string]: unknown;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Options for put().
|
|
343
|
-
* @internal Reserved for future extensibility
|
|
344
|
-
*/
|
|
345
|
-
export interface CachePutOptions {
|
|
346
|
-
/** Time-to-live in seconds */
|
|
347
|
-
ttl?: number;
|
|
348
|
-
/** Metadata to store with entry */
|
|
349
|
-
metadata?: Omit<CacheMetadata, "expiresAt">;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Generic cache store interface for arbitrary value types.
|
|
354
|
-
*
|
|
355
|
-
* This interface is designed for future extensibility to support caching
|
|
356
|
-
* responses, streams, and other values. Currently, segment caching uses
|
|
357
|
-
* the SegmentCacheStore interface directly.
|
|
358
|
-
*
|
|
359
|
-
* Implementations must handle:
|
|
360
|
-
* - Stream values (clone before storing, streams can only be read once)
|
|
361
|
-
* - Promise values (await before storing)
|
|
362
|
-
* - Expiration/TTL
|
|
363
|
-
*
|
|
364
|
-
* @internal Reserved for future extensibility
|
|
365
|
-
*/
|
|
366
|
-
export interface CacheStore {
|
|
367
|
-
/**
|
|
368
|
-
* Retrieve a cached entry by key.
|
|
369
|
-
* @param key - Cache key
|
|
370
|
-
* @returns The cached entry or undefined if not found/expired
|
|
371
|
-
*/
|
|
372
|
-
match<T = CacheValue>(key: string): Promise<CacheEntry<T> | undefined>;
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Store a value in the cache.
|
|
376
|
-
* @param key - Cache key
|
|
377
|
-
* @param value - Value to cache (stream, response, string, object, etc.)
|
|
378
|
-
* @param options - TTL, metadata, etc.
|
|
379
|
-
*/
|
|
380
|
-
put<T extends CacheValue>(
|
|
381
|
-
key: string,
|
|
382
|
-
value: T,
|
|
383
|
-
options?: CachePutOptions
|
|
384
|
-
): Promise<void>;
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Delete a cached entry.
|
|
388
|
-
* @param key - Cache key
|
|
389
|
-
* @returns true if entry was deleted, false if not found
|
|
390
|
-
*/
|
|
391
|
-
delete(key: string): Promise<boolean>;
|
|
392
|
-
}
|
package/src/client.rsc.tsx
CHANGED
|
@@ -17,7 +17,6 @@ export {
|
|
|
17
17
|
OutletProvider,
|
|
18
18
|
useOutlet,
|
|
19
19
|
useLoader,
|
|
20
|
-
useLoaderData,
|
|
21
20
|
ErrorBoundary,
|
|
22
21
|
type ErrorBoundaryProps,
|
|
23
22
|
} from "./client.js";
|
|
@@ -64,6 +63,8 @@ export { Meta } from "./handles/meta.js";
|
|
|
64
63
|
// MetaTags is a "use client" component that can be imported from RSC
|
|
65
64
|
export { MetaTags } from "./handles/MetaTags.js";
|
|
66
65
|
export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
|
|
66
|
+
// Breadcrumbs handle works in RSC context
|
|
67
|
+
export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
|
|
67
68
|
|
|
68
69
|
// Location state - createLocationState works in RSC (just creates definition)
|
|
69
70
|
// useLocationState is NOT exported here as it uses client hooks
|
|
@@ -71,6 +72,7 @@ export {
|
|
|
71
72
|
createLocationState,
|
|
72
73
|
type LocationStateDefinition,
|
|
73
74
|
type LocationStateEntry,
|
|
75
|
+
type LocationStateOptions,
|
|
74
76
|
} from "./browser/react/location-state-shared.js";
|
|
75
77
|
|
|
76
78
|
// Re-export useHref - it's a "use client" hook
|
package/src/client.tsx
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
RouteContentWrapper,
|
|
21
21
|
LoaderBoundary,
|
|
22
22
|
} from "./route-content-wrapper.js";
|
|
23
|
+
import { OutletProvider } from "./outlet-provider.js";
|
|
24
|
+
import { MountContextProvider } from "./browser/react/mount-context.js";
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* Outlet component - renders child content in layouts
|
|
@@ -86,6 +88,8 @@ export function Outlet({ name }: { name?: `@${string}` } = {}): ReactNode {
|
|
|
86
88
|
content = segment.component ?? null;
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
let result: ReactNode;
|
|
92
|
+
|
|
89
93
|
// If segment has a layout, wrap appropriately
|
|
90
94
|
if (segment.layout) {
|
|
91
95
|
// Check if this segment has loaders that need streaming
|
|
@@ -105,25 +109,23 @@ export function Outlet({ name }: { name?: `@${string}` } = {}): ReactNode {
|
|
|
105
109
|
</LoaderBoundary>
|
|
106
110
|
);
|
|
107
111
|
|
|
108
|
-
|
|
112
|
+
result = (
|
|
109
113
|
<OutletProvider content={loaderAwareContent} segment={segment}>
|
|
110
114
|
{segment.layout}
|
|
111
115
|
</OutletProvider>
|
|
112
116
|
);
|
|
117
|
+
} else {
|
|
118
|
+
// No loaders - wrap in OutletProvider so layout can use <Outlet />
|
|
119
|
+
result = (
|
|
120
|
+
<OutletProvider content={content} segment={segment}>
|
|
121
|
+
{segment.layout}
|
|
122
|
+
</OutletProvider>
|
|
123
|
+
);
|
|
113
124
|
}
|
|
114
|
-
|
|
115
|
-
// No loaders - wrap
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
{segment.layout}
|
|
119
|
-
</OutletProvider>
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// No layout but has loaders - wrap content with LoaderBoundary for useLoader context
|
|
124
|
-
// This is common for intercept routes that use useLoader without a custom layout
|
|
125
|
-
if (segment.loaderDataPromise && segment.loaderIds) {
|
|
126
|
-
return (
|
|
125
|
+
} else if (segment.loaderDataPromise && segment.loaderIds) {
|
|
126
|
+
// No layout but has loaders - wrap content with LoaderBoundary for useLoader context
|
|
127
|
+
// This is common for intercept routes that use useLoader without a custom layout
|
|
128
|
+
result = (
|
|
127
129
|
<LoaderBoundary
|
|
128
130
|
loaderDataPromise={segment.loaderDataPromise}
|
|
129
131
|
loaderIds={segment.loaderIds}
|
|
@@ -135,9 +137,20 @@ export function Outlet({ name }: { name?: `@${string}` } = {}): ReactNode {
|
|
|
135
137
|
{content}
|
|
136
138
|
</LoaderBoundary>
|
|
137
139
|
);
|
|
140
|
+
} else {
|
|
141
|
+
result = content;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Wrap with MountContextProvider for include() scoped parallel/intercept slots
|
|
145
|
+
if (segment.mountPath) {
|
|
146
|
+
return (
|
|
147
|
+
<MountContextProvider value={segment.mountPath}>
|
|
148
|
+
{result}
|
|
149
|
+
</MountContextProvider>
|
|
150
|
+
);
|
|
138
151
|
}
|
|
139
152
|
|
|
140
|
-
return
|
|
153
|
+
return result;
|
|
141
154
|
}
|
|
142
155
|
|
|
143
156
|
// Default: render child content
|
|
@@ -201,6 +214,8 @@ export function ParallelOutlet({ name }: { name: `@${string}` }): ReactNode {
|
|
|
201
214
|
content = segment.component ?? null;
|
|
202
215
|
}
|
|
203
216
|
|
|
217
|
+
let result: ReactNode;
|
|
218
|
+
|
|
204
219
|
// If segment has a layout, wrap appropriately
|
|
205
220
|
if (segment.layout) {
|
|
206
221
|
// Check if this segment has loaders that need streaming
|
|
@@ -219,25 +234,23 @@ export function ParallelOutlet({ name }: { name: `@${string}` }): ReactNode {
|
|
|
219
234
|
</LoaderBoundary>
|
|
220
235
|
);
|
|
221
236
|
|
|
222
|
-
|
|
237
|
+
result = (
|
|
223
238
|
<OutletProvider content={loaderAwareContent} segment={segment}>
|
|
224
239
|
{segment.layout}
|
|
225
240
|
</OutletProvider>
|
|
226
241
|
);
|
|
242
|
+
} else {
|
|
243
|
+
// No loaders - wrap in OutletProvider so layout can use <Outlet />
|
|
244
|
+
result = (
|
|
245
|
+
<OutletProvider content={content} segment={segment}>
|
|
246
|
+
{segment.layout}
|
|
247
|
+
</OutletProvider>
|
|
248
|
+
);
|
|
227
249
|
}
|
|
228
|
-
|
|
229
|
-
// No loaders - wrap
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{segment.layout}
|
|
233
|
-
</OutletProvider>
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// No layout but has loaders - wrap content with LoaderBoundary for useLoader context
|
|
238
|
-
// This is common for intercept routes that use useLoader without a custom layout
|
|
239
|
-
if (segment.loaderDataPromise && segment.loaderIds) {
|
|
240
|
-
return (
|
|
250
|
+
} else if (segment.loaderDataPromise && segment.loaderIds) {
|
|
251
|
+
// No layout but has loaders - wrap content with LoaderBoundary for useLoader context
|
|
252
|
+
// This is common for intercept routes that use useLoader without a custom layout
|
|
253
|
+
result = (
|
|
241
254
|
<LoaderBoundary
|
|
242
255
|
loaderDataPromise={segment.loaderDataPromise}
|
|
243
256
|
loaderIds={segment.loaderIds}
|
|
@@ -249,51 +262,28 @@ export function ParallelOutlet({ name }: { name: `@${string}` }): ReactNode {
|
|
|
249
262
|
{content}
|
|
250
263
|
</LoaderBoundary>
|
|
251
264
|
);
|
|
265
|
+
} else {
|
|
266
|
+
result = content;
|
|
252
267
|
}
|
|
253
268
|
|
|
254
|
-
|
|
255
|
-
|
|
269
|
+
// Wrap with MountContextProvider for include() scoped parallel/intercept slots
|
|
270
|
+
if (segment.mountPath) {
|
|
271
|
+
return (
|
|
272
|
+
<MountContextProvider value={segment.mountPath}>
|
|
273
|
+
{result}
|
|
274
|
+
</MountContextProvider>
|
|
275
|
+
);
|
|
276
|
+
}
|
|
256
277
|
|
|
257
|
-
|
|
258
|
-
* Provider for outlet content - used internally by renderSegments
|
|
259
|
-
*
|
|
260
|
-
* Stores a reference to parent context so useLoader can walk up the chain
|
|
261
|
-
* to find loader data from parent layouts. If this segment defines a loading
|
|
262
|
-
* component, Outlet will wrap content with Suspense using that as fallback.
|
|
263
|
-
*/
|
|
264
|
-
export function OutletProvider({
|
|
265
|
-
content,
|
|
266
|
-
parallel,
|
|
267
|
-
segment,
|
|
268
|
-
loaderData,
|
|
269
|
-
children,
|
|
270
|
-
}: {
|
|
271
|
-
content: ReactNode;
|
|
272
|
-
parallel?: ResolvedSegment[];
|
|
273
|
-
segment?: ResolvedSegment;
|
|
274
|
-
loaderData?: Record<string, any>;
|
|
275
|
-
children: ReactNode;
|
|
276
|
-
}): ReactNode {
|
|
277
|
-
// Get parent context to enable walking up the chain for loader lookups
|
|
278
|
-
const parentContext = useContext(OutletContext);
|
|
279
|
-
|
|
280
|
-
const value = useMemo(
|
|
281
|
-
() => ({
|
|
282
|
-
content,
|
|
283
|
-
parallel,
|
|
284
|
-
segment,
|
|
285
|
-
loaderData,
|
|
286
|
-
parent: parentContext,
|
|
287
|
-
loading: segment?.loading,
|
|
288
|
-
}),
|
|
289
|
-
[content, parallel, segment, loaderData, parentContext]
|
|
290
|
-
);
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<OutletContext.Provider value={value}>{children}</OutletContext.Provider>
|
|
294
|
-
);
|
|
278
|
+
return result;
|
|
295
279
|
}
|
|
296
280
|
|
|
281
|
+
// OutletProvider is defined in outlet-provider.tsx to break a circular
|
|
282
|
+
// dependency between client.tsx and route-content-wrapper.tsx.
|
|
283
|
+
// Imported at the top of this file for local use in Outlet/ParallelOutlet,
|
|
284
|
+
// and re-exported here for backwards compatibility.
|
|
285
|
+
export { OutletProvider };
|
|
286
|
+
|
|
297
287
|
/**
|
|
298
288
|
* Hook to access outlet content programmatically
|
|
299
289
|
*
|
|
@@ -323,52 +313,6 @@ export {
|
|
|
323
313
|
type UseLoaderOptions,
|
|
324
314
|
} from "./use-loader.js";
|
|
325
315
|
|
|
326
|
-
/**
|
|
327
|
-
* Hook to access all loader data in the current context
|
|
328
|
-
*
|
|
329
|
-
* Returns a record of all loader data available in the current outlet context
|
|
330
|
-
* and all parent contexts. Useful for debugging or when you need access to
|
|
331
|
-
* multiple loaders.
|
|
332
|
-
*
|
|
333
|
-
* @returns Record of loader name to data, or empty object if no loaders
|
|
334
|
-
*
|
|
335
|
-
* @example
|
|
336
|
-
* ```tsx
|
|
337
|
-
* "use client";
|
|
338
|
-
* import { useLoaderData } from "rsc-router/client";
|
|
339
|
-
*
|
|
340
|
-
* export function DebugPanel() {
|
|
341
|
-
* const loaderData = useLoaderData();
|
|
342
|
-
* return <pre>{JSON.stringify(loaderData, null, 2)}</pre>;
|
|
343
|
-
* }
|
|
344
|
-
* ```
|
|
345
|
-
*/
|
|
346
|
-
export function useLoaderData(): Record<string, any> {
|
|
347
|
-
const context = useContext(OutletContext);
|
|
348
|
-
|
|
349
|
-
// Collect all loader data from the context chain
|
|
350
|
-
// Child loaders override parent loaders with the same name
|
|
351
|
-
const result: Record<string, any> = {};
|
|
352
|
-
const stack: OutletContextValue[] = [];
|
|
353
|
-
|
|
354
|
-
// Build stack from current to root
|
|
355
|
-
let current: OutletContextValue | null | undefined = context;
|
|
356
|
-
while (current) {
|
|
357
|
-
stack.push(current);
|
|
358
|
-
current = current.parent;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
// Apply from root to current (so children override parents)
|
|
362
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
363
|
-
const ctx = stack[i];
|
|
364
|
-
if (ctx.loaderData) {
|
|
365
|
-
Object.assign(result, ctx.loaderData);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
return result;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
316
|
/**
|
|
373
317
|
* Client-safe createLoader factory
|
|
374
318
|
*
|
|
@@ -398,13 +342,13 @@ export function useLoaderData(): Record<string, any> {
|
|
|
398
342
|
*/
|
|
399
343
|
// Overload 1: With function only (not fetchable)
|
|
400
344
|
export function createLoader<T>(
|
|
401
|
-
fn: LoaderFn<T, Record<string, string | undefined>, any
|
|
345
|
+
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
402
346
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
403
347
|
|
|
404
348
|
// Overload 2: With function and fetchable flag
|
|
405
349
|
export function createLoader<T>(
|
|
406
350
|
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
407
|
-
fetchable: true
|
|
351
|
+
fetchable: true,
|
|
408
352
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
409
353
|
|
|
410
354
|
// Implementation - function is ignored at runtime on client
|
|
@@ -412,7 +356,7 @@ export function createLoader<T>(
|
|
|
412
356
|
export function createLoader(
|
|
413
357
|
_fn: LoaderFn<any, Record<string, string | undefined>, any>,
|
|
414
358
|
_fetchable?: true,
|
|
415
|
-
__injectedId?: string
|
|
359
|
+
__injectedId?: string,
|
|
416
360
|
): LoaderDefinition<any, Record<string, string | undefined>> {
|
|
417
361
|
return {
|
|
418
362
|
__brand: "loader",
|
|
@@ -534,11 +478,16 @@ export class ErrorBoundary extends Component<
|
|
|
534
478
|
// ============================================================================
|
|
535
479
|
|
|
536
480
|
// Navigation hooks
|
|
537
|
-
export {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
} from "./browser/react/use-
|
|
481
|
+
export { useNavigation } from "./browser/react/use-navigation.js";
|
|
482
|
+
export { useRouter } from "./browser/react/use-router.js";
|
|
483
|
+
export { usePathname } from "./browser/react/use-pathname.js";
|
|
484
|
+
export { useSearchParams } from "./browser/react/use-search-params.js";
|
|
485
|
+
export { useParams } from "./browser/react/use-params.js";
|
|
486
|
+
export type {
|
|
487
|
+
RouterInstance,
|
|
488
|
+
RouterNavigateOptions,
|
|
489
|
+
ReadonlyURLSearchParams,
|
|
490
|
+
} from "./browser/types.js";
|
|
542
491
|
|
|
543
492
|
// Action state tracking hook
|
|
544
493
|
export {
|
|
@@ -595,6 +544,7 @@ export { useHandle } from "./browser/react/use-handle.js";
|
|
|
595
544
|
export { Meta } from "./handles/meta.js";
|
|
596
545
|
export { MetaTags } from "./handles/MetaTags.js";
|
|
597
546
|
export type { MetaDescriptor, MetaDescriptorBase } from "./router/types.js";
|
|
547
|
+
export { Breadcrumbs, type BreadcrumbItem } from "./handles/breadcrumbs.js";
|
|
598
548
|
|
|
599
549
|
// Location state - type-safe navigation state
|
|
600
550
|
export {
|
|
@@ -602,10 +552,16 @@ export {
|
|
|
602
552
|
useLocationState,
|
|
603
553
|
type LocationStateDefinition,
|
|
604
554
|
type LocationStateEntry,
|
|
555
|
+
type LocationStateOptions,
|
|
605
556
|
} from "./browser/react/location-state.js";
|
|
606
557
|
|
|
607
558
|
// Type-safe href for client-side path validation
|
|
608
|
-
export {
|
|
559
|
+
export {
|
|
560
|
+
href,
|
|
561
|
+
type ValidPaths,
|
|
562
|
+
type PatternToPath,
|
|
563
|
+
type PathResponse,
|
|
564
|
+
} from "./href-client.js";
|
|
609
565
|
|
|
610
566
|
// Response envelope types for consuming JSON response routes
|
|
611
567
|
export type { ResponseEnvelope, ResponseError } from "./urls.js";
|
|
@@ -624,8 +580,10 @@ export type { ResponseEnvelope, ResponseError } from "./urls.js";
|
|
|
624
580
|
* ```
|
|
625
581
|
*/
|
|
626
582
|
export function isResponseError<T>(
|
|
627
|
-
result: import("./urls.js").ResponseEnvelope<T
|
|
628
|
-
): result is import("./urls.js").ResponseEnvelope<T> & {
|
|
583
|
+
result: import("./urls.js").ResponseEnvelope<T>,
|
|
584
|
+
): result is import("./urls.js").ResponseEnvelope<T> & {
|
|
585
|
+
error: import("./urls.js").ResponseError;
|
|
586
|
+
} {
|
|
629
587
|
return result.error !== undefined;
|
|
630
588
|
}
|
|
631
589
|
|
package/src/component-utils.ts
CHANGED
|
@@ -33,7 +33,7 @@ const CLIENT_REFERENCE = Symbol.for("react.client.reference");
|
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export function isClientComponent(
|
|
36
|
-
component: ComponentType<unknown> | unknown
|
|
36
|
+
component: ComponentType<unknown> | unknown,
|
|
37
37
|
): boolean {
|
|
38
38
|
if (typeof component !== "function") {
|
|
39
39
|
return false;
|
|
@@ -52,13 +52,13 @@ export function isClientComponent(
|
|
|
52
52
|
*/
|
|
53
53
|
export function assertClientComponent(
|
|
54
54
|
component: ComponentType<unknown> | unknown,
|
|
55
|
-
name: string
|
|
55
|
+
name: string,
|
|
56
56
|
): asserts component is ComponentType<unknown> {
|
|
57
57
|
if (typeof component !== "function") {
|
|
58
58
|
throw new Error(
|
|
59
59
|
`${name} must be a client component function with "use client" directive. ` +
|
|
60
60
|
`Make sure to pass the component itself, not a JSX element: ` +
|
|
61
|
-
`${name}: My${capitalize(name)} (correct) vs ${name}: <My${capitalize(name)} /> (incorrect)
|
|
61
|
+
`${name}: My${capitalize(name)} (correct) vs ${name}: <My${capitalize(name)} /> (incorrect)`,
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -66,7 +66,7 @@ export function assertClientComponent(
|
|
|
66
66
|
throw new Error(
|
|
67
67
|
`${name} must be a client component with "use client" directive at the top of the file. ` +
|
|
68
68
|
`Server components cannot be used as the ${name} because their function reference ` +
|
|
69
|
-
`cannot be serialized in the RSC payload. Add "use client" to your ${name} file
|
|
69
|
+
`cannot be serialized in the RSC payload. Add "use client" to your ${name} file.`,
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -11,7 +11,11 @@ import { MetaTags } from "../handles/MetaTags.js";
|
|
|
11
11
|
* Uses suppressHydrationWarning on <html> because the theme script
|
|
12
12
|
* may modify class/style attributes before React hydrates.
|
|
13
13
|
*/
|
|
14
|
-
export function DefaultDocument({
|
|
14
|
+
export function DefaultDocument({
|
|
15
|
+
children,
|
|
16
|
+
}: {
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}): ReactElement {
|
|
15
19
|
return (
|
|
16
20
|
<html lang="en" suppressHydrationWarning>
|
|
17
21
|
<head>
|