@rangojs/router 0.0.0-experimental.8 → 0.0.0-experimental.80
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 +942 -4
- package/dist/bin/rango.js +1689 -0
- package/dist/vite/index.js +4960 -935
- package/package.json +70 -60
- package/skills/breadcrumbs/SKILL.md +250 -0
- package/skills/cache-guide/SKILL.md +294 -0
- package/skills/caching/SKILL.md +93 -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 +167 -0
- package/skills/handler-use/SKILL.md +362 -0
- package/skills/hooks/SKILL.md +334 -72
- package/skills/host-router/SKILL.md +218 -0
- package/skills/intercept/SKILL.md +151 -8
- package/skills/layout/SKILL.md +122 -3
- package/skills/links/SKILL.md +92 -31
- package/skills/loader/SKILL.md +404 -44
- package/skills/middleware/SKILL.md +205 -37
- package/skills/migrate-nextjs/SKILL.md +560 -0
- package/skills/migrate-react-router/SKILL.md +764 -0
- package/skills/mime-routes/SKILL.md +128 -0
- package/skills/parallel/SKILL.md +263 -1
- package/skills/prerender/SKILL.md +685 -0
- package/skills/rango/SKILL.md +87 -16
- package/skills/response-routes/SKILL.md +411 -0
- package/skills/route/SKILL.md +281 -14
- package/skills/router-setup/SKILL.md +210 -32
- package/skills/tailwind/SKILL.md +129 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +328 -89
- package/skills/use-cache/SKILL.md +324 -0
- package/src/__internal.ts +102 -4
- package/src/bin/rango.ts +321 -0
- package/src/browser/action-coordinator.ts +97 -0
- package/src/browser/action-response-classifier.ts +99 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +92 -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 +317 -560
- package/src/browser/navigation-client.ts +206 -68
- package/src/browser/navigation-store.ts +73 -55
- package/src/browser/navigation-transaction.ts +297 -0
- package/src/browser/network-error-handler.ts +61 -0
- package/src/browser/partial-update.ts +343 -316
- package/src/browser/prefetch/cache.ts +216 -0
- package/src/browser/prefetch/fetch.ts +206 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +160 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +112 -0
- package/src/browser/react/Link.tsx +253 -74
- package/src/browser/react/NavigationProvider.tsx +87 -11
- package/src/browser/react/context.ts +11 -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 +30 -126
- package/src/browser/react/use-href.tsx +2 -2
- package/src/browser/react/use-link-status.ts +6 -5
- package/src/browser/react/use-navigation.ts +44 -65
- 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 +76 -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 +214 -58
- package/src/browser/scroll-restoration.ts +127 -52
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +16 -0
- package/src/browser/server-action-bridge.ts +510 -603
- package/src/browser/shallow.ts +6 -1
- package/src/browser/types.ts +141 -48
- package/src/browser/validate-redirect-origin.ts +29 -0
- package/src/build/generate-manifest.ts +235 -24
- package/src/build/generate-route-types.ts +39 -0
- package/src/build/index.ts +13 -0
- package/src/build/route-trie.ts +291 -0
- 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 +418 -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 +618 -0
- package/src/build/route-types/scan-filter.ts +85 -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 +342 -0
- package/src/cache/cache-scope.ts +167 -309
- package/src/cache/cf/cf-cache-store.ts +571 -17
- package/src/cache/cf/index.ts +13 -3
- package/src/cache/document-cache.ts +116 -77
- 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 +153 -0
- package/src/cache/types.ts +72 -122
- package/src/client.rsc.tsx +3 -1
- package/src/client.tsx +135 -301
- package/src/component-utils.ts +4 -4
- package/src/components/DefaultDocument.tsx +5 -1
- package/src/context-var.ts +156 -0
- package/src/debug.ts +19 -9
- package/src/errors.ts +108 -2
- package/src/handle.ts +55 -29
- 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 +119 -29
- package/src/index.rsc.ts +155 -19
- package/src/index.ts +251 -30
- package/src/internal-debug.ts +11 -0
- package/src/loader.rsc.ts +26 -157
- 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 +37 -0
- package/src/prerender/store.ts +186 -0
- package/src/prerender.ts +524 -0
- package/src/reverse.ts +354 -0
- package/src/root-error-boundary.tsx +41 -29
- package/src/route-content-wrapper.tsx +7 -4
- package/src/route-definition/dsl-helpers.ts +1121 -0
- package/src/route-definition/helper-factories.ts +200 -0
- package/src/route-definition/helpers-types.ts +478 -0
- package/src/route-definition/index.ts +55 -0
- package/src/route-definition/redirect.ts +101 -0
- package/src/route-definition/resolve-handler-use.ts +149 -0
- package/src/route-definition.ts +1 -1428
- package/src/route-map-builder.ts +217 -123
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +77 -8
- package/src/router/content-negotiation.ts +215 -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 +438 -86
- package/src/router/intercept-resolution.ts +402 -0
- package/src/router/lazy-includes.ts +237 -0
- package/src/router/loader-resolution.ts +356 -128
- package/src/router/logging.ts +251 -0
- package/src/router/manifest.ts +163 -35
- package/src/router/match-api.ts +555 -0
- package/src/router/match-context.ts +5 -3
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +108 -93
- package/src/router/match-middleware/cache-lookup.ts +460 -10
- package/src/router/match-middleware/cache-store.ts +98 -26
- package/src/router/match-middleware/intercept-resolution.ts +57 -17
- package/src/router/match-middleware/segment-resolution.ts +80 -6
- package/src/router/match-pipelines.ts +10 -45
- package/src/router/match-result.ts +135 -35
- package/src/router/metrics.ts +240 -15
- package/src/router/middleware-cookies.ts +55 -0
- package/src/router/middleware-types.ts +220 -0
- package/src/router/middleware.ts +324 -369
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +211 -43
- package/src/router/prerender-match.ts +502 -0
- package/src/router/preview-match.ts +98 -0
- package/src/router/request-classification.ts +310 -0
- package/src/router/revalidation.ts +137 -38
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +41 -21
- package/src/router/router-interfaces.ts +484 -0
- package/src/router/router-options.ts +618 -0
- package/src/router/router-registry.ts +24 -0
- package/src/router/segment-resolution/fresh.ts +748 -0
- package/src/router/segment-resolution/helpers.ts +268 -0
- package/src/router/segment-resolution/loader-cache.ts +199 -0
- package/src/router/segment-resolution/revalidation.ts +1379 -0
- package/src/router/segment-resolution/static-store.ts +67 -0
- package/src/router/segment-resolution.ts +21 -0
- 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 +239 -0
- package/src/router/types.ts +78 -3
- package/src/router.ts +740 -4252
- package/src/rsc/handler-context.ts +45 -0
- package/src/rsc/handler.ts +907 -797
- package/src/rsc/helpers.ts +140 -6
- package/src/rsc/index.ts +0 -20
- package/src/rsc/loader-fetch.ts +229 -0
- package/src/rsc/manifest-init.ts +90 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +141 -0
- package/src/rsc/progressive-enhancement.ts +391 -0
- package/src/rsc/response-error.ts +37 -0
- package/src/rsc/response-route-handler.ts +347 -0
- package/src/rsc/rsc-rendering.ts +246 -0
- package/src/rsc/runtime-warnings.ts +42 -0
- package/src/rsc/server-action.ts +356 -0
- package/src/rsc/ssr-setup.ts +128 -0
- package/src/rsc/types.ts +46 -11
- package/src/search-params.ts +230 -0
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +134 -36
- package/src/server/context.ts +341 -61
- package/src/server/cookie-store.ts +190 -0
- package/src/server/fetchable-loader-store.ts +37 -0
- package/src/server/handle-store.ts +113 -15
- package/src/server/loader-registry.ts +24 -64
- package/src/server/request-context.ts +607 -81
- package/src/server.ts +35 -130
- package/src/ssr/index.tsx +103 -30
- package/src/static-handler.ts +126 -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 +791 -0
- package/src/types/index.ts +88 -0
- package/src/types/loader-types.ts +210 -0
- package/src/types/route-config.ts +170 -0
- package/src/types/route-entry.ts +120 -0
- package/src/types/segments.ts +150 -0
- package/src/types.ts +1 -1623
- package/src/urls/include-helper.ts +207 -0
- package/src/urls/index.ts +53 -0
- package/src/urls/path-helper-types.ts +372 -0
- package/src/urls/path-helper.ts +364 -0
- package/src/urls/pattern-types.ts +107 -0
- package/src/urls/response-types.ts +116 -0
- package/src/urls/type-extraction.ts +372 -0
- package/src/urls/urls-function.ts +98 -0
- package/src/urls.ts +1 -802
- package/src/use-loader.tsx +161 -81
- package/src/vite/discovery/bundle-postprocess.ts +181 -0
- package/src/vite/discovery/discover-routers.ts +348 -0
- package/src/vite/discovery/prerender-collection.ts +439 -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 +117 -0
- package/src/vite/discovery/virtual-module-codegen.ts +203 -0
- package/src/vite/index.ts +15 -1133
- package/src/vite/plugin-types.ts +103 -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 +299 -0
- package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +209 -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 +786 -0
- package/src/vite/plugins/performance-tracks.ts +88 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -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 +266 -0
- package/src/vite/{virtual-entries.ts → plugins/virtual-entries.ts} +23 -14
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +462 -0
- package/src/vite/router-discovery.ts +918 -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 +221 -0
- package/src/vite/utils/shared-utils.ts +170 -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/href.ts +0 -255
- package/src/server/route-manifest-cache.ts +0 -173
- 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/{version.d.ts → plugins/version.d.ts} +0 -0
package/src/theme/constants.ts
CHANGED
|
@@ -33,7 +33,9 @@ export const THEME_COOKIE: {
|
|
|
33
33
|
* Resolve theme config by applying defaults.
|
|
34
34
|
* Accepts `true` to enable with all defaults, or a config object.
|
|
35
35
|
*/
|
|
36
|
-
export function resolveThemeConfig(
|
|
36
|
+
export function resolveThemeConfig(
|
|
37
|
+
config: ThemeConfig | true,
|
|
38
|
+
): ResolvedThemeConfig {
|
|
37
39
|
// Handle `theme: true` shorthand
|
|
38
40
|
if (config === true) {
|
|
39
41
|
config = {};
|
|
@@ -53,7 +55,8 @@ export function resolveThemeConfig(config: ThemeConfig | true): ResolvedThemeCon
|
|
|
53
55
|
attribute: config.attribute ?? THEME_DEFAULTS.attribute,
|
|
54
56
|
storageKey: config.storageKey ?? THEME_DEFAULTS.storageKey,
|
|
55
57
|
enableSystem: config.enableSystem ?? THEME_DEFAULTS.enableSystem,
|
|
56
|
-
enableColorScheme:
|
|
58
|
+
enableColorScheme:
|
|
59
|
+
config.enableColorScheme ?? THEME_DEFAULTS.enableColorScheme,
|
|
57
60
|
value,
|
|
58
61
|
};
|
|
59
62
|
}
|
package/src/theme/index.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme module exports for @rangojs/router/theme
|
|
3
3
|
*
|
|
4
|
-
* This module provides
|
|
4
|
+
* This module provides the public theme API:
|
|
5
5
|
* - useTheme: Hook for accessing theme state in client components
|
|
6
6
|
* - ThemeProvider: Component for manual theme provider setup (typically not needed)
|
|
7
|
+
* - ThemeScript: FOUC-prevention script component for document/head usage
|
|
7
8
|
* - Types for theme configuration
|
|
8
9
|
*
|
|
9
10
|
* @example
|
|
@@ -43,16 +44,5 @@ export type {
|
|
|
43
44
|
ThemeContextValue,
|
|
44
45
|
} from "./types.js";
|
|
45
46
|
|
|
46
|
-
// Constants
|
|
47
|
-
export { THEME_DEFAULTS, THEME_COOKIE
|
|
48
|
-
|
|
49
|
-
// Script generation (for advanced SSR use cases)
|
|
50
|
-
export { generateThemeScript, getNonceAttribute } from "./theme-script.js";
|
|
51
|
-
|
|
52
|
-
// Context (for advanced use cases)
|
|
53
|
-
export {
|
|
54
|
-
ThemeContext,
|
|
55
|
-
useThemeContext,
|
|
56
|
-
initThemeConfigSync,
|
|
57
|
-
getSSRThemeConfig,
|
|
58
|
-
} from "./theme-context.js";
|
|
47
|
+
// Constants
|
|
48
|
+
export { THEME_DEFAULTS, THEME_COOKIE } from "./constants.js";
|
|
@@ -10,40 +10,14 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { createContext, useContext, type Context } from "react";
|
|
13
|
-
import type {
|
|
13
|
+
import type { ThemeContextValue } from "./types.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* React context for theme state
|
|
17
17
|
* null when theme is not enabled in router config
|
|
18
18
|
*/
|
|
19
|
-
export const ThemeContext: Context<ThemeContextValue | null> =
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* SSR module-level state for theme config.
|
|
23
|
-
* Populated by initThemeConfigSync before React renders.
|
|
24
|
-
* Used by MetaTags during SSR to render the theme script.
|
|
25
|
-
*/
|
|
26
|
-
let ssrThemeConfig: ResolvedThemeConfig | null = null;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Initialize theme config synchronously for SSR.
|
|
30
|
-
* Called before rendering to populate state for MetaTags.
|
|
31
|
-
*
|
|
32
|
-
* @param config - Theme config from router, or null if theme is disabled
|
|
33
|
-
*/
|
|
34
|
-
export function initThemeConfigSync(config: ResolvedThemeConfig | null): void {
|
|
35
|
-
ssrThemeConfig = config;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Get theme config for SSR/hydration.
|
|
40
|
-
* Used by MetaTags to render the theme script.
|
|
41
|
-
*
|
|
42
|
-
* @returns Theme config if available, null otherwise
|
|
43
|
-
*/
|
|
44
|
-
export function getSSRThemeConfig(): ResolvedThemeConfig | null {
|
|
45
|
-
return ssrThemeConfig;
|
|
46
|
-
}
|
|
19
|
+
export const ThemeContext: Context<ThemeContextValue | null> =
|
|
20
|
+
createContext<ThemeContextValue | null>(null);
|
|
47
21
|
|
|
48
22
|
/**
|
|
49
23
|
* Get theme context (internal use)
|
|
@@ -63,7 +37,7 @@ export function requireThemeContext(): ThemeContextValue {
|
|
|
63
37
|
throw new Error(
|
|
64
38
|
"useTheme must be used within a ThemeProvider. " +
|
|
65
39
|
"Make sure theme is enabled in your router config: " +
|
|
66
|
-
"createRouter({ theme: { ... } })"
|
|
40
|
+
"createRouter({ theme: { ... } })",
|
|
67
41
|
);
|
|
68
42
|
}
|
|
69
43
|
return ctx;
|
|
@@ -40,7 +40,8 @@ export function generateThemeScript(config: ResolvedThemeConfig): string {
|
|
|
40
40
|
for (var i = 0; i < cookies.length; i++) {
|
|
41
41
|
var cookie = cookies[i].trim();
|
|
42
42
|
if (cookie.indexOf(storageKey + '=') === 0) {
|
|
43
|
-
return decodeURIComponent(cookie.substring(storageKey.length + 1));
|
|
43
|
+
try { return decodeURIComponent(cookie.substring(storageKey.length + 1)); }
|
|
44
|
+
catch (e) { return cookie.substring(storageKey.length + 1); }
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
// Fall back to localStorage
|
|
@@ -125,23 +126,25 @@ export function generateThemeScript(config: ResolvedThemeConfig): string {
|
|
|
125
126
|
* Removes comments, extra whitespace, and unnecessary newlines
|
|
126
127
|
*/
|
|
127
128
|
function minifyScript(script: string): string {
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
129
|
+
return (
|
|
130
|
+
script
|
|
131
|
+
// Remove single-line comments
|
|
132
|
+
.replace(/\/\/.*$/gm, "")
|
|
133
|
+
// Remove multi-line comments
|
|
134
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
135
|
+
// Remove leading/trailing whitespace from lines
|
|
136
|
+
.split("\n")
|
|
137
|
+
.map((line) => line.trim())
|
|
138
|
+
.filter((line) => line.length > 0)
|
|
139
|
+
.join("")
|
|
140
|
+
// Collapse multiple spaces to single space
|
|
141
|
+
.replace(/\s+/g, " ")
|
|
142
|
+
// Remove spaces around operators and punctuation
|
|
143
|
+
.replace(/\s*([{};,=!<>()[\]+\-*/&|?:])\s*/g, "$1")
|
|
144
|
+
// Add back necessary spaces (e.g., "var x")
|
|
145
|
+
.replace(/(var|function|return|if|for|try|catch|typeof|else)\(/g, "$1 (")
|
|
146
|
+
.replace(/\)([a-zA-Z])/g, ") $1")
|
|
147
|
+
);
|
|
145
148
|
}
|
|
146
149
|
|
|
147
150
|
/**
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error information passed to error boundary fallback components
|
|
5
|
+
*/
|
|
6
|
+
export interface ErrorInfo {
|
|
7
|
+
/** Error message (always available) */
|
|
8
|
+
message: string;
|
|
9
|
+
/** Error name/type (e.g., "RouteNotFoundError", "MiddlewareError") */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Optional error code for programmatic handling */
|
|
12
|
+
code?: string;
|
|
13
|
+
/** Stack trace (only in development) */
|
|
14
|
+
stack?: string;
|
|
15
|
+
/** Original error cause if available */
|
|
16
|
+
cause?: unknown;
|
|
17
|
+
/** Segment ID where the error occurred */
|
|
18
|
+
segmentId: string;
|
|
19
|
+
/** Segment type where the error occurred */
|
|
20
|
+
segmentType:
|
|
21
|
+
| "layout"
|
|
22
|
+
| "route"
|
|
23
|
+
| "parallel"
|
|
24
|
+
| "loader"
|
|
25
|
+
| "middleware"
|
|
26
|
+
| "cache";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Props passed to server-side error boundary fallback components
|
|
31
|
+
*
|
|
32
|
+
* Server error boundaries don't have a reset function since the error
|
|
33
|
+
* occurred during server rendering. Users can navigate away or refresh.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* function ProductErrorFallback({ error }: ErrorBoundaryFallbackProps) {
|
|
38
|
+
* return (
|
|
39
|
+
* <div>
|
|
40
|
+
* <h2>Something went wrong loading the product</h2>
|
|
41
|
+
* <p>{error.message}</p>
|
|
42
|
+
* <a href="/">Go home</a>
|
|
43
|
+
* </div>
|
|
44
|
+
* );
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export interface ErrorBoundaryFallbackProps {
|
|
49
|
+
/** Error information */
|
|
50
|
+
error: ErrorInfo;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Error boundary handler - receives error info and returns fallback UI
|
|
55
|
+
*/
|
|
56
|
+
export type ErrorBoundaryHandler = (
|
|
57
|
+
props: ErrorBoundaryFallbackProps,
|
|
58
|
+
) => ReactNode;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Props passed to client-side error boundary fallback components
|
|
62
|
+
*
|
|
63
|
+
* Client error boundaries have a reset function that clears the error state
|
|
64
|
+
* and re-renders the children.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* function ClientErrorFallback({ error, reset }: ClientErrorBoundaryFallbackProps) {
|
|
69
|
+
* return (
|
|
70
|
+
* <div>
|
|
71
|
+
* <h2>Something went wrong</h2>
|
|
72
|
+
* <p>{error.message}</p>
|
|
73
|
+
* <button onClick={reset}>Try again</button>
|
|
74
|
+
* </div>
|
|
75
|
+
* );
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export interface ClientErrorBoundaryFallbackProps {
|
|
80
|
+
/** Error information */
|
|
81
|
+
error: ErrorInfo;
|
|
82
|
+
/** Function to reset error state and retry rendering */
|
|
83
|
+
reset: () => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Wrapped loader data result for deferred resolution with error handling.
|
|
88
|
+
* When loaders are deferred to client-side resolution, errors need to be
|
|
89
|
+
* wrapped so the client can handle them appropriately.
|
|
90
|
+
*/
|
|
91
|
+
export type LoaderDataResult<T = unknown> =
|
|
92
|
+
| { __loaderResult: true; ok: true; data: T }
|
|
93
|
+
| {
|
|
94
|
+
__loaderResult: true;
|
|
95
|
+
ok: false;
|
|
96
|
+
error: ErrorInfo;
|
|
97
|
+
fallback: ReactNode | null;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Type guard to check if a value is a wrapped loader result
|
|
102
|
+
*/
|
|
103
|
+
export function isLoaderDataResult(value: unknown): value is LoaderDataResult {
|
|
104
|
+
return (
|
|
105
|
+
typeof value === "object" &&
|
|
106
|
+
value !== null &&
|
|
107
|
+
"__loaderResult" in value &&
|
|
108
|
+
(value as any).__loaderResult === true
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Not found information passed to notFound boundary fallback components
|
|
114
|
+
*/
|
|
115
|
+
export interface NotFoundInfo {
|
|
116
|
+
/** Not found message */
|
|
117
|
+
message: string;
|
|
118
|
+
/** Segment ID where notFound was thrown */
|
|
119
|
+
segmentId: string;
|
|
120
|
+
/** Segment type where notFound was thrown */
|
|
121
|
+
segmentType:
|
|
122
|
+
| "layout"
|
|
123
|
+
| "route"
|
|
124
|
+
| "parallel"
|
|
125
|
+
| "loader"
|
|
126
|
+
| "middleware"
|
|
127
|
+
| "cache";
|
|
128
|
+
/** The pathname that triggered the not found */
|
|
129
|
+
pathname?: string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Props passed to notFound boundary fallback components
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* function ProductNotFound({ notFound }: NotFoundBoundaryFallbackProps) {
|
|
138
|
+
* return (
|
|
139
|
+
* <div>
|
|
140
|
+
* <h2>Product Not Found</h2>
|
|
141
|
+
* <p>{notFound.message}</p>
|
|
142
|
+
* <a href="/products">Browse all products</a>
|
|
143
|
+
* </div>
|
|
144
|
+
* );
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export interface NotFoundBoundaryFallbackProps {
|
|
149
|
+
/** Not found information */
|
|
150
|
+
notFound: NotFoundInfo;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* NotFound boundary handler - receives not found info and returns fallback UI
|
|
155
|
+
*/
|
|
156
|
+
export type NotFoundBoundaryHandler = (
|
|
157
|
+
props: NotFoundBoundaryFallbackProps,
|
|
158
|
+
) => ReactNode;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context passed to cache condition/key/tags functions.
|
|
3
|
+
*
|
|
4
|
+
* This is a subset of RequestContext that's guaranteed to be available
|
|
5
|
+
* during cache key generation (before middleware runs).
|
|
6
|
+
*
|
|
7
|
+
* Note: While the full RequestContext is passed, middleware-set variables
|
|
8
|
+
* read via `ctx.get()` may not be populated yet since cache lookup happens
|
|
9
|
+
* before middleware execution.
|
|
10
|
+
*/
|
|
11
|
+
export type { RequestContext as CacheContext } from "../server/request-context.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Cache configuration options for cache() DSL
|
|
15
|
+
*
|
|
16
|
+
* Controls how segments, layouts, and loaders are cached.
|
|
17
|
+
* Cache configuration inherits down the route tree unless overridden.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Basic caching with TTL
|
|
22
|
+
* cache({ ttl: 60 }, () => [
|
|
23
|
+
* layout(<BlogLayout />),
|
|
24
|
+
* route("post/:slug"),
|
|
25
|
+
* ])
|
|
26
|
+
*
|
|
27
|
+
* // With stale-while-revalidate
|
|
28
|
+
* cache({ ttl: 60, swr: 300 }, () => [
|
|
29
|
+
* route("product/:id"),
|
|
30
|
+
* ])
|
|
31
|
+
*
|
|
32
|
+
* // Conditional caching
|
|
33
|
+
* cache({
|
|
34
|
+
* ttl: 300,
|
|
35
|
+
* condition: (ctx) => !ctx.request.headers.get('x-preview'),
|
|
36
|
+
* }, () => [...])
|
|
37
|
+
*
|
|
38
|
+
* // Custom cache key
|
|
39
|
+
* cache({
|
|
40
|
+
* ttl: 300,
|
|
41
|
+
* key: (ctx) => `product-${ctx.params.id}-${ctx.searchParams.get('variant')}`,
|
|
42
|
+
* }, () => [...])
|
|
43
|
+
*
|
|
44
|
+
* // With tags for invalidation
|
|
45
|
+
* cache({
|
|
46
|
+
* ttl: 300,
|
|
47
|
+
* tags: (ctx) => [`product:${ctx.params.id}`, 'products'],
|
|
48
|
+
* }, () => [...])
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export interface CacheOptions<TEnv = unknown> {
|
|
52
|
+
/**
|
|
53
|
+
* Time-to-live in seconds.
|
|
54
|
+
* After this period, cached content is considered stale.
|
|
55
|
+
*/
|
|
56
|
+
ttl: number;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Stale-while-revalidate window in seconds (after TTL).
|
|
60
|
+
* During this window, stale content is served immediately while
|
|
61
|
+
* fresh content is fetched in the background via waitUntil.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* // TTL: 60s, SWR: 300s
|
|
65
|
+
* // 0-60s: FRESH (serve from cache)
|
|
66
|
+
* // 60-360s: STALE (serve from cache, revalidate in background)
|
|
67
|
+
* // 360s+: EXPIRED (cache miss, fetch fresh)
|
|
68
|
+
*/
|
|
69
|
+
swr?: number;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Override the cache store for this boundary.
|
|
73
|
+
* When specified, this boundary and its children use this store
|
|
74
|
+
* instead of the app-level store from handler config.
|
|
75
|
+
*
|
|
76
|
+
* Useful for:
|
|
77
|
+
* - Different backends per route section (memory vs KV vs Redis)
|
|
78
|
+
* - Loader-specific caching strategies
|
|
79
|
+
* - Hot data in fast cache, cold data in larger/slower cache
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const kvStore = new CloudflareKVStore(env.CACHE_KV);
|
|
84
|
+
* const memoryStore = new MemorySegmentCacheStore({ defaults: { ttl: 10 } });
|
|
85
|
+
*
|
|
86
|
+
* // Fast memory cache for hot data
|
|
87
|
+
* cache({ store: memoryStore }, () => [
|
|
88
|
+
* route("dashboard"),
|
|
89
|
+
* ])
|
|
90
|
+
*
|
|
91
|
+
* // KV for larger, less frequently accessed data
|
|
92
|
+
* cache({ store: kvStore, ttl: 3600 }, () => [
|
|
93
|
+
* route("archive/:year"),
|
|
94
|
+
* ])
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
store?: import("../cache/types.js").SegmentCacheStore;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Conditional cache read function.
|
|
101
|
+
* Return false to skip cache for this request (always fetch fresh).
|
|
102
|
+
*
|
|
103
|
+
* Has access to full RequestContext including env, request, params, cookies, etc.
|
|
104
|
+
* Note: Middleware-set variables read via `ctx.get()` may not be populated yet.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* condition: (ctx) => {
|
|
109
|
+
* // Skip cache for preview mode
|
|
110
|
+
* if (ctx.request.headers.get('x-preview')) return false;
|
|
111
|
+
* // Skip cache for authenticated users
|
|
112
|
+
* if (ctx.request.headers.has('authorization')) return false;
|
|
113
|
+
* return true;
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
condition?: (
|
|
118
|
+
ctx: import("../server/request-context.js").RequestContext<TEnv>,
|
|
119
|
+
) => boolean;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Custom cache key function - FULL OVERRIDE.
|
|
123
|
+
* Bypasses default key generation AND store's keyGenerator.
|
|
124
|
+
*
|
|
125
|
+
* Has access to full RequestContext including env, request, params, cookies, etc.
|
|
126
|
+
* Note: Middleware-set variables read via `ctx.get()` may not be populated yet.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* // Include query params in cache key
|
|
131
|
+
* key: (ctx) => `product-${ctx.params.id}-${ctx.searchParams.get('variant')}`
|
|
132
|
+
*
|
|
133
|
+
* // Include env bindings
|
|
134
|
+
* key: (ctx) => `${ctx.env.REGION}:product:${ctx.params.id}`
|
|
135
|
+
*
|
|
136
|
+
* // Include cookies
|
|
137
|
+
* key: (ctx) => `${cookies().get('locale')?.value ?? 'en'}:${ctx.pathname}`
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
key?: (
|
|
141
|
+
ctx: import("../server/request-context.js").RequestContext<TEnv>,
|
|
142
|
+
) => string | Promise<string>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Tags for cache invalidation.
|
|
146
|
+
* Can be a static array or a function that returns tags.
|
|
147
|
+
*
|
|
148
|
+
* Note: Tags are passed through to the store but built-in stores
|
|
149
|
+
* (MemorySegmentCacheStore, CFCacheStore) do not yet index or
|
|
150
|
+
* invalidate by tag. Effective tag-based invalidation requires a
|
|
151
|
+
* custom store implementation with secondary indices.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* // Static tags
|
|
156
|
+
* tags: ['products', 'catalog']
|
|
157
|
+
*
|
|
158
|
+
* // Dynamic tags
|
|
159
|
+
* tags: (ctx) => [`product:${ctx.params.id}`, 'products']
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
tags?:
|
|
163
|
+
| string[]
|
|
164
|
+
| ((
|
|
165
|
+
ctx: import("../server/request-context.js").RequestContext<TEnv>,
|
|
166
|
+
) => string[]);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Partial cache options for cache() DSL.
|
|
171
|
+
*
|
|
172
|
+
* When `ttl` is not specified, it will use the default from cache config.
|
|
173
|
+
* This allows cache() calls to inherit app-level defaults:
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* // App-level default (in handler config)
|
|
178
|
+
* cache: { store: myStore, defaults: { ttl: 60 } }
|
|
179
|
+
*
|
|
180
|
+
* // Route-level (inherits ttl from defaults)
|
|
181
|
+
* cache(() => [
|
|
182
|
+
* route("products"),
|
|
183
|
+
* ])
|
|
184
|
+
*
|
|
185
|
+
* // Override with explicit ttl
|
|
186
|
+
* cache({ ttl: 300 }, () => [...])
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
export type PartialCacheOptions<TEnv = unknown> = Partial<CacheOptions<TEnv>>;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Cache entry configuration stored in EntryData.
|
|
193
|
+
* Represents the resolved cache config for a segment.
|
|
194
|
+
*/
|
|
195
|
+
export interface EntryCacheConfig {
|
|
196
|
+
/** Cache options (false means caching disabled for this entry) - ttl is optional, uses defaults */
|
|
197
|
+
options: PartialCacheOptions | false;
|
|
198
|
+
}
|