@rangojs/router 0.0.0-experimental.8 → 0.0.0-experimental.81
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 +5091 -941
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +61 -52
- 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 +340 -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 +765 -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 +91 -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 +75 -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 +393 -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 +358 -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/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
- package/src/vite/{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 +977 -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
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { parseAst, type Plugin } from "vite";
|
|
2
|
+
import { VIRTUAL_IDS, getVirtualVersionContent } from "./virtual-entries.js";
|
|
3
|
+
|
|
4
|
+
interface ClientModuleSignature {
|
|
5
|
+
key: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function isCodeModule(id: string): boolean {
|
|
9
|
+
return /\.(tsx?|jsx?)($|\?)/.test(id);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function normalizeModuleId(id: string): string {
|
|
13
|
+
return id.split("?", 1)[0];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getClientModuleSignature(
|
|
17
|
+
source: string,
|
|
18
|
+
): ClientModuleSignature | undefined {
|
|
19
|
+
let program: any;
|
|
20
|
+
try {
|
|
21
|
+
program = parseAst(source, { jsx: true });
|
|
22
|
+
} catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let isUseClient = false;
|
|
27
|
+
for (const node of program.body ?? []) {
|
|
28
|
+
if (
|
|
29
|
+
node?.type === "ExpressionStatement" &&
|
|
30
|
+
node.expression?.type === "Literal" &&
|
|
31
|
+
typeof node.expression.value === "string"
|
|
32
|
+
) {
|
|
33
|
+
if (node.expression.value === "use client") {
|
|
34
|
+
isUseClient = true;
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!isUseClient) return undefined;
|
|
42
|
+
|
|
43
|
+
const exports = new Set<string>();
|
|
44
|
+
let hasDefault = false;
|
|
45
|
+
let hasExportAll = false;
|
|
46
|
+
|
|
47
|
+
const collectBindingNames = (pattern: any) => {
|
|
48
|
+
if (!pattern) return;
|
|
49
|
+
if (pattern.type === "Identifier") {
|
|
50
|
+
exports.add(pattern.name);
|
|
51
|
+
} else if (pattern.type === "ObjectPattern") {
|
|
52
|
+
for (const prop of pattern.properties ?? []) {
|
|
53
|
+
if (prop?.type === "RestElement") {
|
|
54
|
+
collectBindingNames(prop.argument);
|
|
55
|
+
} else {
|
|
56
|
+
collectBindingNames(prop?.value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} else if (pattern.type === "ArrayPattern") {
|
|
60
|
+
for (const el of pattern.elements ?? []) {
|
|
61
|
+
if (el?.type === "RestElement") {
|
|
62
|
+
collectBindingNames(el.argument);
|
|
63
|
+
} else {
|
|
64
|
+
collectBindingNames(el);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const collectDeclarationNames = (declaration: any) => {
|
|
71
|
+
if (!declaration) return;
|
|
72
|
+
if (declaration.type === "VariableDeclaration") {
|
|
73
|
+
for (const decl of declaration.declarations ?? []) {
|
|
74
|
+
collectBindingNames(decl?.id);
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
collectBindingNames(declaration.id);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
for (const node of program.body ?? []) {
|
|
82
|
+
if (node?.type === "ExportDefaultDeclaration") {
|
|
83
|
+
hasDefault = true;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (node?.type === "ExportAllDeclaration") {
|
|
87
|
+
hasExportAll = true;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (node?.type !== "ExportNamedDeclaration") continue;
|
|
91
|
+
|
|
92
|
+
collectDeclarationNames(node.declaration);
|
|
93
|
+
|
|
94
|
+
for (const specifier of node.specifiers ?? []) {
|
|
95
|
+
const exportedName =
|
|
96
|
+
specifier?.exported?.name ?? specifier?.exported?.value;
|
|
97
|
+
if (exportedName === "default") {
|
|
98
|
+
hasDefault = true;
|
|
99
|
+
} else if (typeof exportedName === "string") {
|
|
100
|
+
exports.add(exportedName);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
key: JSON.stringify({
|
|
107
|
+
default: hasDefault,
|
|
108
|
+
exportAll: hasExportAll,
|
|
109
|
+
exports: [...exports].sort(),
|
|
110
|
+
}),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Plugin providing rsc-router:version virtual module.
|
|
116
|
+
* Exports VERSION that changes when RSC modules change (dev) or at build time (production).
|
|
117
|
+
*
|
|
118
|
+
* The version is used for:
|
|
119
|
+
* 1. Cache invalidation - CFCacheStore uses VERSION to invalidate stale cache
|
|
120
|
+
* 2. Version mismatch detection - client sends version, server reloads on mismatch
|
|
121
|
+
*
|
|
122
|
+
* In dev mode, the version updates when:
|
|
123
|
+
* - Server starts (initial version)
|
|
124
|
+
* - RSC modules change via HMR (triggers version module invalidation)
|
|
125
|
+
*
|
|
126
|
+
* Client-only HMR changes don't update the version since they don't affect
|
|
127
|
+
* server-rendered content or cached RSC payloads.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
export function createVersionPlugin(): Plugin {
|
|
131
|
+
// Generate version at plugin creation time (build/server start)
|
|
132
|
+
const buildVersion = Date.now().toString(16);
|
|
133
|
+
let currentVersion = buildVersion;
|
|
134
|
+
let isDev = false;
|
|
135
|
+
let server: any = null;
|
|
136
|
+
const clientModuleSignatures = new Map<string, ClientModuleSignature>();
|
|
137
|
+
|
|
138
|
+
let versionCounter = 0;
|
|
139
|
+
const bumpVersion = (reason: string) => {
|
|
140
|
+
// Use timestamp + counter to guarantee uniqueness even when multiple
|
|
141
|
+
// bumps happen within the same millisecond (e.g. cascading HMR events).
|
|
142
|
+
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
143
|
+
console.log(`[rsc-router] ${reason}, version updated: ${currentVersion}`);
|
|
144
|
+
|
|
145
|
+
const rscEnv = server?.environments?.rsc;
|
|
146
|
+
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
147
|
+
"\0" + VIRTUAL_IDS.version,
|
|
148
|
+
);
|
|
149
|
+
if (versionMod) {
|
|
150
|
+
rscEnv.moduleGraph.invalidateModule(versionMod);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
name: "@rangojs/router:version",
|
|
156
|
+
enforce: "pre",
|
|
157
|
+
|
|
158
|
+
configResolved(config) {
|
|
159
|
+
isDev = config.command === "serve";
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
configureServer(devServer) {
|
|
163
|
+
server = devServer;
|
|
164
|
+
|
|
165
|
+
devServer.watcher.on("unlink", (filePath) => {
|
|
166
|
+
if (!isDev) return;
|
|
167
|
+
if (!clientModuleSignatures.has(filePath)) return;
|
|
168
|
+
clientModuleSignatures.delete(filePath);
|
|
169
|
+
bumpVersion("Client module removed");
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
resolveId(id) {
|
|
174
|
+
if (id === VIRTUAL_IDS.version) {
|
|
175
|
+
return "\0" + id;
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
load(id) {
|
|
181
|
+
if (id === "\0" + VIRTUAL_IDS.version) {
|
|
182
|
+
return getVirtualVersionContent(currentVersion);
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
transform(code, id) {
|
|
188
|
+
if (!isDev || !isCodeModule(id)) return null;
|
|
189
|
+
const normalizedId = normalizeModuleId(id);
|
|
190
|
+
if (
|
|
191
|
+
!code.includes("use client") &&
|
|
192
|
+
!clientModuleSignatures.has(normalizedId)
|
|
193
|
+
) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const signature = getClientModuleSignature(code);
|
|
198
|
+
if (signature) {
|
|
199
|
+
clientModuleSignatures.set(normalizedId, signature);
|
|
200
|
+
} else {
|
|
201
|
+
clientModuleSignatures.delete(normalizedId);
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
// Track RSC module changes and update version
|
|
207
|
+
async hotUpdate(ctx) {
|
|
208
|
+
if (!isDev) return;
|
|
209
|
+
|
|
210
|
+
// Check if this is an RSC environment update (not client/ssr)
|
|
211
|
+
// RSC modules affect server-rendered content and cached payloads
|
|
212
|
+
// In Vite 6, environment is accessed via `this.environment`
|
|
213
|
+
const isRscModule = this.environment?.name === "rsc";
|
|
214
|
+
|
|
215
|
+
if (!isRscModule) return;
|
|
216
|
+
|
|
217
|
+
// Skip re-bumping when the version virtual module itself is invalidated
|
|
218
|
+
// (our own bumpVersion() invalidates it, which re-triggers hotUpdate).
|
|
219
|
+
if (
|
|
220
|
+
ctx.modules.length === 1 &&
|
|
221
|
+
ctx.modules[0].id === "\0" + VIRTUAL_IDS.version
|
|
222
|
+
) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (isCodeModule(ctx.file)) {
|
|
227
|
+
const filePath = normalizeModuleId(ctx.file);
|
|
228
|
+
const previousSignature = clientModuleSignatures.get(filePath);
|
|
229
|
+
try {
|
|
230
|
+
const source = await ctx.read();
|
|
231
|
+
const nextSignature = getClientModuleSignature(source);
|
|
232
|
+
if (nextSignature) {
|
|
233
|
+
// "use client" file — compare export signatures.
|
|
234
|
+
// client-component-hmr may have cleared ctx.modules, so we
|
|
235
|
+
// cannot rely on ctx.modules.length for these files.
|
|
236
|
+
clientModuleSignatures.set(filePath, nextSignature);
|
|
237
|
+
if (
|
|
238
|
+
previousSignature &&
|
|
239
|
+
previousSignature.key === nextSignature.key
|
|
240
|
+
) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
clientModuleSignatures.delete(filePath);
|
|
245
|
+
if (!previousSignature) {
|
|
246
|
+
// Not and never was "use client" — use module graph check.
|
|
247
|
+
// ctx.modules is reliable for pure server files (only
|
|
248
|
+
// client-component-hmr clears it for "use client" modules).
|
|
249
|
+
if (ctx.modules.length === 0) return;
|
|
250
|
+
}
|
|
251
|
+
// Was "use client" but directive removed — boundary changed,
|
|
252
|
+
// bump below.
|
|
253
|
+
}
|
|
254
|
+
} catch {
|
|
255
|
+
// Fail open: if we can't read or parse the update, invalidate.
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
// Non-code file (json, css, etc.) — only bump if it's actually
|
|
259
|
+
// referenced by the RSC module graph.
|
|
260
|
+
if (ctx.modules.length === 0) return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
bumpVersion("RSC module changed");
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
@@ -78,20 +78,29 @@ import "virtual:rsc-router/loader-manifest";
|
|
|
78
78
|
// In dev mode, this is a no-op (manifest is populated in-memory by the discovery plugin).
|
|
79
79
|
import "virtual:rsc-router/routes-manifest";
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
// Lazily create the handler on first request so that ESM live bindings
|
|
82
|
+
// have resolved by the time we read \`router\`. During HMR the module may
|
|
83
|
+
// re-evaluate before router.tsx finishes, leaving the import undefined.
|
|
84
|
+
let _handler;
|
|
85
|
+
export default function handler(request, env) {
|
|
86
|
+
if (!_handler) {
|
|
87
|
+
_handler = createRSCHandler({
|
|
88
|
+
router,
|
|
89
|
+
version: VERSION,
|
|
90
|
+
deps: {
|
|
91
|
+
renderToReadableStream,
|
|
92
|
+
decodeReply,
|
|
93
|
+
createTemporaryReferenceSet,
|
|
94
|
+
loadServerAction,
|
|
95
|
+
decodeAction,
|
|
96
|
+
decodeFormState,
|
|
97
|
+
},
|
|
98
|
+
loadSSRModule: () =>
|
|
99
|
+
import.meta.viteRsc.loadModule("ssr", "index"),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return _handler(request, env);
|
|
103
|
+
}
|
|
95
104
|
`.trim();
|
|
96
105
|
}
|
|
97
106
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stub plugin that resolves and provides empty exports for virtual modules
|
|
5
|
+
* that the RSC entry may import but aren't needed for route discovery.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export function createVirtualStubPlugin(): Plugin {
|
|
9
|
+
const STUB_PREFIXES = [
|
|
10
|
+
"virtual:rsc-router/",
|
|
11
|
+
"virtual:entry-",
|
|
12
|
+
"virtual:vite-rsc/",
|
|
13
|
+
];
|
|
14
|
+
return {
|
|
15
|
+
name: "@rangojs/router:virtual-stubs",
|
|
16
|
+
resolveId(id) {
|
|
17
|
+
if (STUB_PREFIXES.some((p) => id.startsWith(p))) {
|
|
18
|
+
return "\0stub:" + id;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
},
|
|
22
|
+
load(id) {
|
|
23
|
+
if (id.startsWith("\0stub:")) {
|
|
24
|
+
return "export default {}";
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|