@rangojs/router 0.0.0-experimental.d20dd405 → 0.0.0-experimental.dacec167
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/README.md +8 -8
- package/dist/bin/rango.js +147 -57
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +914 -485
- package/package.json +55 -11
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +220 -30
- package/skills/caching/SKILL.md +116 -8
- package/skills/composability/SKILL.md +27 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +1 -1
- package/skills/hooks/SKILL.md +196 -21
- package/skills/host-router/SKILL.md +45 -20
- package/skills/intercept/SKILL.md +1 -4
- package/skills/layout/SKILL.md +4 -7
- package/skills/links/SKILL.md +22 -10
- package/skills/loader/SKILL.md +149 -6
- package/skills/middleware/SKILL.md +13 -9
- package/skills/migrate-nextjs/SKILL.md +1 -1
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +3 -6
- package/skills/prerender/SKILL.md +14 -33
- package/skills/rango/SKILL.md +242 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +58 -9
- package/skills/route/SKILL.md +9 -4
- package/skills/router-setup/SKILL.md +3 -3
- package/skills/server-actions/SKILL.md +53 -41
- package/skills/testing/SKILL.md +778 -0
- package/skills/typesafety/SKILL.md +310 -26
- package/skills/use-cache/SKILL.md +34 -5
- package/skills/view-transitions/SKILL.md +85 -3
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +117 -0
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/event-controller.ts +42 -66
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/navigation-bridge.ts +9 -67
- package/src/browser/navigation-client.ts +12 -15
- package/src/browser/navigation-store.ts +7 -8
- package/src/browser/navigation-transaction.ts +10 -28
- package/src/browser/partial-update.ts +8 -16
- package/src/browser/react/NavigationProvider.tsx +55 -65
- package/src/browser/react/location-state-shared.ts +175 -4
- package/src/browser/react/location-state.ts +39 -13
- package/src/browser/react/use-handle.ts +17 -9
- package/src/browser/react/use-params.ts +3 -4
- package/src/browser/react/use-reverse.ts +19 -12
- package/src/browser/react/use-router.ts +14 -1
- package/src/browser/response-adapter.ts +25 -0
- package/src/browser/rsc-router.tsx +30 -16
- package/src/browser/scroll-restoration.ts +30 -25
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +23 -30
- package/src/browser/types.ts +2 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +60 -35
- package/src/build/generate-route-types.ts +2 -0
- package/src/build/index.ts +2 -0
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +1 -1
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +55 -14
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-scope.ts +28 -42
- package/src/cache/cf/cf-cache-store.ts +49 -6
- package/src/client.tsx +5 -7
- package/src/context-var.ts +5 -5
- package/src/decode-loader-results.ts +36 -0
- package/src/errors.ts +30 -1
- package/src/handle.ts +26 -13
- package/src/host/index.ts +2 -2
- package/src/host/router.ts +129 -57
- package/src/host/types.ts +31 -2
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +136 -19
- package/src/index.rsc.ts +6 -4
- package/src/index.ts +13 -6
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +21 -6
- package/src/loader.ts +3 -10
- package/src/missing-id-error.ts +68 -0
- package/src/prerender.ts +4 -4
- package/src/response-utils.ts +9 -0
- package/src/reverse.ts +16 -13
- package/src/route-content-wrapper.tsx +6 -28
- package/src/route-definition/dsl-helpers.ts +238 -263
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +37 -14
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-types.ts +19 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +15 -2
- package/src/router/error-handling.ts +1 -1
- package/src/router/intercept-resolution.ts +4 -18
- package/src/router/lazy-includes.ts +2 -2
- package/src/router/loader-resolution.ts +16 -2
- package/src/router/match-handlers.ts +62 -20
- package/src/router/match-middleware/cache-lookup.ts +44 -91
- package/src/router/match-middleware/cache-store.ts +3 -2
- package/src/router/match-result.ts +32 -30
- package/src/router/metrics.ts +1 -1
- package/src/router/middleware-types.ts +1 -1
- package/src/router/middleware.ts +46 -78
- package/src/router/prerender-match.ts +1 -1
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +4 -28
- package/src/router/revalidation.ts +43 -1
- package/src/router/router-interfaces.ts +45 -28
- package/src/router/router-options.ts +40 -1
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +19 -6
- package/src/router/segment-resolution/revalidation.ts +19 -6
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/telemetry.ts +99 -0
- package/src/router/types.ts +8 -0
- package/src/router.ts +37 -21
- package/src/rsc/handler-context.ts +2 -2
- package/src/rsc/handler.ts +20 -65
- package/src/rsc/helpers.ts +22 -2
- package/src/rsc/index.ts +1 -1
- package/src/rsc/origin-guard.ts +28 -10
- package/src/rsc/response-route-handler.ts +32 -52
- package/src/rsc/rsc-rendering.ts +27 -53
- package/src/rsc/runtime-warnings.ts +9 -10
- package/src/rsc/server-action.ts +13 -37
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/types.ts +2 -2
- package/src/search-params.ts +4 -4
- package/src/segment-system.tsx +64 -49
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +118 -51
- package/src/server/cookie-store.ts +28 -4
- package/src/server/request-context.ts +10 -0
- package/src/static-handler.ts +1 -1
- package/src/testing/cache-status.ts +166 -0
- package/src/testing/collect-handle.ts +63 -0
- package/src/testing/dispatch.ts +440 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +154 -0
- package/src/testing/e2e/index.ts +149 -0
- package/src/testing/e2e/matchers.ts +51 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +306 -0
- package/src/testing/e2e/server.ts +183 -0
- package/src/testing/flight-matchers.ts +104 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +320 -0
- package/src/testing/flight.entry.ts +39 -0
- package/src/testing/flight.ts +197 -0
- package/src/testing/generated-routes.ts +223 -0
- package/src/testing/index.ts +106 -0
- package/src/testing/internal/context.ts +331 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/render-route.tsx +565 -0
- package/src/testing/run-loader.ts +341 -0
- package/src/testing/run-middleware.ts +188 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +270 -0
- package/src/types/global-namespace.ts +39 -26
- package/src/types/handler-context.ts +56 -11
- package/src/types/index.ts +1 -0
- package/src/types/segments.ts +18 -1
- package/src/urls/include-helper.ts +10 -53
- package/src/urls/index.ts +0 -3
- package/src/urls/path-helper-types.ts +11 -3
- package/src/urls/path-helper.ts +17 -52
- package/src/urls/pattern-types.ts +36 -19
- package/src/urls/response-types.ts +20 -19
- package/src/urls/type-extraction.ts +26 -116
- package/src/urls/urls-function.ts +1 -5
- package/src/use-loader.tsx +413 -42
- package/src/vite/debug.ts +1 -0
- package/src/vite/discovery/bundle-postprocess.ts +6 -6
- package/src/vite/discovery/discover-routers.ts +70 -48
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/prerender-collection.ts +19 -25
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/state.ts +33 -0
- package/src/vite/discovery/virtual-module-codegen.ts +13 -23
- package/src/vite/index.ts +2 -0
- package/src/vite/plugin-types.ts +67 -0
- package/src/vite/plugins/cjs-to-esm.ts +3 -7
- package/src/vite/plugins/client-ref-hashing.ts +12 -1
- package/src/vite/plugins/cloudflare-protocol-stub.ts +1 -1
- package/src/vite/plugins/expose-action-id.ts +2 -2
- package/src/vite/plugins/expose-id-utils.ts +12 -8
- package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
- package/src/vite/plugins/expose-ids/handler-transform.ts +8 -61
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
- package/src/vite/plugins/expose-internal-ids.ts +47 -67
- package/src/vite/plugins/performance-tracks.ts +12 -16
- package/src/vite/plugins/use-cache-transform.ts +13 -11
- package/src/vite/plugins/version-injector.ts +2 -12
- package/src/vite/plugins/version-plugin.ts +59 -2
- package/src/vite/plugins/virtual-entries.ts +2 -2
- package/src/vite/rango.ts +67 -15
- package/src/vite/router-discovery.ts +208 -63
- package/src/vite/utils/ast-handler-extract.ts +15 -15
- package/src/vite/utils/bundle-analysis.ts +4 -2
- package/src/vite/utils/client-chunks.ts +190 -0
- package/src/vite/utils/forward-user-plugins.ts +193 -0
- package/src/vite/utils/manifest-utils.ts +21 -5
- package/src/vite/utils/shared-utils.ts +107 -26
- package/src/browser/action-response-classifier.ts +0 -99
package/dist/vite/index.js
CHANGED
|
@@ -21,8 +21,8 @@ function hashId(filePath, exportName) {
|
|
|
21
21
|
function makeStubId(filePath, exportName, isBuild) {
|
|
22
22
|
return isBuild ? hashId(filePath, exportName) : `${filePath}#${exportName}`;
|
|
23
23
|
}
|
|
24
|
-
function hashInlineId(filePath,
|
|
25
|
-
const input =
|
|
24
|
+
function hashInlineId(filePath, fnName, index) {
|
|
25
|
+
const input = `${filePath}:${fnName}:${index}`;
|
|
26
26
|
return crypto.createHash("sha256").update(input).digest("hex").slice(0, 8);
|
|
27
27
|
}
|
|
28
28
|
function buildExportMap(program) {
|
|
@@ -200,7 +200,8 @@ var NS = {
|
|
|
200
200
|
prerender: "rango:prerender",
|
|
201
201
|
build: "rango:build",
|
|
202
202
|
dev: "rango:dev",
|
|
203
|
-
transform: "rango:transform"
|
|
203
|
+
transform: "rango:transform",
|
|
204
|
+
chunks: "rango:chunks"
|
|
204
205
|
};
|
|
205
206
|
if (process.env.INTERNAL_RANGO_DEBUG) {
|
|
206
207
|
const existing = debugFactory.disable();
|
|
@@ -292,7 +293,7 @@ function getRscPluginApi(config) {
|
|
|
292
293
|
);
|
|
293
294
|
if (plugin) {
|
|
294
295
|
console.warn(
|
|
295
|
-
`[
|
|
296
|
+
`[rango:expose-action-id] RSC plugin found by API structure (name: "${plugin.name}"). Consider updating the name lookup if the plugin was renamed.`
|
|
296
297
|
);
|
|
297
298
|
}
|
|
298
299
|
}
|
|
@@ -393,7 +394,7 @@ function exposeActionId() {
|
|
|
393
394
|
}
|
|
394
395
|
if (!rscPluginApi) {
|
|
395
396
|
throw new Error(
|
|
396
|
-
"[
|
|
397
|
+
"[rango] Could not find @vitejs/plugin-rsc. @rangojs/router requires the Vite RSC plugin, which is included automatically by rango()."
|
|
397
398
|
);
|
|
398
399
|
}
|
|
399
400
|
if (!isBuild) return;
|
|
@@ -465,7 +466,7 @@ function exposeActionId() {
|
|
|
465
466
|
|
|
466
467
|
// src/vite/plugins/expose-internal-ids.ts
|
|
467
468
|
import { parseAst as parseAst2 } from "vite";
|
|
468
|
-
import
|
|
469
|
+
import MagicString3 from "magic-string";
|
|
469
470
|
import path4 from "node:path";
|
|
470
471
|
|
|
471
472
|
// src/vite/utils/ast-handler-extract.ts
|
|
@@ -475,7 +476,7 @@ function isDirectivePrologueStatement(node) {
|
|
|
475
476
|
function findImportInsertionPos(code, parseAst4) {
|
|
476
477
|
let program;
|
|
477
478
|
try {
|
|
478
|
-
program = parseAst4(code, {
|
|
479
|
+
program = parseAst4(code, { lang: "tsx" });
|
|
479
480
|
} catch {
|
|
480
481
|
return 0;
|
|
481
482
|
}
|
|
@@ -515,7 +516,7 @@ function walkNode(node, parent, ancestors, enter) {
|
|
|
515
516
|
function findHandlerCalls(code, fnName, parseAst4) {
|
|
516
517
|
let program;
|
|
517
518
|
try {
|
|
518
|
-
program = parseAst4(code, {
|
|
519
|
+
program = parseAst4(code, { lang: "tsx" });
|
|
519
520
|
} catch {
|
|
520
521
|
return [];
|
|
521
522
|
}
|
|
@@ -589,7 +590,7 @@ function getImportedLocalNamesFromProgram(program, importedName) {
|
|
|
589
590
|
}
|
|
590
591
|
function getImportedLocalNames(code, importedName, parseAst4) {
|
|
591
592
|
try {
|
|
592
|
-
const program = parseAst4(code, {
|
|
593
|
+
const program = parseAst4(code, { lang: "tsx" });
|
|
593
594
|
return getImportedLocalNamesFromProgram(program, importedName);
|
|
594
595
|
} catch {
|
|
595
596
|
return /* @__PURE__ */ new Set();
|
|
@@ -598,7 +599,7 @@ function getImportedLocalNames(code, importedName, parseAst4) {
|
|
|
598
599
|
function extractImportDeclarations(code, parseAst4) {
|
|
599
600
|
let program;
|
|
600
601
|
try {
|
|
601
|
-
program = parseAst4(code, {
|
|
602
|
+
program = parseAst4(code, { lang: "tsx" });
|
|
602
603
|
} catch {
|
|
603
604
|
return [];
|
|
604
605
|
}
|
|
@@ -653,7 +654,7 @@ function isSafeVariableDeclaration(node, handlerNames) {
|
|
|
653
654
|
function extractModuleLevelDeclarations(code, parseAst4, handlerNames) {
|
|
654
655
|
let program;
|
|
655
656
|
try {
|
|
656
|
-
program = parseAst4(code, {
|
|
657
|
+
program = parseAst4(code, { lang: "tsx" });
|
|
657
658
|
} catch {
|
|
658
659
|
return [];
|
|
659
660
|
}
|
|
@@ -697,14 +698,12 @@ function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtu
|
|
|
697
698
|
parseAst4,
|
|
698
699
|
handlerNames
|
|
699
700
|
);
|
|
700
|
-
const lineCounts = /* @__PURE__ */ new Map();
|
|
701
701
|
const importStatements = [];
|
|
702
|
-
for (const site of inlineSites) {
|
|
703
|
-
const
|
|
704
|
-
lineCounts.set(site.lineNumber, lineCount + 1);
|
|
705
|
-
const hash = hashInlineId(filePath, site.lineNumber, lineCount);
|
|
702
|
+
for (const [siteIndex, site] of inlineSites.entries()) {
|
|
703
|
+
const hash = hashInlineId(filePath, fnName, siteIndex);
|
|
706
704
|
const exportName = `__sh_${hash}`;
|
|
707
|
-
const
|
|
705
|
+
const idSuffix = `${filePath}:${fnName}:${siteIndex}`;
|
|
706
|
+
const virtualId = `\0${virtualPrefix}${idSuffix}`;
|
|
708
707
|
const handlerCode = code.slice(site.callStart, site.callEnd);
|
|
709
708
|
virtualRegistry.set(virtualId, {
|
|
710
709
|
originalModuleId: moduleId,
|
|
@@ -714,7 +713,7 @@ function transformInlineHandlers(fnName, virtualPrefix, s, code, filePath, virtu
|
|
|
714
713
|
exportName
|
|
715
714
|
});
|
|
716
715
|
s.overwrite(site.callStart, site.callEnd, exportName);
|
|
717
|
-
const importId = `${virtualPrefix}${
|
|
716
|
+
const importId = `${virtualPrefix}${idSuffix}`;
|
|
718
717
|
importStatements.push(`import { ${exportName} } from "${importId}";`);
|
|
719
718
|
}
|
|
720
719
|
if (importStatements.length > 0) {
|
|
@@ -746,6 +745,83 @@ var STRICT_CREATE_CONFIGS = [
|
|
|
746
745
|
|
|
747
746
|
// src/vite/plugins/expose-ids/export-analysis.ts
|
|
748
747
|
import { parseAst } from "vite";
|
|
748
|
+
|
|
749
|
+
// src/build/route-types/source-scan.ts
|
|
750
|
+
function isLineTerminator(ch) {
|
|
751
|
+
const c = ch.charCodeAt(0);
|
|
752
|
+
return c === 10 || c === 13 || c === 8232 || c === 8233;
|
|
753
|
+
}
|
|
754
|
+
function makeCodeClassifier(code) {
|
|
755
|
+
const n = code.length;
|
|
756
|
+
let i = 0;
|
|
757
|
+
let skipStart = -1;
|
|
758
|
+
let skipEnd = -1;
|
|
759
|
+
return (q) => {
|
|
760
|
+
if (q >= skipStart && q < skipEnd) return false;
|
|
761
|
+
while (i < n && i <= q) {
|
|
762
|
+
const c = code[i];
|
|
763
|
+
const d = i + 1 < n ? code[i + 1] : "";
|
|
764
|
+
let end = -1;
|
|
765
|
+
if (c === "/" && d === "/") {
|
|
766
|
+
let j = i + 2;
|
|
767
|
+
while (j < n && !isLineTerminator(code[j])) j++;
|
|
768
|
+
end = j;
|
|
769
|
+
} else if (c === "/" && d === "*") {
|
|
770
|
+
let j = i + 2;
|
|
771
|
+
while (j < n && !(code[j] === "*" && code[j + 1] === "/")) j++;
|
|
772
|
+
end = Math.min(n, j + 2);
|
|
773
|
+
} else if (c === '"' || c === "'" || c === "`") {
|
|
774
|
+
let j = i + 1;
|
|
775
|
+
while (j < n) {
|
|
776
|
+
if (code[j] === "\\") {
|
|
777
|
+
j += 2;
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
if (code[j] === c) {
|
|
781
|
+
j++;
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
j++;
|
|
785
|
+
}
|
|
786
|
+
end = j;
|
|
787
|
+
}
|
|
788
|
+
if (end >= 0) {
|
|
789
|
+
if (q < end) {
|
|
790
|
+
skipStart = i;
|
|
791
|
+
skipEnd = end;
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
i = end;
|
|
795
|
+
} else {
|
|
796
|
+
i++;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return true;
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function firstCodeMatchIndex(code, pattern) {
|
|
803
|
+
const inCode = makeCodeClassifier(code);
|
|
804
|
+
pattern.lastIndex = 0;
|
|
805
|
+
let m;
|
|
806
|
+
while ((m = pattern.exec(code)) !== null) {
|
|
807
|
+
if (inCode(m.index)) return m.index;
|
|
808
|
+
if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
|
|
809
|
+
}
|
|
810
|
+
return -1;
|
|
811
|
+
}
|
|
812
|
+
function codeMatchIndices(code, pattern) {
|
|
813
|
+
const inCode = makeCodeClassifier(code);
|
|
814
|
+
const indices = [];
|
|
815
|
+
pattern.lastIndex = 0;
|
|
816
|
+
let m;
|
|
817
|
+
while ((m = pattern.exec(code)) !== null) {
|
|
818
|
+
if (inCode(m.index)) indices.push(m.index);
|
|
819
|
+
if (pattern.lastIndex <= m.index) pattern.lastIndex = m.index + 1;
|
|
820
|
+
}
|
|
821
|
+
return indices;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// src/vite/plugins/expose-ids/export-analysis.ts
|
|
749
825
|
function isExportOnlyFile(code, bindings) {
|
|
750
826
|
if (bindings.length === 0) return false;
|
|
751
827
|
const knownLocals = /* @__PURE__ */ new Set();
|
|
@@ -774,12 +850,30 @@ function isExportOnlyFile(code, bindings) {
|
|
|
774
850
|
}
|
|
775
851
|
return true;
|
|
776
852
|
}
|
|
777
|
-
function
|
|
778
|
-
|
|
853
|
+
function createCallPattern(fnNames) {
|
|
854
|
+
return new RegExp(
|
|
779
855
|
`\\b(?:${fnNames.map(escapeRegExp).join("|")})\\s*(?:<[^>]*>\\s*)?\\(`,
|
|
780
856
|
"g"
|
|
781
857
|
);
|
|
782
|
-
|
|
858
|
+
}
|
|
859
|
+
function countCreateCallsForNames(code, fnNames) {
|
|
860
|
+
return codeMatchIndices(code, createCallPattern(fnNames)).length;
|
|
861
|
+
}
|
|
862
|
+
function offsetToLineColumn(code, index) {
|
|
863
|
+
let line = 1;
|
|
864
|
+
let lineStart = 0;
|
|
865
|
+
const end = Math.min(index, code.length);
|
|
866
|
+
for (let i = 0; i < end; i++) {
|
|
867
|
+
if (code[i] === "\n") {
|
|
868
|
+
line++;
|
|
869
|
+
lineStart = i + 1;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return { line, column: index - lineStart + 1 };
|
|
873
|
+
}
|
|
874
|
+
function findUnsupportedCreateCallSites(code, fnNames, supportedBindings) {
|
|
875
|
+
const supported = new Set(supportedBindings.map((b) => b.callExprStart));
|
|
876
|
+
return codeMatchIndices(code, createCallPattern(fnNames)).filter((index) => !supported.has(index)).map((index) => offsetToLineColumn(code, index));
|
|
783
877
|
}
|
|
784
878
|
function getImportedFnNames(code, importedName) {
|
|
785
879
|
const importPattern = /import\s*\{([^}]*)\}\s*from\s*["']@rangojs\/router(?:\/[^"']*)?["']/g;
|
|
@@ -810,6 +904,17 @@ function getCalledIdentifierFromCall(callExpr) {
|
|
|
810
904
|
}
|
|
811
905
|
return null;
|
|
812
906
|
}
|
|
907
|
+
function unwrapSignatureWrappedCall(init, fnNameSet) {
|
|
908
|
+
if (init?.type !== "CallExpression") return init;
|
|
909
|
+
const directId = getCalledIdentifierFromCall(init);
|
|
910
|
+
if (directId && fnNameSet.has(directId)) return init;
|
|
911
|
+
const firstArg = init.arguments?.[0];
|
|
912
|
+
if (firstArg?.type === "CallExpression") {
|
|
913
|
+
const innerId = getCalledIdentifierFromCall(firstArg);
|
|
914
|
+
if (innerId && fnNameSet.has(innerId)) return firstArg;
|
|
915
|
+
}
|
|
916
|
+
return init;
|
|
917
|
+
}
|
|
813
918
|
function collectCreateExportBindingsFallback(code, fnNames) {
|
|
814
919
|
const alternation = fnNames.map(escapeRegExp).join("|");
|
|
815
920
|
const exportConstPattern = new RegExp(
|
|
@@ -869,7 +974,7 @@ function collectCreateExportBindingsFallback(code, fnNames) {
|
|
|
869
974
|
function collectCreateExportBindings(code, fnNames, program) {
|
|
870
975
|
if (!program) {
|
|
871
976
|
try {
|
|
872
|
-
program = parseAst(code, {
|
|
977
|
+
program = parseAst(code, { lang: "tsx" });
|
|
873
978
|
} catch {
|
|
874
979
|
return collectCreateExportBindingsFallback(code, fnNames);
|
|
875
980
|
}
|
|
@@ -882,16 +987,16 @@ function collectCreateExportBindings(code, fnNames, program) {
|
|
|
882
987
|
return;
|
|
883
988
|
}
|
|
884
989
|
for (const decl of varDecl.declarations ?? []) {
|
|
885
|
-
const
|
|
886
|
-
|
|
990
|
+
const callExpr = unwrapSignatureWrappedCall(decl?.init, fnNameSet);
|
|
991
|
+
const calledIdentifier = getCalledIdentifierFromCall(callExpr);
|
|
992
|
+
if (decl?.id?.type !== "Identifier" || callExpr?.type !== "CallExpression" || !calledIdentifier || !fnNameSet.has(calledIdentifier)) {
|
|
887
993
|
continue;
|
|
888
994
|
}
|
|
889
995
|
const localName = decl.id.name;
|
|
890
996
|
const exportNames = exportMap.get(localName) ?? [];
|
|
891
997
|
if (exportNames.length === 0) continue;
|
|
892
|
-
const
|
|
893
|
-
const
|
|
894
|
-
const calleeEnd = decl.init.callee.end;
|
|
998
|
+
const callEnd = callExpr.end;
|
|
999
|
+
const calleeEnd = callExpr.callee.end;
|
|
895
1000
|
let openParenPos = -1;
|
|
896
1001
|
for (let i = calleeEnd; i < callEnd; i++) {
|
|
897
1002
|
if (code[i] === "(") {
|
|
@@ -905,10 +1010,10 @@ function collectCreateExportBindings(code, fnNames, program) {
|
|
|
905
1010
|
bindings.push({
|
|
906
1011
|
localName,
|
|
907
1012
|
exportNames,
|
|
908
|
-
callExprStart:
|
|
1013
|
+
callExprStart: callExpr.start,
|
|
909
1014
|
callOpenParenPos: openParenPos,
|
|
910
1015
|
callCloseParenPos: closeParenPos,
|
|
911
|
-
argCount:
|
|
1016
|
+
argCount: callExpr.arguments?.length ?? 0,
|
|
912
1017
|
statementEnd
|
|
913
1018
|
});
|
|
914
1019
|
}
|
|
@@ -927,9 +1032,20 @@ function collectCreateExportBindings(code, fnNames, program) {
|
|
|
927
1032
|
}
|
|
928
1033
|
return bindings;
|
|
929
1034
|
}
|
|
930
|
-
function buildUnsupportedShapeWarning(filePath, fnName) {
|
|
931
|
-
|
|
932
|
-
|
|
1035
|
+
function buildUnsupportedShapeWarning(filePath, fnName, sites = []) {
|
|
1036
|
+
const lines = [`[rango] Unsupported ${fnName} shape in "${filePath}".`];
|
|
1037
|
+
if (sites.length === 1) {
|
|
1038
|
+
const s = sites[0];
|
|
1039
|
+
lines.push(
|
|
1040
|
+
`The ${fnName}(...) call at ${filePath}:${s.line}:${s.column} has no stable $$id injected \u2014 it is not in a supported shape.`
|
|
1041
|
+
);
|
|
1042
|
+
} else if (sites.length > 1) {
|
|
1043
|
+
lines.push(
|
|
1044
|
+
`These ${fnName}(...) calls have no stable $$id injected \u2014 they are not in a supported shape:`
|
|
1045
|
+
);
|
|
1046
|
+
for (const s of sites) lines.push(` - ${filePath}:${s.line}:${s.column}`);
|
|
1047
|
+
}
|
|
1048
|
+
lines.push(
|
|
933
1049
|
`Supported shapes are:`,
|
|
934
1050
|
` - export const X = ${fnName}(...)`,
|
|
935
1051
|
` - const X = ${fnName}(...); export { X }`,
|
|
@@ -937,7 +1053,8 @@ function buildUnsupportedShapeWarning(filePath, fnName) {
|
|
|
937
1053
|
`Potentially unsupported forms include:`,
|
|
938
1054
|
` - export let/var X = ${fnName}(...)`,
|
|
939
1055
|
` - inline ${fnName}(...) calls`
|
|
940
|
-
|
|
1056
|
+
);
|
|
1057
|
+
return lines.join("\n");
|
|
941
1058
|
}
|
|
942
1059
|
|
|
943
1060
|
// src/vite/plugins/expose-ids/loader-transform.ts
|
|
@@ -951,7 +1068,7 @@ function generateClientLoaderStubs(bindings, code, filePath, isBuild) {
|
|
|
951
1068
|
const lines = [];
|
|
952
1069
|
for (const binding of bindings) {
|
|
953
1070
|
for (const name of binding.exportNames) {
|
|
954
|
-
const loaderId =
|
|
1071
|
+
const loaderId = makeStubId(filePath, name, isBuild);
|
|
955
1072
|
lines.push(
|
|
956
1073
|
`export const ${name} = { __brand: "loader", $$id: "${loaderId}" };`
|
|
957
1074
|
);
|
|
@@ -963,7 +1080,7 @@ function transformLoaders(bindings, s, filePath, isBuild) {
|
|
|
963
1080
|
let hasChanges = false;
|
|
964
1081
|
for (const binding of bindings) {
|
|
965
1082
|
const exportName = binding.exportNames[0];
|
|
966
|
-
const loaderId =
|
|
1083
|
+
const loaderId = makeStubId(filePath, exportName, isBuild);
|
|
967
1084
|
const paramInjection = binding.argCount === 1 ? `, undefined, "${loaderId}"` : `, "${loaderId}"`;
|
|
968
1085
|
s.appendLeft(binding.callCloseParenPos, paramInjection);
|
|
969
1086
|
const propInjection = `
|
|
@@ -975,7 +1092,6 @@ ${binding.localName}.$$id = "${loaderId}";`;
|
|
|
975
1092
|
}
|
|
976
1093
|
|
|
977
1094
|
// src/vite/plugins/expose-ids/handler-transform.ts
|
|
978
|
-
import MagicString2 from "magic-string";
|
|
979
1095
|
function analyzeCreateHandleArgs(code, startPos, endPos) {
|
|
980
1096
|
const content = code.slice(startPos, endPos).trim();
|
|
981
1097
|
return { hasArgs: content.length > 0 };
|
|
@@ -989,7 +1105,7 @@ function transformHandles(bindings, s, code, filePath, isBuild) {
|
|
|
989
1105
|
binding.callOpenParenPos + 1,
|
|
990
1106
|
binding.callCloseParenPos
|
|
991
1107
|
);
|
|
992
|
-
const handleId =
|
|
1108
|
+
const handleId = makeStubId(filePath, exportName, isBuild);
|
|
993
1109
|
let paramInjection;
|
|
994
1110
|
if (!args.hasArgs) {
|
|
995
1111
|
paramInjection = `undefined, "${handleId}"`;
|
|
@@ -1008,7 +1124,7 @@ function transformLocationState(bindings, s, filePath, isBuild) {
|
|
|
1008
1124
|
let hasChanges = false;
|
|
1009
1125
|
for (const binding of bindings) {
|
|
1010
1126
|
const exportName = binding.exportNames[0];
|
|
1011
|
-
const stateKey =
|
|
1127
|
+
const stateKey = makeStubId(filePath, exportName, isBuild);
|
|
1012
1128
|
const propInjection = `
|
|
1013
1129
|
${binding.localName}.__rsc_ls_key = "__rsc_ls_${stateKey}";`;
|
|
1014
1130
|
s.appendRight(binding.statementEnd, propInjection);
|
|
@@ -1020,7 +1136,7 @@ function generateWholeFileStubs(cfg, bindings, code, filePath, isBuild) {
|
|
|
1020
1136
|
if (!isExportOnlyFile(code, bindings)) return null;
|
|
1021
1137
|
const exportNames = bindings.flatMap((b) => b.exportNames);
|
|
1022
1138
|
const stubs = exportNames.map((name) => {
|
|
1023
|
-
const handlerId =
|
|
1139
|
+
const handlerId = makeStubId(filePath, name, isBuild);
|
|
1024
1140
|
return `export const ${name} = { __brand: "${cfg.brand}", $$id: "${handlerId}" };`;
|
|
1025
1141
|
});
|
|
1026
1142
|
return { code: stubs.join("\n") + "\n", map: null };
|
|
@@ -1029,7 +1145,7 @@ function stubHandlerExprs(cfg, bindings, s, filePath, isBuild) {
|
|
|
1029
1145
|
let hasChanges = false;
|
|
1030
1146
|
for (const binding of bindings) {
|
|
1031
1147
|
const exportName = binding.exportNames[0];
|
|
1032
|
-
const handlerId =
|
|
1148
|
+
const handlerId = makeStubId(filePath, exportName, isBuild);
|
|
1033
1149
|
s.overwrite(
|
|
1034
1150
|
binding.callExprStart,
|
|
1035
1151
|
binding.callCloseParenPos + 1,
|
|
@@ -1043,7 +1159,7 @@ function transformHandlerIds(cfg, bindings, s, filePath, isBuild) {
|
|
|
1043
1159
|
let hasChanges = false;
|
|
1044
1160
|
for (const binding of bindings) {
|
|
1045
1161
|
const exportName = binding.exportNames[0];
|
|
1046
|
-
const handlerId =
|
|
1162
|
+
const handlerId = makeStubId(filePath, exportName, isBuild);
|
|
1047
1163
|
let paramInjection;
|
|
1048
1164
|
if (binding.argCount === 0) {
|
|
1049
1165
|
paramInjection = `undefined, "${handlerId}"`;
|
|
@@ -1062,7 +1178,7 @@ ${binding.localName}.$$id = "${handlerId}";`;
|
|
|
1062
1178
|
}
|
|
1063
1179
|
|
|
1064
1180
|
// src/vite/plugins/expose-ids/router-transform.ts
|
|
1065
|
-
import
|
|
1181
|
+
import MagicString2 from "magic-string";
|
|
1066
1182
|
import path3 from "node:path";
|
|
1067
1183
|
import { createHash } from "node:crypto";
|
|
1068
1184
|
var debug2 = createRangoDebugger(NS.transform);
|
|
@@ -1072,10 +1188,10 @@ function transformRouter(code, filePath, routerFnNames, absolutePath) {
|
|
|
1072
1188
|
"g"
|
|
1073
1189
|
);
|
|
1074
1190
|
let match;
|
|
1075
|
-
const s = new
|
|
1191
|
+
const s = new MagicString2(code);
|
|
1076
1192
|
let changed = false;
|
|
1077
|
-
const
|
|
1078
|
-
const routeNamesImport = `./${
|
|
1193
|
+
const basename2 = path3.basename(filePath).replace(/\.(tsx?|jsx?)$/, "");
|
|
1194
|
+
const routeNamesImport = `./${basename2}.named-routes.gen.js`;
|
|
1079
1195
|
const routeNamesVar = `__rsc_rn`;
|
|
1080
1196
|
while ((match = pat.exec(code)) !== null) {
|
|
1081
1197
|
const callStart = match.index;
|
|
@@ -1335,7 +1451,7 @@ ${lazyImports.join(",\n")}
|
|
|
1335
1451
|
}
|
|
1336
1452
|
if (_cachedAst !== void 0 || _astParseFailed) return _cachedAst;
|
|
1337
1453
|
try {
|
|
1338
|
-
_cachedAst = parseAst2(code, {
|
|
1454
|
+
_cachedAst = parseAst2(code, { lang: "tsx" });
|
|
1339
1455
|
} catch {
|
|
1340
1456
|
_astParseFailed = true;
|
|
1341
1457
|
}
|
|
@@ -1358,13 +1474,16 @@ ${lazyImports.join(",\n")}
|
|
|
1358
1474
|
const hasCode = cfg.fnName === "createLoader" ? hasLoaderCode : cfg.fnName === "createHandle" ? hasHandleCode : hasLocationStateCode;
|
|
1359
1475
|
if (!hasCode) continue;
|
|
1360
1476
|
const fnNames = getFnNames(cfg.fnName);
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1477
|
+
const sites = findUnsupportedCreateCallSites(
|
|
1478
|
+
code,
|
|
1479
|
+
fnNames,
|
|
1480
|
+
getBindings(code, fnNames)
|
|
1481
|
+
);
|
|
1482
|
+
if (sites.length === 0) continue;
|
|
1364
1483
|
const warnKey = `${id}::${cfg.fnName}`;
|
|
1365
1484
|
if (unsupportedShapeWarnings.has(warnKey)) continue;
|
|
1366
1485
|
unsupportedShapeWarnings.add(warnKey);
|
|
1367
|
-
this.warn(buildUnsupportedShapeWarning(filePath, cfg.fnName));
|
|
1486
|
+
this.warn(buildUnsupportedShapeWarning(filePath, cfg.fnName, sites));
|
|
1368
1487
|
}
|
|
1369
1488
|
if (hasLoaderCode && isRscEnv) {
|
|
1370
1489
|
const fnNames = getFnNames("createLoader");
|
|
@@ -1401,15 +1520,6 @@ ${lazyImports.join(",\n")}
|
|
|
1401
1520
|
);
|
|
1402
1521
|
if (wholeFile) return wholeFile;
|
|
1403
1522
|
}
|
|
1404
|
-
if (hasPrerenderHandlerCode && isRscEnv && isBuild) {
|
|
1405
|
-
const fnNames = getFnNames(PRERENDER_CONFIG.fnName);
|
|
1406
|
-
const exportNames = getBindings(code, fnNames).map(
|
|
1407
|
-
(b) => b.exportNames[0]
|
|
1408
|
-
);
|
|
1409
|
-
if (exportNames.length > 0) {
|
|
1410
|
-
prerenderHandlerModules.set(id, exportNames);
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
1523
|
let changed = false;
|
|
1414
1524
|
const handlerConfigs = [
|
|
1415
1525
|
hasStaticHandlerCode && STATIC_CONFIG,
|
|
@@ -1422,7 +1532,7 @@ ${lazyImports.join(",\n")}
|
|
|
1422
1532
|
const totalCalls = countCreateCallsForNames(code, fnNames);
|
|
1423
1533
|
const supportedBindings = getBindings(code, fnNames).length;
|
|
1424
1534
|
if (totalCalls > supportedBindings) {
|
|
1425
|
-
const iterS = new
|
|
1535
|
+
const iterS = new MagicString3(code);
|
|
1426
1536
|
const result = transformInlineHandlers(
|
|
1427
1537
|
cfg.fnName,
|
|
1428
1538
|
VIRTUAL_HANDLER_PREFIX,
|
|
@@ -1587,16 +1697,24 @@ ${lazyImports.join(",\n")}
|
|
|
1587
1697
|
return { code: lines.join("\n") + "\n", map: null };
|
|
1588
1698
|
}
|
|
1589
1699
|
}
|
|
1590
|
-
if (
|
|
1591
|
-
const
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1700
|
+
if (isRscEnv && isBuild) {
|
|
1701
|
+
const trackTypes = [
|
|
1702
|
+
[
|
|
1703
|
+
hasPrerenderHandlerCode,
|
|
1704
|
+
PRERENDER_CONFIG,
|
|
1705
|
+
prerenderHandlerModules
|
|
1706
|
+
],
|
|
1707
|
+
[hasStaticHandlerCode, STATIC_CONFIG, staticHandlerModules]
|
|
1708
|
+
];
|
|
1709
|
+
for (const [has2, cfg, trackMap] of trackTypes) {
|
|
1710
|
+
if (!has2) continue;
|
|
1711
|
+
const exportNames = getBindings(code, getFnNames(cfg.fnName)).map(
|
|
1712
|
+
(b) => b.exportNames[0]
|
|
1713
|
+
);
|
|
1714
|
+
if (exportNames.length > 0) trackMap.set(id, exportNames);
|
|
1597
1715
|
}
|
|
1598
1716
|
}
|
|
1599
|
-
const s = new
|
|
1717
|
+
const s = new MagicString3(code);
|
|
1600
1718
|
if (hasLoaderCode) {
|
|
1601
1719
|
const fnNames = getFnNames("createLoader");
|
|
1602
1720
|
changed = transformLoaders(
|
|
@@ -1625,41 +1743,13 @@ ${lazyImports.join(",\n")}
|
|
|
1625
1743
|
isBuild
|
|
1626
1744
|
) || changed;
|
|
1627
1745
|
}
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
s,
|
|
1636
|
-
filePath,
|
|
1637
|
-
isBuild
|
|
1638
|
-
) || changed;
|
|
1639
|
-
} else {
|
|
1640
|
-
changed = stubHandlerExprs(
|
|
1641
|
-
PRERENDER_CONFIG,
|
|
1642
|
-
bindings,
|
|
1643
|
-
s,
|
|
1644
|
-
filePath,
|
|
1645
|
-
isBuild
|
|
1646
|
-
) || changed;
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
if (hasStaticHandlerCode) {
|
|
1650
|
-
const fnNames = getFnNames(STATIC_CONFIG.fnName);
|
|
1651
|
-
const bindings = getBindings(code, fnNames);
|
|
1652
|
-
if (isRscEnv) {
|
|
1653
|
-
changed = transformHandlerIds(
|
|
1654
|
-
STATIC_CONFIG,
|
|
1655
|
-
bindings,
|
|
1656
|
-
s,
|
|
1657
|
-
filePath,
|
|
1658
|
-
isBuild
|
|
1659
|
-
) || changed;
|
|
1660
|
-
} else {
|
|
1661
|
-
changed = stubHandlerExprs(STATIC_CONFIG, bindings, s, filePath, isBuild) || changed;
|
|
1662
|
-
}
|
|
1746
|
+
const finalHandlerConfigs = [
|
|
1747
|
+
hasPrerenderHandlerCode && PRERENDER_CONFIG,
|
|
1748
|
+
hasStaticHandlerCode && STATIC_CONFIG
|
|
1749
|
+
].filter((c) => !!c);
|
|
1750
|
+
for (const cfg of finalHandlerConfigs) {
|
|
1751
|
+
const bindings = getBindings(code, getFnNames(cfg.fnName));
|
|
1752
|
+
changed = (isRscEnv ? transformHandlerIds(cfg, bindings, s, filePath, isBuild) : stubHandlerExprs(cfg, bindings, s, filePath, isBuild)) || changed;
|
|
1663
1753
|
}
|
|
1664
1754
|
if (!changed) return;
|
|
1665
1755
|
return {
|
|
@@ -1675,10 +1765,11 @@ ${lazyImports.join(",\n")}
|
|
|
1675
1765
|
|
|
1676
1766
|
// src/vite/plugins/use-cache-transform.ts
|
|
1677
1767
|
import path5 from "node:path";
|
|
1678
|
-
import
|
|
1768
|
+
import MagicString4 from "magic-string";
|
|
1679
1769
|
var debug4 = createRangoDebugger(NS.transform);
|
|
1680
1770
|
var CACHE_RUNTIME_IMPORT = "@rangojs/router/cache-runtime";
|
|
1681
1771
|
var LAYOUT_TEMPLATE_PATTERN = /\/(layout|template)\.(tsx?|jsx?)$/;
|
|
1772
|
+
var USE_CACHE_DIRECTIVE_RE = /^use cache(:\s*[\w-]+)?$/;
|
|
1682
1773
|
function useCacheTransform() {
|
|
1683
1774
|
let projectRoot = "";
|
|
1684
1775
|
let isBuild = false;
|
|
@@ -1716,7 +1807,7 @@ function useCacheTransform() {
|
|
|
1716
1807
|
let ast;
|
|
1717
1808
|
try {
|
|
1718
1809
|
const { parseAst: parseAst4 } = await import("vite");
|
|
1719
|
-
ast = parseAst4(code);
|
|
1810
|
+
ast = parseAst4(code, { lang: "tsx" });
|
|
1720
1811
|
} catch {
|
|
1721
1812
|
return;
|
|
1722
1813
|
}
|
|
@@ -1772,7 +1863,7 @@ function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild, isLa
|
|
|
1772
1863
|
);
|
|
1773
1864
|
}
|
|
1774
1865
|
if (exportNames.length === 0) {
|
|
1775
|
-
const s = new
|
|
1866
|
+
const s = new MagicString4(code);
|
|
1776
1867
|
const directive2 = findFileLevelDirective(ast);
|
|
1777
1868
|
if (directive2) {
|
|
1778
1869
|
s.overwrite(
|
|
@@ -1807,7 +1898,7 @@ function transformFileLevelUseCache(code, ast, filePath, sourceId, isBuild, isLa
|
|
|
1807
1898
|
function transformFunctionLevelUseCache(code, ast, filePath, sourceId, isBuild, transformHoistInlineDirective) {
|
|
1808
1899
|
try {
|
|
1809
1900
|
const { output, names } = transformHoistInlineDirective(code, ast, {
|
|
1810
|
-
directive:
|
|
1901
|
+
directive: USE_CACHE_DIRECTIVE_RE,
|
|
1811
1902
|
runtime: (value, name, meta) => {
|
|
1812
1903
|
const funcId = isBuild ? hashId(filePath, name) : `${filePath}#${name}`;
|
|
1813
1904
|
const profileMatch = meta.directiveMatch[1];
|
|
@@ -1837,14 +1928,13 @@ function findFileLevelDirective(ast) {
|
|
|
1837
1928
|
}
|
|
1838
1929
|
return null;
|
|
1839
1930
|
}
|
|
1840
|
-
var VALID_DIRECTIVE_RE = /^use cache(:\s*[\w-]+)?$/;
|
|
1841
1931
|
var NEAR_MISS_RE = /^use cache:\s*.+$/;
|
|
1842
1932
|
function warnOnNearMissDirectives(ast, fileId, warn) {
|
|
1843
1933
|
const visit = (node) => {
|
|
1844
1934
|
if (!node || typeof node !== "object") return;
|
|
1845
1935
|
if (node.type === "ExpressionStatement" && node.expression?.type === "Literal" && typeof node.expression.value === "string") {
|
|
1846
1936
|
const value = node.expression.value;
|
|
1847
|
-
if (value.startsWith("use cache") && NEAR_MISS_RE.test(value) && !
|
|
1937
|
+
if (value.startsWith("use cache") && NEAR_MISS_RE.test(value) && !USE_CACHE_DIRECTIVE_RE.test(value)) {
|
|
1848
1938
|
const profilePart = value.slice("use cache:".length).trim();
|
|
1849
1939
|
warn(
|
|
1850
1940
|
`[rango:use-cache] "${value}" in ${fileId} has an invalid profile name "${profilePart}". Profile names must match [a-zA-Z0-9_-]+. This directive will be ignored.`
|
|
@@ -1938,7 +2028,7 @@ import {
|
|
|
1938
2028
|
import { createElement, StrictMode } from "react";
|
|
1939
2029
|
import { hydrateRoot } from "react-dom/client";
|
|
1940
2030
|
import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
|
|
1941
|
-
import { initBrowserApp,
|
|
2031
|
+
import { initBrowserApp, Rango } from "@rangojs/router/browser";
|
|
1942
2032
|
|
|
1943
2033
|
async function initializeApp() {
|
|
1944
2034
|
const deps = {
|
|
@@ -1953,7 +2043,7 @@ async function initializeApp() {
|
|
|
1953
2043
|
|
|
1954
2044
|
hydrateRoot(
|
|
1955
2045
|
document,
|
|
1956
|
-
createElement(StrictMode, null, createElement(
|
|
2046
|
+
createElement(StrictMode, null, createElement(Rango))
|
|
1957
2047
|
);
|
|
1958
2048
|
}
|
|
1959
2049
|
|
|
@@ -2040,7 +2130,7 @@ import { resolve } from "node:path";
|
|
|
2040
2130
|
// package.json
|
|
2041
2131
|
var package_default = {
|
|
2042
2132
|
name: "@rangojs/router",
|
|
2043
|
-
version: "0.0.0-experimental.
|
|
2133
|
+
version: "0.0.0-experimental.dacec167",
|
|
2044
2134
|
description: "Django-inspired RSC router with composable URL patterns",
|
|
2045
2135
|
keywords: [
|
|
2046
2136
|
"react",
|
|
@@ -2166,6 +2256,31 @@ var package_default = {
|
|
|
2166
2256
|
"./host/testing": {
|
|
2167
2257
|
types: "./src/host/testing.ts",
|
|
2168
2258
|
default: "./src/host/testing.ts"
|
|
2259
|
+
},
|
|
2260
|
+
"./testing": {
|
|
2261
|
+
types: "./src/testing/index.ts",
|
|
2262
|
+
default: "./src/testing/index.ts"
|
|
2263
|
+
},
|
|
2264
|
+
"./testing/vitest": {
|
|
2265
|
+
types: "./src/testing/vitest.ts",
|
|
2266
|
+
default: "./dist/testing/vitest.js"
|
|
2267
|
+
},
|
|
2268
|
+
"./testing/dom": {
|
|
2269
|
+
types: "./src/testing/dom.entry.ts",
|
|
2270
|
+
default: "./src/testing/dom.entry.ts"
|
|
2271
|
+
},
|
|
2272
|
+
"./testing/e2e": {
|
|
2273
|
+
types: "./src/testing/e2e/index.ts",
|
|
2274
|
+
default: "./src/testing/e2e/index.ts"
|
|
2275
|
+
},
|
|
2276
|
+
"./testing/flight": {
|
|
2277
|
+
types: "./src/testing/flight.entry.ts",
|
|
2278
|
+
"react-server": "./src/testing/flight.entry.ts",
|
|
2279
|
+
default: "./src/testing/flight.entry.ts"
|
|
2280
|
+
},
|
|
2281
|
+
"./testing/flight-matchers": {
|
|
2282
|
+
types: "./src/testing/flight-matchers.ts",
|
|
2283
|
+
default: "./src/testing/flight-matchers.ts"
|
|
2169
2284
|
}
|
|
2170
2285
|
},
|
|
2171
2286
|
publishConfig: {
|
|
@@ -2173,47 +2288,66 @@ var package_default = {
|
|
|
2173
2288
|
tag: "experimental"
|
|
2174
2289
|
},
|
|
2175
2290
|
scripts: {
|
|
2176
|
-
build: "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && mkdir -p dist/vite/plugins && cp src/vite/plugins/cloudflare-protocol-loader-hook.mjs dist/vite/plugins/cloudflare-protocol-loader-hook.mjs && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
|
|
2291
|
+
build: "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && mkdir -p dist/vite/plugins && cp src/vite/plugins/cloudflare-protocol-loader-hook.mjs dist/vite/plugins/cloudflare-protocol-loader-hook.mjs && pnpm dlx esbuild src/testing/vitest.ts --bundle --format=esm --outfile=dist/testing/vitest.js --platform=node --packages=external && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
|
|
2177
2292
|
prepublishOnly: "pnpm build",
|
|
2178
|
-
typecheck: "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit",
|
|
2293
|
+
typecheck: "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit && tsc -p tsconfig.augment-check.json --noEmit",
|
|
2179
2294
|
test: "playwright test",
|
|
2180
2295
|
"test:ui": "playwright test --ui",
|
|
2296
|
+
"test:hmr-local": "playwright test --project=dev-warmup --project=hmr-routes --project=hmr-basename --project=hmr-prerender --no-deps --workers=1",
|
|
2181
2297
|
"test:unit": "vitest run",
|
|
2182
|
-
"test:unit:watch": "vitest"
|
|
2298
|
+
"test:unit:watch": "vitest",
|
|
2299
|
+
"test:unit:rsc": "vitest run --config vitest.rsc.config.ts"
|
|
2183
2300
|
},
|
|
2184
2301
|
dependencies: {
|
|
2185
2302
|
"@types/debug": "^4.1.12",
|
|
2186
|
-
"@vitejs/plugin-rsc": "^0.5.
|
|
2303
|
+
"@vitejs/plugin-rsc": "^0.5.26",
|
|
2187
2304
|
debug: "^4.4.1",
|
|
2188
2305
|
"magic-string": "^0.30.17",
|
|
2189
2306
|
picomatch: "^4.0.3",
|
|
2190
|
-
"rsc-html-stream": "^0.0.7"
|
|
2307
|
+
"rsc-html-stream": "^0.0.7",
|
|
2308
|
+
tinyexec: "^0.3.2"
|
|
2191
2309
|
},
|
|
2192
2310
|
devDependencies: {
|
|
2193
2311
|
"@playwright/test": "^1.49.1",
|
|
2312
|
+
"@shared/e2e": "workspace:*",
|
|
2313
|
+
"@testing-library/dom": "^10.4.1",
|
|
2314
|
+
"@testing-library/react": "^16.3.2",
|
|
2194
2315
|
"@types/node": "^24.10.1",
|
|
2195
2316
|
"@types/react": "catalog:",
|
|
2196
2317
|
"@types/react-dom": "catalog:",
|
|
2197
2318
|
esbuild: "^0.27.0",
|
|
2319
|
+
"happy-dom": "^20.10.1",
|
|
2198
2320
|
jiti: "^2.6.1",
|
|
2199
2321
|
react: "catalog:",
|
|
2200
2322
|
"react-dom": "catalog:",
|
|
2201
|
-
tinyexec: "^0.3.2",
|
|
2202
2323
|
typescript: "^5.3.0",
|
|
2203
2324
|
vitest: "^4.0.0"
|
|
2204
2325
|
},
|
|
2205
2326
|
peerDependencies: {
|
|
2206
|
-
"@cloudflare/vite-plugin": "^1.
|
|
2207
|
-
"@
|
|
2208
|
-
react: "
|
|
2209
|
-
|
|
2327
|
+
"@cloudflare/vite-plugin": "^1.38.0",
|
|
2328
|
+
"@playwright/test": "^1.49.1",
|
|
2329
|
+
"@testing-library/react": ">=16",
|
|
2330
|
+
"@vitejs/plugin-rsc": "^0.5.26",
|
|
2331
|
+
react: ">=19.2.6 <20",
|
|
2332
|
+
"react-dom": ">=19.2.6 <20",
|
|
2333
|
+
vite: "^8.0.0",
|
|
2334
|
+
vitest: ">=3"
|
|
2210
2335
|
},
|
|
2211
2336
|
peerDependenciesMeta: {
|
|
2212
2337
|
"@cloudflare/vite-plugin": {
|
|
2213
2338
|
optional: true
|
|
2214
2339
|
},
|
|
2340
|
+
"@playwright/test": {
|
|
2341
|
+
optional: true
|
|
2342
|
+
},
|
|
2343
|
+
"@testing-library/react": {
|
|
2344
|
+
optional: true
|
|
2345
|
+
},
|
|
2215
2346
|
vite: {
|
|
2216
2347
|
optional: true
|
|
2348
|
+
},
|
|
2349
|
+
vitest: {
|
|
2350
|
+
optional: true
|
|
2217
2351
|
}
|
|
2218
2352
|
}
|
|
2219
2353
|
};
|
|
@@ -2399,7 +2533,7 @@ ${objectBody}
|
|
|
2399
2533
|
} as const;
|
|
2400
2534
|
|
|
2401
2535
|
declare global {
|
|
2402
|
-
namespace
|
|
2536
|
+
namespace Rango {
|
|
2403
2537
|
interface GeneratedRouteMap extends Readonly<typeof NamedRoutes> {}
|
|
2404
2538
|
}
|
|
2405
2539
|
}
|
|
@@ -2634,7 +2768,7 @@ function buildCombinedRouteMapWithSearch(filePath, variableName, visited, diagno
|
|
|
2634
2768
|
const realPath = resolve2(filePath);
|
|
2635
2769
|
const key = variableName ? `${realPath}:${variableName}` : realPath;
|
|
2636
2770
|
if (visited.has(key)) {
|
|
2637
|
-
console.warn(`[
|
|
2771
|
+
console.warn(`[rango] Circular include detected, skipping: ${key}`);
|
|
2638
2772
|
return { routes: {}, searchSchemas: {} };
|
|
2639
2773
|
}
|
|
2640
2774
|
visited.add(key);
|
|
@@ -2695,6 +2829,7 @@ function countPublicRouteEntries(source) {
|
|
|
2695
2829
|
return count;
|
|
2696
2830
|
}
|
|
2697
2831
|
var ROUTER_CALL_PATTERN = /\bcreateRouter\s*[<(]/;
|
|
2832
|
+
var ROUTER_CALL_PATTERN_G = /\bcreateRouter\s*[<(]/g;
|
|
2698
2833
|
function isRoutableSourceFile(name) {
|
|
2699
2834
|
return (name.endsWith(".ts") || name.endsWith(".tsx") || name.endsWith(".js") || name.endsWith(".jsx")) && !name.includes(".gen.") && !name.includes(".test.") && !name.includes(".spec.");
|
|
2700
2835
|
}
|
|
@@ -2704,7 +2839,7 @@ function findRouterFilesRecursive(dir, filter, results) {
|
|
|
2704
2839
|
entries = readdirSync(dir, { withFileTypes: true });
|
|
2705
2840
|
} catch (err) {
|
|
2706
2841
|
console.warn(
|
|
2707
|
-
`[
|
|
2842
|
+
`[rango] Failed to scan directory ${dir}: ${err.message}`
|
|
2708
2843
|
);
|
|
2709
2844
|
return;
|
|
2710
2845
|
}
|
|
@@ -2722,7 +2857,7 @@ function findRouterFilesRecursive(dir, filter, results) {
|
|
|
2722
2857
|
if (filter && !filter(fullPath)) continue;
|
|
2723
2858
|
try {
|
|
2724
2859
|
const source = readFileSync2(fullPath, "utf-8");
|
|
2725
|
-
if (ROUTER_CALL_PATTERN.test(source)) {
|
|
2860
|
+
if (ROUTER_CALL_PATTERN.test(source) && firstCodeMatchIndex(source, ROUTER_CALL_PATTERN_G) >= 0) {
|
|
2726
2861
|
routerFilesInDir.push(fullPath);
|
|
2727
2862
|
}
|
|
2728
2863
|
} catch {
|
|
@@ -2760,7 +2895,7 @@ function findNestedRouterConflict(routerFiles) {
|
|
|
2760
2895
|
}
|
|
2761
2896
|
return null;
|
|
2762
2897
|
}
|
|
2763
|
-
function formatNestedRouterConflictError(conflict, prefix = "[
|
|
2898
|
+
function formatNestedRouterConflictError(conflict, prefix = "[rango]") {
|
|
2764
2899
|
return `${prefix} Nested router roots are not supported.
|
|
2765
2900
|
Router root: ${conflict.ancestor}
|
|
2766
2901
|
Nested router: ${conflict.nested}
|
|
@@ -2856,19 +2991,38 @@ function extractBasenameFromRouter(code) {
|
|
|
2856
2991
|
visit(sourceFile);
|
|
2857
2992
|
return result;
|
|
2858
2993
|
}
|
|
2859
|
-
function applyBasenameToRoutes(result,
|
|
2994
|
+
function applyBasenameToRoutes(result, basename2) {
|
|
2860
2995
|
const prefixed = {};
|
|
2861
2996
|
for (const [name, pattern] of Object.entries(result.routes)) {
|
|
2862
2997
|
if (pattern === "/") {
|
|
2863
|
-
prefixed[name] =
|
|
2864
|
-
} else if (
|
|
2865
|
-
prefixed[name] =
|
|
2998
|
+
prefixed[name] = basename2;
|
|
2999
|
+
} else if (basename2.endsWith("/") && pattern.startsWith("/")) {
|
|
3000
|
+
prefixed[name] = basename2 + pattern.slice(1);
|
|
2866
3001
|
} else {
|
|
2867
|
-
prefixed[name] =
|
|
3002
|
+
prefixed[name] = basename2 + pattern;
|
|
2868
3003
|
}
|
|
2869
3004
|
}
|
|
2870
3005
|
return { routes: prefixed, searchSchemas: result.searchSchemas };
|
|
2871
3006
|
}
|
|
3007
|
+
function genFileTsPath(sourceFile) {
|
|
3008
|
+
const base = pathBasename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
3009
|
+
return join(dirname2(sourceFile), `${base}.named-routes.gen.ts`);
|
|
3010
|
+
}
|
|
3011
|
+
function resolveSearchSchemas(publicRouteNames, runtimeSchemas, sourceFile) {
|
|
3012
|
+
if (runtimeSchemas && Object.keys(runtimeSchemas).length > 0) {
|
|
3013
|
+
return runtimeSchemas;
|
|
3014
|
+
}
|
|
3015
|
+
const staticParsed = buildCombinedRouteMapForRouterFile(sourceFile);
|
|
3016
|
+
if (Object.keys(staticParsed.searchSchemas).length === 0) {
|
|
3017
|
+
return runtimeSchemas;
|
|
3018
|
+
}
|
|
3019
|
+
const filtered = {};
|
|
3020
|
+
for (const name of publicRouteNames) {
|
|
3021
|
+
const schema = staticParsed.searchSchemas[name];
|
|
3022
|
+
if (schema) filtered[name] = schema;
|
|
3023
|
+
}
|
|
3024
|
+
return Object.keys(filtered).length > 0 ? filtered : runtimeSchemas;
|
|
3025
|
+
}
|
|
2872
3026
|
function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
2873
3027
|
let routerSource;
|
|
2874
3028
|
try {
|
|
@@ -2881,7 +3035,7 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
2881
3035
|
return { routes: {}, searchSchemas: {} };
|
|
2882
3036
|
}
|
|
2883
3037
|
const rawBasename = extractBasenameFromRouter(routerSource);
|
|
2884
|
-
const
|
|
3038
|
+
const basename2 = rawBasename ? ("/" + rawBasename.replace(/^\/+|\/+$/g, "")).replace(/^\/$/, "") : void 0;
|
|
2885
3039
|
let result;
|
|
2886
3040
|
if (extraction.kind === "inline") {
|
|
2887
3041
|
result = buildCombinedRouteMapWithSearch(
|
|
@@ -2906,8 +3060,8 @@ function buildCombinedRouteMapForRouterFile(routerFilePath) {
|
|
|
2906
3060
|
result = buildCombinedRouteMapWithSearch(routerFilePath, extraction.name);
|
|
2907
3061
|
}
|
|
2908
3062
|
}
|
|
2909
|
-
if (
|
|
2910
|
-
result = applyBasenameToRoutes(result,
|
|
3063
|
+
if (basename2) {
|
|
3064
|
+
result = applyBasenameToRoutes(result, basename2);
|
|
2911
3065
|
}
|
|
2912
3066
|
return result;
|
|
2913
3067
|
}
|
|
@@ -2922,7 +3076,7 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
2922
3076
|
if (existsSync3(oldCombinedPath)) {
|
|
2923
3077
|
unlinkSync(oldCombinedPath);
|
|
2924
3078
|
console.log(
|
|
2925
|
-
`[
|
|
3079
|
+
`[rango] Removed stale combined route types: ${oldCombinedPath}`
|
|
2926
3080
|
);
|
|
2927
3081
|
}
|
|
2928
3082
|
} catch {
|
|
@@ -2944,18 +3098,12 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
2944
3098
|
}
|
|
2945
3099
|
if (!extractUrlsFromRouter(routerSource)) continue;
|
|
2946
3100
|
}
|
|
2947
|
-
const
|
|
2948
|
-
/\.(tsx?|jsx?)$/,
|
|
2949
|
-
""
|
|
2950
|
-
);
|
|
2951
|
-
const outPath = join(
|
|
2952
|
-
dirname2(routerFilePath),
|
|
2953
|
-
`${routerBasename}.named-routes.gen.ts`
|
|
2954
|
-
);
|
|
3101
|
+
const outPath = genFileTsPath(routerFilePath);
|
|
2955
3102
|
const existing = existsSync3(outPath) ? readFileSync2(outPath, "utf-8") : null;
|
|
2956
3103
|
if (Object.keys(result.routes).length === 0) {
|
|
2957
3104
|
if (!existing) {
|
|
2958
3105
|
const emptySource = generateRouteTypesSource({});
|
|
3106
|
+
opts?.onWrite?.(outPath, emptySource);
|
|
2959
3107
|
writeFileSync(outPath, emptySource);
|
|
2960
3108
|
}
|
|
2961
3109
|
continue;
|
|
@@ -2975,9 +3123,10 @@ function writeCombinedRouteTypes(root, knownRouterFiles, opts) {
|
|
|
2975
3123
|
continue;
|
|
2976
3124
|
}
|
|
2977
3125
|
}
|
|
3126
|
+
opts?.onWrite?.(outPath, source);
|
|
2978
3127
|
writeFileSync(outPath, source);
|
|
2979
3128
|
console.log(
|
|
2980
|
-
`[
|
|
3129
|
+
`[rango] Generated route types (${Object.keys(result.routes).length} routes) -> ${outPath}`
|
|
2981
3130
|
);
|
|
2982
3131
|
}
|
|
2983
3132
|
}
|
|
@@ -2994,7 +3143,7 @@ function normalizeModuleId(id) {
|
|
|
2994
3143
|
function getClientModuleSignature(source) {
|
|
2995
3144
|
let program;
|
|
2996
3145
|
try {
|
|
2997
|
-
program = parseAst3(source, {
|
|
3146
|
+
program = parseAst3(source, { lang: "tsx" });
|
|
2998
3147
|
} catch {
|
|
2999
3148
|
return void 0;
|
|
3000
3149
|
}
|
|
@@ -3077,11 +3226,12 @@ function createVersionPlugin() {
|
|
|
3077
3226
|
let currentVersion = buildVersion;
|
|
3078
3227
|
let isDev = false;
|
|
3079
3228
|
let server = null;
|
|
3229
|
+
let resolvedCacheDir;
|
|
3080
3230
|
const clientModuleSignatures = /* @__PURE__ */ new Map();
|
|
3081
3231
|
let versionCounter = 0;
|
|
3082
3232
|
const bumpVersion = (reason) => {
|
|
3083
3233
|
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
3084
|
-
console.log(`[
|
|
3234
|
+
console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
|
|
3085
3235
|
const rscEnv = server?.environments?.rsc;
|
|
3086
3236
|
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
3087
3237
|
"\0" + VIRTUAL_IDS.version
|
|
@@ -3095,6 +3245,7 @@ function createVersionPlugin() {
|
|
|
3095
3245
|
enforce: "pre",
|
|
3096
3246
|
configResolved(config) {
|
|
3097
3247
|
isDev = config.command === "serve";
|
|
3248
|
+
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
3098
3249
|
},
|
|
3099
3250
|
configureServer(devServer) {
|
|
3100
3251
|
server = devServer;
|
|
@@ -3136,6 +3287,7 @@ function createVersionPlugin() {
|
|
|
3136
3287
|
if (!isDev) return;
|
|
3137
3288
|
const isRscModule = this.environment?.name === "rsc";
|
|
3138
3289
|
if (!isRscModule) return;
|
|
3290
|
+
if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
|
|
3139
3291
|
if (ctx.modules.length === 1 && ctx.modules[0].id === "\0" + VIRTUAL_IDS.version) {
|
|
3140
3292
|
return;
|
|
3141
3293
|
}
|
|
@@ -3165,6 +3317,17 @@ function createVersionPlugin() {
|
|
|
3165
3317
|
}
|
|
3166
3318
|
};
|
|
3167
3319
|
}
|
|
3320
|
+
function isViteDepCachePath(filePath, cacheDir) {
|
|
3321
|
+
if (!filePath) return false;
|
|
3322
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
3323
|
+
if (cacheDir) {
|
|
3324
|
+
const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
3325
|
+
if (normalized === normalizedCacheDir || normalized.startsWith(normalizedCacheDir + "/")) {
|
|
3326
|
+
return true;
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
return /\/node_modules\/\.vite[^/]*\//.test(normalized) || normalized.includes("/.vite-isolated/");
|
|
3330
|
+
}
|
|
3168
3331
|
|
|
3169
3332
|
// src/vite/utils/shared-utils.ts
|
|
3170
3333
|
import * as Vite from "vite";
|
|
@@ -3193,22 +3356,18 @@ function patchRsdwClientDebugInfoRecovery(code) {
|
|
|
3193
3356
|
};
|
|
3194
3357
|
}
|
|
3195
3358
|
function performanceTracksOptimizeDepsPlugin() {
|
|
3359
|
+
const RSDW_CLIENT_RE = /react-server-dom-webpack-client\.browser\.(development|production)\.js$/;
|
|
3196
3360
|
return {
|
|
3197
3361
|
name: "@rangojs/router:performance-tracks-optimize-deps",
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
contents: patched.code,
|
|
3208
|
-
loader: "js"
|
|
3209
|
-
};
|
|
3210
|
-
}
|
|
3211
|
-
);
|
|
3362
|
+
// Vite 8 optimizes deps with Rolldown (Rollup-style plugin pipeline), so the
|
|
3363
|
+
// pre-bundled RSDW client is patched via load() rather than esbuild's onLoad.
|
|
3364
|
+
// Returning code overrides Rolldown's default filesystem read for the module.
|
|
3365
|
+
async load(id) {
|
|
3366
|
+
const cleanId = id.split("?")[0] ?? id;
|
|
3367
|
+
if (!RSDW_CLIENT_RE.test(cleanId)) return null;
|
|
3368
|
+
const code = await readFile(cleanId, "utf8");
|
|
3369
|
+
const patched = patchRsdwClientDebugInfoRecovery(code);
|
|
3370
|
+
return { code: patched.code };
|
|
3212
3371
|
}
|
|
3213
3372
|
};
|
|
3214
3373
|
}
|
|
@@ -3235,24 +3394,27 @@ function performanceTracksPlugin() {
|
|
|
3235
3394
|
}
|
|
3236
3395
|
|
|
3237
3396
|
// src/vite/utils/shared-utils.ts
|
|
3238
|
-
|
|
3397
|
+
function resolveRscEntryFromConfig(config) {
|
|
3398
|
+
const entries = config.environments?.["rsc"]?.optimizeDeps?.entries;
|
|
3399
|
+
if (typeof entries === "string") return entries;
|
|
3400
|
+
if (Array.isArray(entries) && entries.length > 0) return entries[0];
|
|
3401
|
+
return void 0;
|
|
3402
|
+
}
|
|
3403
|
+
var versionRolldownPlugin = {
|
|
3239
3404
|
name: "@rangojs/router-version",
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
loader: "js"
|
|
3250
|
-
})
|
|
3251
|
-
);
|
|
3405
|
+
resolveId(id) {
|
|
3406
|
+
if (id === VIRTUAL_IDS.version) return "\0" + VIRTUAL_IDS.version;
|
|
3407
|
+
return void 0;
|
|
3408
|
+
},
|
|
3409
|
+
load(id) {
|
|
3410
|
+
if (id === "\0" + VIRTUAL_IDS.version) {
|
|
3411
|
+
return getVirtualVersionContent("dev");
|
|
3412
|
+
}
|
|
3413
|
+
return void 0;
|
|
3252
3414
|
}
|
|
3253
3415
|
};
|
|
3254
|
-
var
|
|
3255
|
-
plugins: [
|
|
3416
|
+
var sharedRolldownOptions = {
|
|
3417
|
+
plugins: [versionRolldownPlugin, performanceTracksOptimizeDepsPlugin()]
|
|
3256
3418
|
};
|
|
3257
3419
|
function createVirtualEntriesPlugin(entries, routerPathRef) {
|
|
3258
3420
|
const virtualModules = {};
|
|
@@ -3294,8 +3456,29 @@ function createVirtualEntriesPlugin(entries, routerPathRef) {
|
|
|
3294
3456
|
}
|
|
3295
3457
|
};
|
|
3296
3458
|
}
|
|
3459
|
+
function isContentHashedAssetConflict(message) {
|
|
3460
|
+
if (!message) return false;
|
|
3461
|
+
const match = /The emitted file "?([^"\s]+)"? overwrites a previously emitted file/.exec(
|
|
3462
|
+
message
|
|
3463
|
+
);
|
|
3464
|
+
if (!match) return false;
|
|
3465
|
+
const fileName = match[1];
|
|
3466
|
+
const base = fileName.slice(fileName.lastIndexOf("/") + 1);
|
|
3467
|
+
const dot = base.lastIndexOf(".");
|
|
3468
|
+
if (dot <= 0) return false;
|
|
3469
|
+
const stem = base.slice(0, dot);
|
|
3470
|
+
const HASH_LEN = 8;
|
|
3471
|
+
if (stem.length < HASH_LEN + 1 || stem[stem.length - HASH_LEN - 1] !== "-") {
|
|
3472
|
+
return false;
|
|
3473
|
+
}
|
|
3474
|
+
const hash = stem.slice(-HASH_LEN);
|
|
3475
|
+
return /^[A-Za-z0-9_-]+$/.test(hash) && /[A-Z0-9]/.test(hash);
|
|
3476
|
+
}
|
|
3297
3477
|
function onwarn(warning, defaultHandler) {
|
|
3298
|
-
if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "SOURCEMAP_ERROR" || warning.code === "EMPTY_BUNDLE") {
|
|
3478
|
+
if (warning.code === "MODULE_LEVEL_DIRECTIVE" || warning.code === "SOURCEMAP_ERROR" || warning.code === "EMPTY_BUNDLE" || warning.code === "INEFFECTIVE_DYNAMIC_IMPORT") {
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3481
|
+
if (warning.code === "FILE_NAME_CONFLICT" && isContentHashedAssetConflict(warning.message)) {
|
|
3299
3482
|
return;
|
|
3300
3483
|
}
|
|
3301
3484
|
if (warning.message?.includes("Sourcemap is likely to be incorrect")) {
|
|
@@ -3314,12 +3497,138 @@ function getManualChunks(id) {
|
|
|
3314
3497
|
return "react";
|
|
3315
3498
|
}
|
|
3316
3499
|
const packageName = getPublishedPackageName();
|
|
3317
|
-
if (normalized.includes(`node_modules/${packageName}/`) ||
|
|
3500
|
+
if (normalized.includes(`node_modules/${packageName}/`) || /\/packages\/(rsc-router|rangojs-router)\/(src|dist)\//.test(normalized)) {
|
|
3318
3501
|
return "router";
|
|
3319
3502
|
}
|
|
3320
3503
|
return void 0;
|
|
3321
3504
|
}
|
|
3322
3505
|
|
|
3506
|
+
// src/vite/plugins/client-ref-hashing.ts
|
|
3507
|
+
import { relative } from "node:path";
|
|
3508
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
3509
|
+
var debug7 = createRangoDebugger(NS.transform);
|
|
3510
|
+
var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
|
|
3511
|
+
var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
|
|
3512
|
+
var FS_PREFIX = "/@fs/";
|
|
3513
|
+
function hashRefKey(relativeId) {
|
|
3514
|
+
return createHash2("sha256").update(relativeId).digest("hex").slice(0, 12);
|
|
3515
|
+
}
|
|
3516
|
+
function computeProductionHash(projectRoot, refKey) {
|
|
3517
|
+
let toHash;
|
|
3518
|
+
if (refKey.startsWith(CLIENT_PKG_PROXY_PREFIX)) {
|
|
3519
|
+
toHash = refKey.slice(CLIENT_PKG_PROXY_PREFIX.length);
|
|
3520
|
+
} else if (refKey.startsWith(CLIENT_IN_SERVER_PKG_PROXY_PREFIX)) {
|
|
3521
|
+
const absPath = decodeURIComponent(
|
|
3522
|
+
refKey.slice(CLIENT_IN_SERVER_PKG_PROXY_PREFIX.length)
|
|
3523
|
+
);
|
|
3524
|
+
toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
|
|
3525
|
+
} else if (refKey.startsWith(FS_PREFIX)) {
|
|
3526
|
+
const absPath = refKey.slice(FS_PREFIX.length - 1);
|
|
3527
|
+
toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
|
|
3528
|
+
} else if (refKey.startsWith("/")) {
|
|
3529
|
+
toHash = refKey.slice(1);
|
|
3530
|
+
} else {
|
|
3531
|
+
return refKey;
|
|
3532
|
+
}
|
|
3533
|
+
return hashRefKey(toHash);
|
|
3534
|
+
}
|
|
3535
|
+
var REGISTER_CLIENT_REF_RE = /registerClientReference\(\s*(?:(?:\([^)]*\))|(?:\(\)[\s\S]*?\}))\s*,\s*"([^"]+)"\s*,\s*"[^"]+"\s*\)/g;
|
|
3536
|
+
function transformClientRefs(code, projectRoot) {
|
|
3537
|
+
if (!code.includes("registerClientReference")) return null;
|
|
3538
|
+
let hasReplacement = false;
|
|
3539
|
+
const result = code.replace(
|
|
3540
|
+
REGISTER_CLIENT_REF_RE,
|
|
3541
|
+
(match, refKey) => {
|
|
3542
|
+
const hash = computeProductionHash(projectRoot, refKey);
|
|
3543
|
+
if (hash === refKey) return match;
|
|
3544
|
+
hasReplacement = true;
|
|
3545
|
+
return match.replace(`"${refKey}"`, `"${hash}"`);
|
|
3546
|
+
}
|
|
3547
|
+
);
|
|
3548
|
+
return hasReplacement ? result : null;
|
|
3549
|
+
}
|
|
3550
|
+
function hashClientRefs(projectRoot) {
|
|
3551
|
+
const counter = createCounter(debug7, "hash-client-refs");
|
|
3552
|
+
return {
|
|
3553
|
+
name: "@rangojs/router:hash-client-refs",
|
|
3554
|
+
// Run after the RSC plugin's transform (default enforce is normal)
|
|
3555
|
+
enforce: "post",
|
|
3556
|
+
applyToEnvironment(env) {
|
|
3557
|
+
return env.name === "rsc";
|
|
3558
|
+
},
|
|
3559
|
+
buildEnd() {
|
|
3560
|
+
counter?.flush();
|
|
3561
|
+
},
|
|
3562
|
+
transform(code, id) {
|
|
3563
|
+
const start = counter ? performance.now() : 0;
|
|
3564
|
+
try {
|
|
3565
|
+
const result = transformClientRefs(code, projectRoot);
|
|
3566
|
+
if (result === null) return;
|
|
3567
|
+
return { code: result, map: null };
|
|
3568
|
+
} finally {
|
|
3569
|
+
counter?.record(id, performance.now() - start);
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
};
|
|
3573
|
+
}
|
|
3574
|
+
|
|
3575
|
+
// src/vite/utils/client-chunks.ts
|
|
3576
|
+
var debugChunks = createRangoDebugger(NS.chunks);
|
|
3577
|
+
function isSharedRuntime(meta) {
|
|
3578
|
+
return [meta.id, meta.normalizedId].some(
|
|
3579
|
+
(path6) => path6.includes("/node_modules/") || /\/@rangojs\/router\//.test(path6) || /\/packages\/(rangojs-router|rsc-router)\/(src|dist)\//.test(path6)
|
|
3580
|
+
);
|
|
3581
|
+
}
|
|
3582
|
+
function sanitizeGroup(name) {
|
|
3583
|
+
return name.replace(/[^a-zA-Z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "app";
|
|
3584
|
+
}
|
|
3585
|
+
var ROUTE_ROOT_DIRS = /* @__PURE__ */ new Set([
|
|
3586
|
+
"routes",
|
|
3587
|
+
"route",
|
|
3588
|
+
"pages",
|
|
3589
|
+
"page",
|
|
3590
|
+
"app",
|
|
3591
|
+
"features",
|
|
3592
|
+
"feature",
|
|
3593
|
+
"views",
|
|
3594
|
+
"view",
|
|
3595
|
+
"handlers",
|
|
3596
|
+
"urls",
|
|
3597
|
+
"modules",
|
|
3598
|
+
"screens",
|
|
3599
|
+
"sections"
|
|
3600
|
+
]);
|
|
3601
|
+
function directoryClientChunks(meta, ctx) {
|
|
3602
|
+
if (isSharedRuntime(meta)) {
|
|
3603
|
+
return void 0;
|
|
3604
|
+
}
|
|
3605
|
+
if (ctx?.fallbackRefs.size && ctx.fallbackRefs.has(hashRefKey(meta.normalizedId))) {
|
|
3606
|
+
debugChunks?.("fallback %s -> app-fallback", meta.normalizedId);
|
|
3607
|
+
return "app-fallback";
|
|
3608
|
+
}
|
|
3609
|
+
const segments = meta.normalizedId.split("/").filter(Boolean);
|
|
3610
|
+
const dirCount = segments.length - 1;
|
|
3611
|
+
if (dirCount >= 1) {
|
|
3612
|
+
for (let i = 0; i < dirCount - 1; i++) {
|
|
3613
|
+
if (ROUTE_ROOT_DIRS.has(segments[i].toLowerCase())) {
|
|
3614
|
+
const group = `app-${sanitizeGroup(segments[i + 1])}`;
|
|
3615
|
+
debugChunks?.("split %s -> %s", meta.normalizedId, group);
|
|
3616
|
+
return group;
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
debugChunks?.(
|
|
3621
|
+
"shared %s (no route-root marker; inherits default grouping)",
|
|
3622
|
+
meta.normalizedId
|
|
3623
|
+
);
|
|
3624
|
+
return void 0;
|
|
3625
|
+
}
|
|
3626
|
+
function resolveClientChunks(option, ctx) {
|
|
3627
|
+
if (!option) return void 0;
|
|
3628
|
+
if (option === true) return (meta) => directoryClientChunks(meta, ctx);
|
|
3629
|
+
return option;
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3323
3632
|
// src/vite/utils/banner.ts
|
|
3324
3633
|
var rangoVersion = package_default.version;
|
|
3325
3634
|
var _bannerPrinted = false;
|
|
@@ -3356,15 +3665,7 @@ function createVersionInjectorPlugin(rscEntryPath) {
|
|
|
3356
3665
|
enforce: "pre",
|
|
3357
3666
|
configResolved(config) {
|
|
3358
3667
|
let entryPath = rscEntryPath;
|
|
3359
|
-
if (!entryPath)
|
|
3360
|
-
const rscEnvConfig = config.environments?.["rsc"];
|
|
3361
|
-
const entries = rscEnvConfig?.optimizeDeps?.entries;
|
|
3362
|
-
if (typeof entries === "string") {
|
|
3363
|
-
entryPath = entries;
|
|
3364
|
-
} else if (Array.isArray(entries) && entries.length > 0) {
|
|
3365
|
-
entryPath = entries[0];
|
|
3366
|
-
}
|
|
3367
|
-
}
|
|
3668
|
+
if (!entryPath) entryPath = resolveRscEntryFromConfig(config);
|
|
3368
3669
|
if (entryPath) {
|
|
3369
3670
|
resolvedEntryPath = resolve4(config.root, entryPath);
|
|
3370
3671
|
}
|
|
@@ -3412,23 +3713,23 @@ function createVersionInjectorPlugin(rscEntryPath) {
|
|
|
3412
3713
|
}
|
|
3413
3714
|
|
|
3414
3715
|
// src/vite/plugins/cjs-to-esm.ts
|
|
3415
|
-
var
|
|
3716
|
+
var debug8 = createRangoDebugger(NS.transform);
|
|
3416
3717
|
function createCjsToEsmPlugin() {
|
|
3417
3718
|
return {
|
|
3418
3719
|
name: "@rangojs/router:cjs-to-esm",
|
|
3419
3720
|
enforce: "pre",
|
|
3420
3721
|
transform(code, id) {
|
|
3421
|
-
const cleanId = id.split("?")[0];
|
|
3422
|
-
if (cleanId.includes("vendor/react-server-dom/client.browser.js")
|
|
3722
|
+
const cleanId = id.split("?")[0].replaceAll("\\", "/");
|
|
3723
|
+
if (cleanId.includes("vendor/react-server-dom/client.browser.js")) {
|
|
3423
3724
|
const isProd = process.env.NODE_ENV === "production";
|
|
3424
3725
|
const cjsFile = isProd ? "./cjs/react-server-dom-webpack-client.browser.production.js" : "./cjs/react-server-dom-webpack-client.browser.development.js";
|
|
3425
|
-
|
|
3726
|
+
debug8?.("cjs-to-esm entry redirect %s", id);
|
|
3426
3727
|
return {
|
|
3427
3728
|
code: `export * from "${cjsFile}";`,
|
|
3428
3729
|
map: null
|
|
3429
3730
|
};
|
|
3430
3731
|
}
|
|
3431
|
-
if (
|
|
3732
|
+
if (cleanId.includes("vendor/react-server-dom/cjs/") && cleanId.includes("client.browser")) {
|
|
3432
3733
|
let transformed = code;
|
|
3433
3734
|
const licenseMatch = transformed.match(/^\/\*\*[\s\S]*?\*\//);
|
|
3434
3735
|
const license = licenseMatch ? licenseMatch[0] : "";
|
|
@@ -3458,7 +3759,7 @@ function createCjsToEsmPlugin() {
|
|
|
3458
3759
|
"export const $1 ="
|
|
3459
3760
|
);
|
|
3460
3761
|
transformed = license + "\n" + transformed;
|
|
3461
|
-
|
|
3762
|
+
debug8?.("cjs-to-esm body rewrite %s", id);
|
|
3462
3763
|
return {
|
|
3463
3764
|
code: transformed,
|
|
3464
3765
|
map: null
|
|
@@ -3547,7 +3848,7 @@ function createCloudflareProtocolStubPlugin() {
|
|
|
3547
3848
|
if (!code.includes(CF_PREFIX)) return null;
|
|
3548
3849
|
let ast;
|
|
3549
3850
|
try {
|
|
3550
|
-
ast = this.parse(code);
|
|
3851
|
+
ast = this.parse(code, { lang: "tsx" });
|
|
3551
3852
|
} catch {
|
|
3552
3853
|
return null;
|
|
3553
3854
|
}
|
|
@@ -3607,72 +3908,6 @@ function walk(node, visit) {
|
|
|
3607
3908
|
}
|
|
3608
3909
|
}
|
|
3609
3910
|
|
|
3610
|
-
// src/vite/plugins/client-ref-hashing.ts
|
|
3611
|
-
import { relative } from "node:path";
|
|
3612
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
3613
|
-
var debug8 = createRangoDebugger(NS.transform);
|
|
3614
|
-
var CLIENT_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-package-proxy/";
|
|
3615
|
-
var CLIENT_IN_SERVER_PKG_PROXY_PREFIX = "/@id/__x00__virtual:vite-rsc/client-in-server-package-proxy/";
|
|
3616
|
-
var FS_PREFIX = "/@fs/";
|
|
3617
|
-
function computeProductionHash(projectRoot, refKey) {
|
|
3618
|
-
let toHash;
|
|
3619
|
-
if (refKey.startsWith(CLIENT_PKG_PROXY_PREFIX)) {
|
|
3620
|
-
toHash = refKey.slice(CLIENT_PKG_PROXY_PREFIX.length);
|
|
3621
|
-
} else if (refKey.startsWith(CLIENT_IN_SERVER_PKG_PROXY_PREFIX)) {
|
|
3622
|
-
const absPath = decodeURIComponent(
|
|
3623
|
-
refKey.slice(CLIENT_IN_SERVER_PKG_PROXY_PREFIX.length)
|
|
3624
|
-
);
|
|
3625
|
-
toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
|
|
3626
|
-
} else if (refKey.startsWith(FS_PREFIX)) {
|
|
3627
|
-
const absPath = refKey.slice(FS_PREFIX.length - 1);
|
|
3628
|
-
toHash = relative(projectRoot, absPath).replaceAll("\\", "/");
|
|
3629
|
-
} else if (refKey.startsWith("/")) {
|
|
3630
|
-
toHash = refKey.slice(1);
|
|
3631
|
-
} else {
|
|
3632
|
-
return refKey;
|
|
3633
|
-
}
|
|
3634
|
-
return createHash2("sha256").update(toHash).digest("hex").slice(0, 12);
|
|
3635
|
-
}
|
|
3636
|
-
var REGISTER_CLIENT_REF_RE = /registerClientReference\(\s*(?:(?:\([^)]*\))|(?:\(\)[\s\S]*?\}))\s*,\s*"([^"]+)"\s*,\s*"[^"]+"\s*\)/g;
|
|
3637
|
-
function transformClientRefs(code, projectRoot) {
|
|
3638
|
-
if (!code.includes("registerClientReference")) return null;
|
|
3639
|
-
let hasReplacement = false;
|
|
3640
|
-
const result = code.replace(
|
|
3641
|
-
REGISTER_CLIENT_REF_RE,
|
|
3642
|
-
(match, refKey) => {
|
|
3643
|
-
const hash = computeProductionHash(projectRoot, refKey);
|
|
3644
|
-
if (hash === refKey) return match;
|
|
3645
|
-
hasReplacement = true;
|
|
3646
|
-
return match.replace(`"${refKey}"`, `"${hash}"`);
|
|
3647
|
-
}
|
|
3648
|
-
);
|
|
3649
|
-
return hasReplacement ? result : null;
|
|
3650
|
-
}
|
|
3651
|
-
function hashClientRefs(projectRoot) {
|
|
3652
|
-
const counter = createCounter(debug8, "hash-client-refs");
|
|
3653
|
-
return {
|
|
3654
|
-
name: "@rangojs/router:hash-client-refs",
|
|
3655
|
-
// Run after the RSC plugin's transform (default enforce is normal)
|
|
3656
|
-
enforce: "post",
|
|
3657
|
-
applyToEnvironment(env) {
|
|
3658
|
-
return env.name === "rsc";
|
|
3659
|
-
},
|
|
3660
|
-
buildEnd() {
|
|
3661
|
-
counter?.flush();
|
|
3662
|
-
},
|
|
3663
|
-
transform(code, id) {
|
|
3664
|
-
const start = counter ? performance.now() : 0;
|
|
3665
|
-
try {
|
|
3666
|
-
const result = transformClientRefs(code, projectRoot);
|
|
3667
|
-
if (result === null) return;
|
|
3668
|
-
return { code: result, map: null };
|
|
3669
|
-
} finally {
|
|
3670
|
-
counter?.record(id, performance.now() - start);
|
|
3671
|
-
}
|
|
3672
|
-
}
|
|
3673
|
-
};
|
|
3674
|
-
}
|
|
3675
|
-
|
|
3676
3911
|
// src/vite/utils/bundle-analysis.ts
|
|
3677
3912
|
function findMatchingParenInBundle(code, openParenPos) {
|
|
3678
3913
|
let depth = 1;
|
|
@@ -3703,7 +3938,7 @@ function extractHandlerExportsFromChunk(chunkCode, handlerModules, fnName, detec
|
|
|
3703
3938
|
if (detectPassthrough) {
|
|
3704
3939
|
const eFnName = escapeRegExp(fnName);
|
|
3705
3940
|
const callStartRe = new RegExp(
|
|
3706
|
-
`const\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
|
|
3941
|
+
`(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
|
|
3707
3942
|
);
|
|
3708
3943
|
const callStart = callStartRe.exec(chunkCode);
|
|
3709
3944
|
if (callStart) {
|
|
@@ -3728,7 +3963,7 @@ function evictHandlerCode(code, exports, fnName, brand) {
|
|
|
3728
3963
|
if (passthrough) continue;
|
|
3729
3964
|
const eName = escapeRegExp(name);
|
|
3730
3965
|
const callStartRe = new RegExp(
|
|
3731
|
-
`const\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
|
|
3966
|
+
`(?:const|let|var)\\s+${eName}\\s*=\\s*${eFnName}\\s*(?:<[^>]*>)?\\s*\\(`
|
|
3732
3967
|
);
|
|
3733
3968
|
const startMatch = callStartRe.exec(modified);
|
|
3734
3969
|
if (!startMatch) continue;
|
|
@@ -3763,6 +3998,8 @@ function createDiscoveryState(entryPath, opts) {
|
|
|
3763
3998
|
projectRoot: "",
|
|
3764
3999
|
isBuildMode: false,
|
|
3765
4000
|
userResolveAlias: void 0,
|
|
4001
|
+
userRunnerConfig: void 0,
|
|
4002
|
+
userResolvePlugins: [],
|
|
3766
4003
|
scanFilter: void 0,
|
|
3767
4004
|
cachedRouterFiles: void 0,
|
|
3768
4005
|
opts,
|
|
@@ -3784,7 +4021,8 @@ function createDiscoveryState(entryPath, opts) {
|
|
|
3784
4021
|
devServerOrigin: null,
|
|
3785
4022
|
devServer: null,
|
|
3786
4023
|
selfWrittenGenFiles: /* @__PURE__ */ new Map(),
|
|
3787
|
-
SELF_WRITE_WINDOW_MS: 5e3
|
|
4024
|
+
SELF_WRITE_WINDOW_MS: 5e3,
|
|
4025
|
+
lastDiscoveryError: null
|
|
3788
4026
|
};
|
|
3789
4027
|
}
|
|
3790
4028
|
|
|
@@ -3824,9 +4062,12 @@ function checkSelfGenWrite(state, filePath, consume) {
|
|
|
3824
4062
|
|
|
3825
4063
|
// src/vite/utils/manifest-utils.ts
|
|
3826
4064
|
function flattenLeafEntries(prefixTree, routeManifest, result) {
|
|
3827
|
-
function visit(node) {
|
|
4065
|
+
function visit(node, ancestorStaticPrefixes) {
|
|
3828
4066
|
const children = node.children || {};
|
|
3829
4067
|
if (Object.keys(children).length === 0 && node.routes && node.routes.length > 0) {
|
|
4068
|
+
if (ancestorStaticPrefixes.has(node.staticPrefix)) {
|
|
4069
|
+
return;
|
|
4070
|
+
}
|
|
3830
4071
|
const routes = {};
|
|
3831
4072
|
for (const name of node.routes) {
|
|
3832
4073
|
if (name in routeManifest) {
|
|
@@ -3835,13 +4076,15 @@ function flattenLeafEntries(prefixTree, routeManifest, result) {
|
|
|
3835
4076
|
}
|
|
3836
4077
|
result.push({ staticPrefix: node.staticPrefix, routes });
|
|
3837
4078
|
} else {
|
|
4079
|
+
const nextAncestors = new Set(ancestorStaticPrefixes);
|
|
4080
|
+
nextAncestors.add(node.staticPrefix);
|
|
3838
4081
|
for (const child of Object.values(children)) {
|
|
3839
|
-
visit(child);
|
|
4082
|
+
visit(child, nextAncestors);
|
|
3840
4083
|
}
|
|
3841
4084
|
}
|
|
3842
4085
|
}
|
|
3843
4086
|
for (const node of Object.values(prefixTree)) {
|
|
3844
|
-
visit(node);
|
|
4087
|
+
visit(node, /* @__PURE__ */ new Set());
|
|
3845
4088
|
}
|
|
3846
4089
|
}
|
|
3847
4090
|
function buildRouteToStaticPrefix(prefixTree, result) {
|
|
@@ -4068,7 +4311,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4068
4311
|
const progressInterval = totalDynamic > 0 ? setInterval(() => {
|
|
4069
4312
|
const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
|
|
4070
4313
|
console.log(
|
|
4071
|
-
`[
|
|
4314
|
+
`[rango] Resolving prerender params... ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
|
|
4072
4315
|
);
|
|
4073
4316
|
}, 5e3) : void 0;
|
|
4074
4317
|
try {
|
|
@@ -4105,7 +4348,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4105
4348
|
get env() {
|
|
4106
4349
|
if (buildEnv !== void 0) return buildEnv;
|
|
4107
4350
|
throw new Error(
|
|
4108
|
-
"[
|
|
4351
|
+
"[rango] ctx.env is not available during build-time getParams(). Configure buildEnv in your rango() plugin options to enable build-time env access."
|
|
4109
4352
|
);
|
|
4110
4353
|
}
|
|
4111
4354
|
};
|
|
@@ -4146,7 +4389,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4146
4389
|
resolvedRoutes++;
|
|
4147
4390
|
if (err.name === "Skip") {
|
|
4148
4391
|
console.log(
|
|
4149
|
-
`[
|
|
4392
|
+
`[rango] SKIP route "${routeName}" - ${err.message}`
|
|
4150
4393
|
);
|
|
4151
4394
|
notifyOnError(
|
|
4152
4395
|
registry,
|
|
@@ -4159,14 +4402,14 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4159
4402
|
continue;
|
|
4160
4403
|
}
|
|
4161
4404
|
console.error(
|
|
4162
|
-
`[
|
|
4405
|
+
`[rango] Failed to get params for prerender route "${routeName}": ${err.message}`
|
|
4163
4406
|
);
|
|
4164
4407
|
notifyOnError(registry, err, "prerender", routeName);
|
|
4165
4408
|
throw err;
|
|
4166
4409
|
}
|
|
4167
4410
|
} else {
|
|
4168
4411
|
console.warn(
|
|
4169
|
-
`[
|
|
4412
|
+
`[rango] Dynamic prerender route "${routeName}" has no getParams(), skipping`
|
|
4170
4413
|
);
|
|
4171
4414
|
}
|
|
4172
4415
|
}
|
|
@@ -4177,7 +4420,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4177
4420
|
clearInterval(progressInterval);
|
|
4178
4421
|
const elapsed = ((performance.now() - paramsStart) / 1e3).toFixed(1);
|
|
4179
4422
|
console.log(
|
|
4180
|
-
`[
|
|
4423
|
+
`[rango] Resolved prerender params: ${resolvedRoutes}/${totalDynamic} routes (${elapsed}s)`
|
|
4181
4424
|
);
|
|
4182
4425
|
}
|
|
4183
4426
|
}
|
|
@@ -4191,7 +4434,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4191
4434
|
const maxConcurrency = Math.max(...entries.map((e) => e.concurrency));
|
|
4192
4435
|
const concurrencyNote = maxConcurrency > 1 ? ` (concurrency: ${maxConcurrency})` : "";
|
|
4193
4436
|
console.log(
|
|
4194
|
-
`[
|
|
4437
|
+
`[rango] Pre-rendering ${entries.length} URL(s)${concurrencyNote}...`
|
|
4195
4438
|
);
|
|
4196
4439
|
debug9?.(
|
|
4197
4440
|
"prerender loop: %d entries, max concurrency %d",
|
|
@@ -4224,7 +4467,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4224
4467
|
if (result.passthrough) {
|
|
4225
4468
|
const elapsed2 = (performance.now() - startUrl).toFixed(0);
|
|
4226
4469
|
console.log(
|
|
4227
|
-
`[
|
|
4470
|
+
`[rango] PASS ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - live fallback`
|
|
4228
4471
|
);
|
|
4229
4472
|
doneCount++;
|
|
4230
4473
|
break;
|
|
@@ -4257,7 +4500,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4257
4500
|
}
|
|
4258
4501
|
const elapsed = (performance.now() - startUrl).toFixed(0);
|
|
4259
4502
|
console.log(
|
|
4260
|
-
`[
|
|
4503
|
+
`[rango] OK ${entry.urlPath.padEnd(40)} (${elapsed}ms)`
|
|
4261
4504
|
);
|
|
4262
4505
|
doneCount++;
|
|
4263
4506
|
break;
|
|
@@ -4265,7 +4508,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4265
4508
|
if (err.name === "Skip") {
|
|
4266
4509
|
const elapsed2 = (performance.now() - startUrl).toFixed(0);
|
|
4267
4510
|
console.log(
|
|
4268
|
-
`[
|
|
4511
|
+
`[rango] SKIP ${entry.urlPath.padEnd(40)} (${elapsed2}ms) - ${err.message}`
|
|
4269
4512
|
);
|
|
4270
4513
|
skipCount++;
|
|
4271
4514
|
notifyOnError(
|
|
@@ -4280,7 +4523,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4280
4523
|
}
|
|
4281
4524
|
const elapsed = (performance.now() - startUrl).toFixed(0);
|
|
4282
4525
|
console.error(
|
|
4283
|
-
`[
|
|
4526
|
+
`[rango] FAIL ${entry.urlPath.padEnd(40)} (${elapsed}ms) - ${err.message}`
|
|
4284
4527
|
);
|
|
4285
4528
|
notifyOnError(
|
|
4286
4529
|
registry,
|
|
@@ -4302,7 +4545,7 @@ async function expandPrerenderRoutes(state, rscEnv, registry, allManifests) {
|
|
|
4302
4545
|
const parts = [`${doneCount} done`];
|
|
4303
4546
|
if (skipCount > 0) parts.push(`${skipCount} skipped`);
|
|
4304
4547
|
console.log(
|
|
4305
|
-
`[
|
|
4548
|
+
`[rango] Pre-render complete: ${parts.join(", ")} (${totalElapsed}ms total)`
|
|
4306
4549
|
);
|
|
4307
4550
|
debug9?.(
|
|
4308
4551
|
"expandPrerenderRoutes done: %d done, %d skipped, %sms (overall %sms)",
|
|
@@ -4328,16 +4571,14 @@ async function renderStaticHandlers(state, rscEnv, registry) {
|
|
|
4328
4571
|
totalStaticCount += exportNames.length;
|
|
4329
4572
|
}
|
|
4330
4573
|
const startStatic = performance.now();
|
|
4331
|
-
console.log(
|
|
4332
|
-
`[rsc-router] Rendering ${totalStaticCount} static handler(s)...`
|
|
4333
|
-
);
|
|
4574
|
+
console.log(`[rango] Rendering ${totalStaticCount} static handler(s)...`);
|
|
4334
4575
|
for (const [moduleId, exportNames] of state.resolvedStaticModules) {
|
|
4335
4576
|
let mod;
|
|
4336
4577
|
try {
|
|
4337
4578
|
mod = await rscEnv.runner.import(moduleId);
|
|
4338
4579
|
} catch (err) {
|
|
4339
4580
|
console.error(
|
|
4340
|
-
`[
|
|
4581
|
+
`[rango] Failed to import static module ${moduleId}: ${err.message}`
|
|
4341
4582
|
);
|
|
4342
4583
|
notifyOnError(registry, err, "static");
|
|
4343
4584
|
throw err;
|
|
@@ -4367,9 +4608,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
|
|
|
4367
4608
|
exportValue
|
|
4368
4609
|
);
|
|
4369
4610
|
const elapsed = (performance.now() - startHandler).toFixed(0);
|
|
4370
|
-
console.log(
|
|
4371
|
-
`[rsc-router] OK ${name.padEnd(40)} (${elapsed}ms)`
|
|
4372
|
-
);
|
|
4611
|
+
console.log(`[rango] OK ${name.padEnd(40)} (${elapsed}ms)`);
|
|
4373
4612
|
staticDone++;
|
|
4374
4613
|
handled = true;
|
|
4375
4614
|
break;
|
|
@@ -4378,7 +4617,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
|
|
|
4378
4617
|
if (err.name === "Skip") {
|
|
4379
4618
|
const elapsed2 = (performance.now() - startHandler).toFixed(0);
|
|
4380
4619
|
console.log(
|
|
4381
|
-
`[
|
|
4620
|
+
`[rango] SKIP ${name.padEnd(40)} (${elapsed2}ms) - ${err.message}`
|
|
4382
4621
|
);
|
|
4383
4622
|
staticSkip++;
|
|
4384
4623
|
notifyOnError(registry, err, "static", void 0, void 0, true);
|
|
@@ -4387,16 +4626,14 @@ async function renderStaticHandlers(state, rscEnv, registry) {
|
|
|
4387
4626
|
}
|
|
4388
4627
|
const elapsed = (performance.now() - startHandler).toFixed(0);
|
|
4389
4628
|
console.error(
|
|
4390
|
-
`[
|
|
4629
|
+
`[rango] FAIL ${name.padEnd(40)} (${elapsed}ms) - ${err.message}`
|
|
4391
4630
|
);
|
|
4392
4631
|
notifyOnError(registry, err, "static");
|
|
4393
4632
|
throw err;
|
|
4394
4633
|
}
|
|
4395
4634
|
}
|
|
4396
4635
|
if (!handled) {
|
|
4397
|
-
console.warn(
|
|
4398
|
-
`[rsc-router] No router could render static handler "${name}"`
|
|
4399
|
-
);
|
|
4636
|
+
console.warn(`[rango] No router could render static handler "${name}"`);
|
|
4400
4637
|
}
|
|
4401
4638
|
}
|
|
4402
4639
|
}
|
|
@@ -4407,7 +4644,7 @@ async function renderStaticHandlers(state, rscEnv, registry) {
|
|
|
4407
4644
|
const staticParts = [`${staticDone} done`];
|
|
4408
4645
|
if (staticSkip > 0) staticParts.push(`${staticSkip} skipped`);
|
|
4409
4646
|
console.log(
|
|
4410
|
-
`[
|
|
4647
|
+
`[rango] Static render complete: ${staticParts.join(", ")} (${totalStaticElapsed}ms total)`
|
|
4411
4648
|
);
|
|
4412
4649
|
debug9?.(
|
|
4413
4650
|
"renderStaticHandlers done: %d done, %d skipped, %sms (overall %sms)",
|
|
@@ -4418,6 +4655,80 @@ async function renderStaticHandlers(state, rscEnv, registry) {
|
|
|
4418
4655
|
);
|
|
4419
4656
|
}
|
|
4420
4657
|
|
|
4658
|
+
// src/vite/discovery/discovery-errors.ts
|
|
4659
|
+
function indent(text, pad) {
|
|
4660
|
+
return text.split("\n").map((line) => line.length > 0 ? pad + line : line).join("\n");
|
|
4661
|
+
}
|
|
4662
|
+
async function invokeLazyMount(loader, context, errors) {
|
|
4663
|
+
try {
|
|
4664
|
+
await loader();
|
|
4665
|
+
} catch (error) {
|
|
4666
|
+
errors.push({ context, error });
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
function isLazyMount(route) {
|
|
4670
|
+
return !!route && route.kind === "lazy" && typeof route.handler === "function";
|
|
4671
|
+
}
|
|
4672
|
+
async function resolveHostRouterHandlers(hostRegistry) {
|
|
4673
|
+
const errors = [];
|
|
4674
|
+
for (const [hostId, entry] of hostRegistry) {
|
|
4675
|
+
for (const route of entry.routes) {
|
|
4676
|
+
if (isLazyMount(route)) {
|
|
4677
|
+
await invokeLazyMount(
|
|
4678
|
+
route.handler,
|
|
4679
|
+
`host "${hostId}" route handler`,
|
|
4680
|
+
errors
|
|
4681
|
+
);
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
if (isLazyMount(entry.fallback)) {
|
|
4685
|
+
await invokeLazyMount(
|
|
4686
|
+
entry.fallback.handler,
|
|
4687
|
+
`host "${hostId}" fallback handler`,
|
|
4688
|
+
errors
|
|
4689
|
+
);
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
return errors;
|
|
4693
|
+
}
|
|
4694
|
+
function formatNoRoutersError(entryPath, errors) {
|
|
4695
|
+
const base = `[rango] No routers found in registry after importing ${entryPath}`;
|
|
4696
|
+
if (errors.length === 0) {
|
|
4697
|
+
return base;
|
|
4698
|
+
}
|
|
4699
|
+
const formatted = errors.map(({ context, error }) => {
|
|
4700
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
4701
|
+
const detail = err.stack ?? err.message;
|
|
4702
|
+
return ` - while resolving ${context}:
|
|
4703
|
+
${indent(detail, " ")}`;
|
|
4704
|
+
}).join("\n");
|
|
4705
|
+
return `${base}
|
|
4706
|
+
|
|
4707
|
+
${errors.length} error(s) were caught during host-router discovery and likely explain why no routers were registered:
|
|
4708
|
+
${formatted}`;
|
|
4709
|
+
}
|
|
4710
|
+
function toCause(errors) {
|
|
4711
|
+
if (errors.length === 0) return void 0;
|
|
4712
|
+
if (errors.length === 1) return errors[0].error;
|
|
4713
|
+
return new AggregateError(
|
|
4714
|
+
errors.map((e) => e.error),
|
|
4715
|
+
"Multiple host-router handlers failed during discovery"
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4718
|
+
var DiscoveryError = class _DiscoveryError extends Error {
|
|
4719
|
+
constructor(entryPath, caught) {
|
|
4720
|
+
super(formatNoRoutersError(entryPath, caught));
|
|
4721
|
+
const cause = toCause(caught);
|
|
4722
|
+
if (cause !== void 0) {
|
|
4723
|
+
this.cause = cause;
|
|
4724
|
+
}
|
|
4725
|
+
this.name = "DiscoveryError";
|
|
4726
|
+
this.entryPath = entryPath;
|
|
4727
|
+
this.caught = caught;
|
|
4728
|
+
Object.setPrototypeOf(this, _DiscoveryError.prototype);
|
|
4729
|
+
}
|
|
4730
|
+
};
|
|
4731
|
+
|
|
4421
4732
|
// src/vite/discovery/discover-routers.ts
|
|
4422
4733
|
var debug10 = createRangoDebugger(NS.discovery);
|
|
4423
4734
|
async function discoverRouters(state, rscEnv) {
|
|
@@ -4434,27 +4745,17 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4434
4745
|
);
|
|
4435
4746
|
let registry = serverMod.RouterRegistry;
|
|
4436
4747
|
if (!registry || registry.size === 0) {
|
|
4748
|
+
const discoveryErrors = [];
|
|
4437
4749
|
try {
|
|
4438
4750
|
const hostRegistry = serverMod.HostRouterRegistry;
|
|
4439
4751
|
if (hostRegistry && hostRegistry.size > 0) {
|
|
4440
4752
|
console.log(
|
|
4441
|
-
`[
|
|
4753
|
+
`[rango] Found ${hostRegistry.size} host router(s), resolving lazy handlers...`
|
|
4442
4754
|
);
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
await route.handler();
|
|
4448
|
-
} catch {
|
|
4449
|
-
}
|
|
4450
|
-
}
|
|
4451
|
-
}
|
|
4452
|
-
if (entry.fallback && typeof entry.fallback.handler === "function") {
|
|
4453
|
-
try {
|
|
4454
|
-
await entry.fallback.handler();
|
|
4455
|
-
} catch {
|
|
4456
|
-
}
|
|
4457
|
-
}
|
|
4755
|
+
const handlerErrors = await resolveHostRouterHandlers(hostRegistry);
|
|
4756
|
+
discoveryErrors.push(...handlerErrors);
|
|
4757
|
+
for (const { context, error } of handlerErrors) {
|
|
4758
|
+
debug10?.("caught error while resolving %s: %O", context, error);
|
|
4458
4759
|
}
|
|
4459
4760
|
const freshServerMod = await rscEnv.runner.import(
|
|
4460
4761
|
"@rangojs/router/server"
|
|
@@ -4465,12 +4766,11 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4465
4766
|
registry = freshRegistry;
|
|
4466
4767
|
}
|
|
4467
4768
|
}
|
|
4468
|
-
} catch {
|
|
4769
|
+
} catch (error) {
|
|
4770
|
+
discoveryErrors.push({ context: "host-router discovery", error });
|
|
4469
4771
|
}
|
|
4470
4772
|
if (!registry || registry.size === 0) {
|
|
4471
|
-
throw new
|
|
4472
|
-
`[rsc-router] No routers found in registry after importing ${state.resolvedEntryPath}`
|
|
4473
|
-
);
|
|
4773
|
+
throw new DiscoveryError(state.resolvedEntryPath, discoveryErrors);
|
|
4474
4774
|
}
|
|
4475
4775
|
}
|
|
4476
4776
|
const buildMod = await timed(
|
|
@@ -4498,6 +4798,15 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4498
4798
|
let mergedRouteTrailingSlash = {};
|
|
4499
4799
|
let routerMountIndex = 0;
|
|
4500
4800
|
const allManifests = [];
|
|
4801
|
+
const clientChunkCtx = state.opts?.clientChunkCtx;
|
|
4802
|
+
const collectClientFallbackRef = clientChunkCtx ? (refKey) => clientChunkCtx.fallbackRefs.add(
|
|
4803
|
+
computeProductionHash(state.projectRoot, refKey)
|
|
4804
|
+
) : void 0;
|
|
4805
|
+
const collectFromBoundaryNode = (node) => {
|
|
4806
|
+
if (collectClientFallbackRef && buildMod.collectFallbackClientRefs) {
|
|
4807
|
+
buildMod.collectFallbackClientRefs(node, collectClientFallbackRef);
|
|
4808
|
+
}
|
|
4809
|
+
};
|
|
4501
4810
|
const manifestGenStart = debug10 ? performance.now() : 0;
|
|
4502
4811
|
for (const [id, router] of registry) {
|
|
4503
4812
|
if (!router.urlpatterns || !generateManifestFull) {
|
|
@@ -4506,10 +4815,18 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4506
4815
|
const manifest = generateManifestFull(
|
|
4507
4816
|
router.urlpatterns,
|
|
4508
4817
|
routerMountIndex,
|
|
4509
|
-
|
|
4818
|
+
{
|
|
4819
|
+
...router.__basename ? { urlPrefix: router.__basename } : {},
|
|
4820
|
+
...collectClientFallbackRef ? { collectClientFallbackRef } : {}
|
|
4821
|
+
}
|
|
4510
4822
|
);
|
|
4511
4823
|
routerMountIndex++;
|
|
4512
4824
|
allManifests.push({ id, manifest });
|
|
4825
|
+
if (collectClientFallbackRef) {
|
|
4826
|
+
collectFromBoundaryNode(router.__defaultErrorBoundary);
|
|
4827
|
+
collectFromBoundaryNode(router.__defaultNotFoundBoundary);
|
|
4828
|
+
collectFromBoundaryNode(router.__notFound);
|
|
4829
|
+
}
|
|
4513
4830
|
const routeCount = Object.keys(manifest.routeManifest).length;
|
|
4514
4831
|
const staticRoutes = Object.values(manifest.routeManifest).filter(
|
|
4515
4832
|
(p) => !p.includes(":") && !p.includes("*")
|
|
@@ -4560,7 +4877,7 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4560
4877
|
);
|
|
4561
4878
|
newPerRouterPrecomputedMap.set(id, routerPrecomputed);
|
|
4562
4879
|
console.log(
|
|
4563
|
-
`[
|
|
4880
|
+
`[rango] Router "${id}" -> ${routeCount} routes (${staticRoutes} static, ${dynamicRoutes} dynamic)`
|
|
4564
4881
|
);
|
|
4565
4882
|
}
|
|
4566
4883
|
if (registry.size > 1) {
|
|
@@ -4569,7 +4886,7 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4569
4886
|
);
|
|
4570
4887
|
if (autoIds.length > 1) {
|
|
4571
4888
|
console.warn(
|
|
4572
|
-
`[
|
|
4889
|
+
`[rango] WARNING: ${autoIds.length} routers use auto-generated IDs (${autoIds.join(", ")}). In multi-router setups, each createRouter() must have an explicit \`id\` option to ensure per-router manifest data is matched correctly at runtime. Example: createRouter({ id: "site", ... })`
|
|
4573
4890
|
);
|
|
4574
4891
|
}
|
|
4575
4892
|
}
|
|
@@ -4614,10 +4931,10 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4614
4931
|
newMergedRouteManifest,
|
|
4615
4932
|
mergedRouteAncestry,
|
|
4616
4933
|
routeToStaticPrefix,
|
|
4617
|
-
|
|
4618
|
-
prerenderRouteNames
|
|
4619
|
-
passthroughRouteNames
|
|
4620
|
-
|
|
4934
|
+
mergedRouteTrailingSlash,
|
|
4935
|
+
prerenderRouteNames,
|
|
4936
|
+
passthroughRouteNames,
|
|
4937
|
+
mergedResponseTypeRoutes
|
|
4621
4938
|
);
|
|
4622
4939
|
for (const { id, manifest } of allManifests) {
|
|
4623
4940
|
if (!manifest._routeAncestry || Object.keys(manifest._routeAncestry).length === 0)
|
|
@@ -4633,10 +4950,10 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4633
4950
|
manifest.routeManifest,
|
|
4634
4951
|
manifest._routeAncestry,
|
|
4635
4952
|
perRouterStaticPrefix,
|
|
4636
|
-
manifest.routeTrailingSlash
|
|
4637
|
-
perRouterPrerenderNames
|
|
4638
|
-
perRouterPassthroughNames
|
|
4639
|
-
manifest.responseTypeRoutes
|
|
4953
|
+
manifest.routeTrailingSlash,
|
|
4954
|
+
perRouterPrerenderNames,
|
|
4955
|
+
perRouterPassthroughNames,
|
|
4956
|
+
manifest.responseTypeRoutes
|
|
4640
4957
|
);
|
|
4641
4958
|
newPerRouterTrieMap.set(id, perRouterTrie);
|
|
4642
4959
|
}
|
|
@@ -4659,7 +4976,7 @@ async function discoverRouters(state, rscEnv) {
|
|
|
4659
4976
|
}
|
|
4660
4977
|
|
|
4661
4978
|
// src/vite/discovery/route-types-writer.ts
|
|
4662
|
-
import { dirname as dirname3,
|
|
4979
|
+
import { dirname as dirname3, join as join2, resolve as resolve6 } from "node:path";
|
|
4663
4980
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5, unlinkSync as unlinkSync2 } from "node:fs";
|
|
4664
4981
|
function filterUserNamedRoutes(manifest) {
|
|
4665
4982
|
const filtered = {};
|
|
@@ -4670,39 +4987,20 @@ function filterUserNamedRoutes(manifest) {
|
|
|
4670
4987
|
}
|
|
4671
4988
|
return filtered;
|
|
4672
4989
|
}
|
|
4990
|
+
function writeGenFileIfChanged(state, outPath, source, opts) {
|
|
4991
|
+
const existing = existsSync5(outPath) ? readFileSync4(outPath, "utf-8") : null;
|
|
4992
|
+
if (existing === source) return;
|
|
4993
|
+
markSelfGenWrite(state, outPath, source);
|
|
4994
|
+
writeFileSync3(outPath, source);
|
|
4995
|
+
if (opts?.log) console.log(`[rango] Generated route types -> ${outPath}`);
|
|
4996
|
+
}
|
|
4673
4997
|
function writeCombinedRouteTypesWithTracking(state, opts) {
|
|
4674
4998
|
const routerFiles = state.cachedRouterFiles ?? findRouterFiles(state.projectRoot, state.scanFilter);
|
|
4675
4999
|
state.cachedRouterFiles = routerFiles;
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
/\.(tsx?|jsx?)$/,
|
|
4681
|
-
""
|
|
4682
|
-
);
|
|
4683
|
-
const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
4684
|
-
try {
|
|
4685
|
-
preContent.set(outPath, readFileSync4(outPath, "utf-8"));
|
|
4686
|
-
} catch {
|
|
4687
|
-
}
|
|
4688
|
-
}
|
|
4689
|
-
writeCombinedRouteTypes(state.projectRoot, routerFiles, opts);
|
|
4690
|
-
for (const routerFilePath of routerFiles) {
|
|
4691
|
-
const routerDir = dirname3(routerFilePath);
|
|
4692
|
-
const routerBasename = basename(routerFilePath).replace(
|
|
4693
|
-
/\.(tsx?|jsx?)$/,
|
|
4694
|
-
""
|
|
4695
|
-
);
|
|
4696
|
-
const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
4697
|
-
if (!existsSync5(outPath)) continue;
|
|
4698
|
-
try {
|
|
4699
|
-
const content = readFileSync4(outPath, "utf-8");
|
|
4700
|
-
if (content !== preContent.get(outPath)) {
|
|
4701
|
-
markSelfGenWrite(state, outPath, content);
|
|
4702
|
-
}
|
|
4703
|
-
} catch {
|
|
4704
|
-
}
|
|
4705
|
-
}
|
|
5000
|
+
writeCombinedRouteTypes(state.projectRoot, routerFiles, {
|
|
5001
|
+
...opts,
|
|
5002
|
+
onWrite: (outPath, content) => markSelfGenWrite(state, outPath, content)
|
|
5003
|
+
});
|
|
4706
5004
|
}
|
|
4707
5005
|
function writeRouteTypesFiles(state) {
|
|
4708
5006
|
if (state.perRouterManifests.length === 0) return;
|
|
@@ -4714,7 +5012,7 @@ function writeRouteTypesFiles(state) {
|
|
|
4714
5012
|
if (existsSync5(oldCombinedPath)) {
|
|
4715
5013
|
unlinkSync2(oldCombinedPath);
|
|
4716
5014
|
console.log(
|
|
4717
|
-
`[
|
|
5015
|
+
`[rango] Removed stale combined route types: ${oldCombinedPath}`
|
|
4718
5016
|
);
|
|
4719
5017
|
}
|
|
4720
5018
|
} catch {
|
|
@@ -4728,39 +5026,23 @@ function writeRouteTypesFiles(state) {
|
|
|
4728
5026
|
if (!sourceFile) continue;
|
|
4729
5027
|
if (sourceFile.includes("node_modules")) {
|
|
4730
5028
|
throw new Error(
|
|
4731
|
-
`[
|
|
5029
|
+
`[rango] Router "${id}" has sourceFile inside node_modules: ${sourceFile}
|
|
4732
5030
|
This means createRouter() stack trace parsing matched a Vite internal frame.
|
|
4733
5031
|
Set an explicit \`id\` on createRouter() or check the call site.`
|
|
4734
5032
|
);
|
|
4735
5033
|
}
|
|
4736
|
-
const
|
|
4737
|
-
const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
4738
|
-
const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
5034
|
+
const outPath = genFileTsPath(sourceFile);
|
|
4739
5035
|
const userRoutes = filterUserNamedRoutes(routeManifest);
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
for (const name of Object.keys(userRoutes)) {
|
|
4746
|
-
const schema = staticParsed.searchSchemas[name];
|
|
4747
|
-
if (schema) filtered[name] = schema;
|
|
4748
|
-
}
|
|
4749
|
-
if (Object.keys(filtered).length > 0) {
|
|
4750
|
-
effectiveSearchSchemas = filtered;
|
|
4751
|
-
}
|
|
4752
|
-
}
|
|
4753
|
-
}
|
|
5036
|
+
const effectiveSearchSchemas = resolveSearchSchemas(
|
|
5037
|
+
Object.keys(userRoutes),
|
|
5038
|
+
routeSearchSchemas,
|
|
5039
|
+
sourceFile
|
|
5040
|
+
);
|
|
4754
5041
|
const source = generateRouteTypesSource(
|
|
4755
5042
|
userRoutes,
|
|
4756
5043
|
effectiveSearchSchemas && Object.keys(effectiveSearchSchemas).length > 0 ? effectiveSearchSchemas : void 0
|
|
4757
5044
|
);
|
|
4758
|
-
|
|
4759
|
-
if (existing !== source) {
|
|
4760
|
-
markSelfGenWrite(state, outPath, source);
|
|
4761
|
-
writeFileSync3(outPath, source);
|
|
4762
|
-
console.log(`[rsc-router] Generated route types -> ${outPath}`);
|
|
4763
|
-
}
|
|
5045
|
+
writeGenFileIfChanged(state, outPath, source, { log: true });
|
|
4764
5046
|
}
|
|
4765
5047
|
}
|
|
4766
5048
|
function supplementGenFilesWithRuntimeRoutes(state) {
|
|
@@ -4798,23 +5080,17 @@ function supplementGenFilesWithRuntimeRoutes(state) {
|
|
|
4798
5080
|
}
|
|
4799
5081
|
}
|
|
4800
5082
|
}
|
|
4801
|
-
const
|
|
4802
|
-
const routerBasename = basename(sourceFile).replace(/\.(tsx?|jsx?)$/, "");
|
|
4803
|
-
const outPath = join2(routerDir, `${routerBasename}.named-routes.gen.ts`);
|
|
5083
|
+
const outPath = genFileTsPath(sourceFile);
|
|
4804
5084
|
const source = generateRouteTypesSource(
|
|
4805
5085
|
mergedRoutes,
|
|
4806
5086
|
Object.keys(mergedSearchSchemas).length > 0 ? mergedSearchSchemas : void 0
|
|
4807
5087
|
);
|
|
4808
|
-
|
|
4809
|
-
if (existing !== source) {
|
|
4810
|
-
markSelfGenWrite(state, outPath, source);
|
|
4811
|
-
writeFileSync3(outPath, source);
|
|
4812
|
-
}
|
|
5088
|
+
writeGenFileIfChanged(state, outPath, source);
|
|
4813
5089
|
}
|
|
4814
5090
|
}
|
|
4815
5091
|
|
|
4816
5092
|
// src/vite/discovery/virtual-module-codegen.ts
|
|
4817
|
-
import { dirname as dirname4, basename
|
|
5093
|
+
import { dirname as dirname4, basename, join as join3 } from "node:path";
|
|
4818
5094
|
function generateRoutesManifestModule(state) {
|
|
4819
5095
|
const hasManifest = state.mergedRouteManifest && Object.keys(state.mergedRouteManifest).length > 0;
|
|
4820
5096
|
if (hasManifest) {
|
|
@@ -4825,7 +5101,7 @@ function generateRoutesManifestModule(state) {
|
|
|
4825
5101
|
for (const entry of state.perRouterManifests) {
|
|
4826
5102
|
if (entry.sourceFile) {
|
|
4827
5103
|
const routerDir = dirname4(entry.sourceFile);
|
|
4828
|
-
const routerBasename =
|
|
5104
|
+
const routerBasename = basename(entry.sourceFile).replace(
|
|
4829
5105
|
/\.(tsx?|jsx?)$/,
|
|
4830
5106
|
""
|
|
4831
5107
|
);
|
|
@@ -4846,7 +5122,7 @@ function generateRoutesManifestModule(state) {
|
|
|
4846
5122
|
}
|
|
4847
5123
|
}
|
|
4848
5124
|
const lines = [
|
|
4849
|
-
`import { setCachedManifest,
|
|
5125
|
+
`import { setCachedManifest, setRouterManifest, registerRouterManifestLoader, clearAllRouterData } from "@rangojs/router/server";`,
|
|
4850
5126
|
...genFileImports,
|
|
4851
5127
|
// Clear stale per-router cached data (manifest, trie, precomputed entries)
|
|
4852
5128
|
// before re-populating. In Cloudflare dev mode, program reloads re-evaluate
|
|
@@ -4882,18 +5158,6 @@ function generateRoutesManifestModule(state) {
|
|
|
4882
5158
|
);
|
|
4883
5159
|
}
|
|
4884
5160
|
}
|
|
4885
|
-
if (state.isBuildMode) {
|
|
4886
|
-
if (state.mergedPrecomputedEntries && state.mergedPrecomputedEntries.length > 0) {
|
|
4887
|
-
lines.push(
|
|
4888
|
-
`setPrecomputedEntries(${jsonParseExpression(state.mergedPrecomputedEntries)});`
|
|
4889
|
-
);
|
|
4890
|
-
}
|
|
4891
|
-
if (state.mergedRouteTrie) {
|
|
4892
|
-
lines.push(
|
|
4893
|
-
`setRouteTrie(${jsonParseExpression(state.mergedRouteTrie)});`
|
|
4894
|
-
);
|
|
4895
|
-
}
|
|
4896
|
-
}
|
|
4897
5161
|
for (const routerId of state.perRouterManifestDataMap.keys()) {
|
|
4898
5162
|
lines.push(
|
|
4899
5163
|
`registerRouterManifestLoader(${JSON.stringify(routerId)}, () => import(${JSON.stringify(VIRTUAL_ROUTES_MANIFEST_ID + "/" + routerId)}));`
|
|
@@ -4922,7 +5186,7 @@ function generatePerRouterModule(state, routerId) {
|
|
|
4922
5186
|
const lines = [];
|
|
4923
5187
|
if (routerEntry?.sourceFile) {
|
|
4924
5188
|
const routerDir = dirname4(routerEntry.sourceFile);
|
|
4925
|
-
const routerBasename =
|
|
5189
|
+
const routerBasename = basename(routerEntry.sourceFile).replace(
|
|
4926
5190
|
/\.(tsx?|jsx?)$/,
|
|
4927
5191
|
""
|
|
4928
5192
|
);
|
|
@@ -4993,12 +5257,12 @@ function postprocessBundle(state) {
|
|
|
4993
5257
|
writeFileSync4(chunkPath, result.code);
|
|
4994
5258
|
const savedKB = (result.savedBytes / 1024).toFixed(1);
|
|
4995
5259
|
console.log(
|
|
4996
|
-
`[
|
|
5260
|
+
`[rango] Evicted ${target.label} (${savedKB} KB saved): ${info.fileName}`
|
|
4997
5261
|
);
|
|
4998
5262
|
}
|
|
4999
5263
|
} catch (replaceErr) {
|
|
5000
5264
|
console.warn(
|
|
5001
|
-
`[
|
|
5265
|
+
`[rango] Failed to evict ${target.label}: ${replaceErr.message}`
|
|
5002
5266
|
);
|
|
5003
5267
|
}
|
|
5004
5268
|
}
|
|
@@ -5036,11 +5300,11 @@ function postprocessBundle(state) {
|
|
|
5036
5300
|
writeFileSync4(rscEntryPath, injection + rscCode);
|
|
5037
5301
|
const totalKB = (totalBytes / 1024).toFixed(1);
|
|
5038
5302
|
console.log(
|
|
5039
|
-
`[
|
|
5303
|
+
`[rango] Wrote prerender assets (${totalKB} KB total, ${Object.keys(state.prerenderManifestEntries).length} entries)`
|
|
5040
5304
|
);
|
|
5041
5305
|
} catch (err) {
|
|
5042
5306
|
throw new Error(
|
|
5043
|
-
`[
|
|
5307
|
+
`[rango] Failed to write prerender assets: ${err.message}`
|
|
5044
5308
|
);
|
|
5045
5309
|
}
|
|
5046
5310
|
}
|
|
@@ -5074,11 +5338,11 @@ function postprocessBundle(state) {
|
|
|
5074
5338
|
writeFileSync4(rscEntryPath, injection + rscCode);
|
|
5075
5339
|
const totalKB = (totalBytes / 1024).toFixed(1);
|
|
5076
5340
|
console.log(
|
|
5077
|
-
`[
|
|
5341
|
+
`[rango] Wrote static assets (${totalKB} KB total, ${Object.keys(state.staticManifestEntries).length} entries)`
|
|
5078
5342
|
);
|
|
5079
5343
|
} catch (err) {
|
|
5080
5344
|
throw new Error(
|
|
5081
|
-
`[
|
|
5345
|
+
`[rango] Failed to write static assets: ${err.message}`
|
|
5082
5346
|
);
|
|
5083
5347
|
}
|
|
5084
5348
|
}
|
|
@@ -5159,6 +5423,57 @@ function createDiscoveryGate(s, debug11) {
|
|
|
5159
5423
|
};
|
|
5160
5424
|
}
|
|
5161
5425
|
|
|
5426
|
+
// src/vite/utils/forward-user-plugins.ts
|
|
5427
|
+
function isDenied(name) {
|
|
5428
|
+
return name.startsWith("vite:") || name === "rsc" || name.startsWith("rsc:") || name.startsWith("@rangojs/router") || name.startsWith("@cloudflare/vite-plugin") || name.startsWith("vite-plugin-cloudflare");
|
|
5429
|
+
}
|
|
5430
|
+
function hasResolutionHooks(p) {
|
|
5431
|
+
return Boolean(p.resolveId || p.load);
|
|
5432
|
+
}
|
|
5433
|
+
function stripToResolutionHooks(p) {
|
|
5434
|
+
const stripped = { name: p.name };
|
|
5435
|
+
if (p.enforce) stripped.enforce = p.enforce;
|
|
5436
|
+
if (p.applyToEnvironment)
|
|
5437
|
+
stripped.applyToEnvironment = p.applyToEnvironment;
|
|
5438
|
+
if (p.resolveId) stripped.resolveId = p.resolveId;
|
|
5439
|
+
if (p.load) stripped.load = p.load;
|
|
5440
|
+
return stripped;
|
|
5441
|
+
}
|
|
5442
|
+
function selectForwardableResolvePlugins(plugins) {
|
|
5443
|
+
if (!plugins) return [];
|
|
5444
|
+
const forwarded = [];
|
|
5445
|
+
for (const p of plugins) {
|
|
5446
|
+
const name = p?.name;
|
|
5447
|
+
if (!name || isDenied(name)) continue;
|
|
5448
|
+
if (!hasResolutionHooks(p)) continue;
|
|
5449
|
+
forwarded.push(stripToResolutionHooks(p));
|
|
5450
|
+
}
|
|
5451
|
+
return forwarded;
|
|
5452
|
+
}
|
|
5453
|
+
function pickForwardedRunnerConfig(config) {
|
|
5454
|
+
const r = config.resolve ?? {};
|
|
5455
|
+
const resolve10 = {};
|
|
5456
|
+
if (r.alias !== void 0) resolve10.alias = r.alias;
|
|
5457
|
+
if (r.dedupe !== void 0) resolve10.dedupe = r.dedupe;
|
|
5458
|
+
if (r.conditions !== void 0) resolve10.conditions = r.conditions;
|
|
5459
|
+
if (r.mainFields !== void 0) resolve10.mainFields = r.mainFields;
|
|
5460
|
+
if (r.extensions !== void 0) resolve10.extensions = r.extensions;
|
|
5461
|
+
if (r.preserveSymlinks !== void 0)
|
|
5462
|
+
resolve10.preserveSymlinks = r.preserveSymlinks;
|
|
5463
|
+
if (r.tsconfigPaths !== void 0) resolve10.tsconfigPaths = r.tsconfigPaths;
|
|
5464
|
+
const userOxc = config.oxc;
|
|
5465
|
+
const userJsx = userOxc && typeof userOxc === "object" && typeof userOxc.jsx === "object" && userOxc.jsx !== null ? userOxc.jsx : {};
|
|
5466
|
+
const oxc = userOxc && typeof userOxc === "object" ? {
|
|
5467
|
+
...userOxc,
|
|
5468
|
+
jsx: { ...userJsx, runtime: "automatic", importSource: "react" }
|
|
5469
|
+
} : { jsx: { runtime: "automatic", importSource: "react" } };
|
|
5470
|
+
return {
|
|
5471
|
+
resolve: resolve10,
|
|
5472
|
+
define: config.define,
|
|
5473
|
+
oxc
|
|
5474
|
+
};
|
|
5475
|
+
}
|
|
5476
|
+
|
|
5162
5477
|
// src/vite/router-discovery.ts
|
|
5163
5478
|
var debugDiscovery = createRangoDebugger(NS.discovery);
|
|
5164
5479
|
var debugRoutes = createRangoDebugger(NS.routes);
|
|
@@ -5174,21 +5489,29 @@ function ensureCloudflareProtocolLoaderRegistered() {
|
|
|
5174
5489
|
);
|
|
5175
5490
|
} catch (err) {
|
|
5176
5491
|
console.warn(
|
|
5177
|
-
`[
|
|
5492
|
+
`[rango] Could not register Node ESM loader hook for cloudflare:* imports (${err?.message ?? err}). Falling back to Vite transform only.`
|
|
5178
5493
|
);
|
|
5179
5494
|
}
|
|
5180
5495
|
}
|
|
5181
5496
|
async function createTempRscServer(state, options = {}) {
|
|
5182
5497
|
ensureCloudflareProtocolLoaderRegistered();
|
|
5183
5498
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
5499
|
+
const runnerConfig = state.userRunnerConfig;
|
|
5500
|
+
const resolveConfig = runnerConfig?.resolve ?? {
|
|
5501
|
+
alias: state.userResolveAlias
|
|
5502
|
+
};
|
|
5503
|
+
const oxcConfig = runnerConfig?.oxc ?? {
|
|
5504
|
+
jsx: { runtime: "automatic", importSource: "react" }
|
|
5505
|
+
};
|
|
5184
5506
|
return createViteServer({
|
|
5185
5507
|
root: state.projectRoot,
|
|
5186
5508
|
configFile: false,
|
|
5187
5509
|
server: { middlewareMode: true },
|
|
5188
5510
|
appType: "custom",
|
|
5189
5511
|
logLevel: "silent",
|
|
5190
|
-
resolve:
|
|
5191
|
-
|
|
5512
|
+
resolve: resolveConfig,
|
|
5513
|
+
...runnerConfig?.define ? { define: runnerConfig.define } : {},
|
|
5514
|
+
oxc: oxcConfig,
|
|
5192
5515
|
...options.cacheDir && { cacheDir: options.cacheDir },
|
|
5193
5516
|
plugins: [
|
|
5194
5517
|
rsc({
|
|
@@ -5206,7 +5529,11 @@ async function createTempRscServer(state, options = {}) {
|
|
|
5206
5529
|
// Dev prerender must use dev-mode IDs (path-based) to match the workerd
|
|
5207
5530
|
// runtime. forceBuild produces hashed IDs for production bundle consistency.
|
|
5208
5531
|
exposeInternalIds(options.forceBuild ? { forceBuild: true } : void 0),
|
|
5209
|
-
exposeRouterId()
|
|
5532
|
+
exposeRouterId(),
|
|
5533
|
+
// Forwarded user resolution plugins (e.g. vite-tsconfig-paths). Stripped
|
|
5534
|
+
// to resolveId/load and placed last so framework resolution runs first;
|
|
5535
|
+
// Vite re-sorts by `enforce`, so `enforce: "pre"` resolvers still lead.
|
|
5536
|
+
...state.userResolvePlugins
|
|
5210
5537
|
]
|
|
5211
5538
|
});
|
|
5212
5539
|
}
|
|
@@ -5215,7 +5542,7 @@ async function resolveBuildEnv(option, factoryCtx) {
|
|
|
5215
5542
|
if (option === "auto") {
|
|
5216
5543
|
if (factoryCtx.preset !== "cloudflare") {
|
|
5217
5544
|
throw new Error(
|
|
5218
|
-
'[
|
|
5545
|
+
'[rango] buildEnv: "auto" is only supported with preset: "cloudflare". Use a factory function or plain object for other presets.'
|
|
5219
5546
|
);
|
|
5220
5547
|
}
|
|
5221
5548
|
try {
|
|
@@ -5231,7 +5558,7 @@ async function resolveBuildEnv(option, factoryCtx) {
|
|
|
5231
5558
|
};
|
|
5232
5559
|
} catch (err) {
|
|
5233
5560
|
throw new Error(
|
|
5234
|
-
`[
|
|
5561
|
+
`[rango] buildEnv: "auto" requires wrangler to be installed.
|
|
5235
5562
|
Install it with: pnpm add -D wrangler
|
|
5236
5563
|
${err.message}`
|
|
5237
5564
|
);
|
|
@@ -5262,7 +5589,7 @@ async function releaseBuildEnv(s) {
|
|
|
5262
5589
|
try {
|
|
5263
5590
|
await s.buildEnvDispose();
|
|
5264
5591
|
} catch (err) {
|
|
5265
|
-
console.warn(`[
|
|
5592
|
+
console.warn(`[rango] buildEnv dispose failed: ${err.message}`);
|
|
5266
5593
|
}
|
|
5267
5594
|
s.buildEnvDispose = null;
|
|
5268
5595
|
}
|
|
@@ -5289,17 +5616,16 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
5289
5616
|
viteCommand = config.command;
|
|
5290
5617
|
viteMode = config.mode;
|
|
5291
5618
|
s.userResolveAlias = config.resolve.alias;
|
|
5619
|
+
s.userRunnerConfig = pickForwardedRunnerConfig(config);
|
|
5620
|
+
s.userResolvePlugins = selectForwardableResolvePlugins(
|
|
5621
|
+
config.plugins
|
|
5622
|
+
);
|
|
5292
5623
|
if (!s.resolvedEntryPath && opts?.routerPathRef?.path) {
|
|
5293
5624
|
s.resolvedEntryPath = opts.routerPathRef.path;
|
|
5294
5625
|
}
|
|
5295
5626
|
if (!s.resolvedEntryPath) {
|
|
5296
|
-
const
|
|
5297
|
-
|
|
5298
|
-
if (typeof entries === "string") {
|
|
5299
|
-
s.resolvedEntryPath = entries;
|
|
5300
|
-
} else if (Array.isArray(entries) && entries.length > 0) {
|
|
5301
|
-
s.resolvedEntryPath = entries[0];
|
|
5302
|
-
}
|
|
5627
|
+
const entry = resolveRscEntryFromConfig(config);
|
|
5628
|
+
if (entry) s.resolvedEntryPath = entry;
|
|
5303
5629
|
}
|
|
5304
5630
|
if (opts?.staticRouteTypesGeneration !== false) {
|
|
5305
5631
|
s.cachedRouterFiles = findRouterFiles(s.projectRoot, s.scanFilter);
|
|
@@ -5426,9 +5752,7 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
5426
5752
|
"getOrCreateTempServer: FAILED message=%s",
|
|
5427
5753
|
err.message
|
|
5428
5754
|
);
|
|
5429
|
-
console.warn(
|
|
5430
|
-
`[rsc-router] Failed to create temp runner: ${err.message}`
|
|
5431
|
-
);
|
|
5755
|
+
console.warn(`[rango] Failed to create temp runner: ${err.message}`);
|
|
5432
5756
|
}
|
|
5433
5757
|
return null;
|
|
5434
5758
|
}
|
|
@@ -5515,7 +5839,7 @@ function createRouterDiscoveryPlugin(entryPath, opts) {
|
|
|
5515
5839
|
}
|
|
5516
5840
|
} catch (err) {
|
|
5517
5841
|
console.warn(
|
|
5518
|
-
`[
|
|
5842
|
+
`[rango] Cloudflare dev discovery failed: ${err.message}
|
|
5519
5843
|
${err.stack}`
|
|
5520
5844
|
);
|
|
5521
5845
|
}
|
|
@@ -5559,7 +5883,7 @@ ${err.stack}`
|
|
|
5559
5883
|
);
|
|
5560
5884
|
} catch (err) {
|
|
5561
5885
|
console.warn(
|
|
5562
|
-
`[
|
|
5886
|
+
`[rango] Router discovery failed: ${err.message}
|
|
5563
5887
|
${err.stack}`
|
|
5564
5888
|
);
|
|
5565
5889
|
} finally {
|
|
@@ -5592,20 +5916,15 @@ ${err.stack}`
|
|
|
5592
5916
|
if (s.mergedRouteTrie && serverMod.setRouteTrie) {
|
|
5593
5917
|
serverMod.setRouteTrie(s.mergedRouteTrie);
|
|
5594
5918
|
}
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
}
|
|
5605
|
-
if (serverMod.setRouterPrecomputedEntries) {
|
|
5606
|
-
for (const [routerId, entries] of s.perRouterPrecomputedMap) {
|
|
5607
|
-
serverMod.setRouterPrecomputedEntries(routerId, entries);
|
|
5608
|
-
}
|
|
5919
|
+
const perRouterSetters = [
|
|
5920
|
+
[s.perRouterManifestDataMap, "setRouterManifest"],
|
|
5921
|
+
[s.perRouterTrieMap, "setRouterTrie"],
|
|
5922
|
+
[s.perRouterPrecomputedMap, "setRouterPrecomputedEntries"]
|
|
5923
|
+
];
|
|
5924
|
+
for (const [map, fn] of perRouterSetters) {
|
|
5925
|
+
const setter = serverMod[fn];
|
|
5926
|
+
if (typeof setter !== "function") continue;
|
|
5927
|
+
for (const [routerId, value] of map) setter(routerId, value);
|
|
5609
5928
|
}
|
|
5610
5929
|
};
|
|
5611
5930
|
server.middlewares.use("/__rsc_prerender", async (req, res) => {
|
|
@@ -5639,7 +5958,7 @@ ${err.stack}`
|
|
|
5639
5958
|
registry = serverMod.RouterRegistry ?? null;
|
|
5640
5959
|
} catch (err) {
|
|
5641
5960
|
console.warn(
|
|
5642
|
-
`[
|
|
5961
|
+
`[rango] Dev prerender module refresh failed: ${err.message}`
|
|
5643
5962
|
);
|
|
5644
5963
|
res.statusCode = 500;
|
|
5645
5964
|
res.end(`Prerender handler error: ${err.message}`);
|
|
@@ -5697,7 +6016,7 @@ ${err.stack}`
|
|
|
5697
6016
|
return;
|
|
5698
6017
|
} catch (err) {
|
|
5699
6018
|
console.warn(
|
|
5700
|
-
`[
|
|
6019
|
+
`[rango] Dev prerender failed for ${pathname}: ${err.message}`
|
|
5701
6020
|
);
|
|
5702
6021
|
}
|
|
5703
6022
|
}
|
|
@@ -5768,9 +6087,25 @@ ${err.stack}`
|
|
|
5768
6087
|
() => writeRouteTypesFiles(s)
|
|
5769
6088
|
);
|
|
5770
6089
|
}
|
|
6090
|
+
if (s.lastDiscoveryError) {
|
|
6091
|
+
debugDiscovery?.(
|
|
6092
|
+
"hmr: cleared lastDiscoveryError (%s) after successful rediscovery",
|
|
6093
|
+
s.lastDiscoveryError.message
|
|
6094
|
+
);
|
|
6095
|
+
s.lastDiscoveryError = null;
|
|
6096
|
+
}
|
|
6097
|
+
if (rscEnv && !rscEnv.runner) forceCloudflareWorkerReload(rscEnv);
|
|
5771
6098
|
} catch (err) {
|
|
6099
|
+
s.lastDiscoveryError = {
|
|
6100
|
+
message: err?.message ?? String(err),
|
|
6101
|
+
at: Date.now()
|
|
6102
|
+
};
|
|
5772
6103
|
console.warn(
|
|
5773
|
-
`[
|
|
6104
|
+
`[rango] Runtime re-discovery failed: ${err.message}`
|
|
6105
|
+
);
|
|
6106
|
+
debugDiscovery?.(
|
|
6107
|
+
"hmr: lastDiscoveryError set (%s) \u2014 manifest preserved at last-good; recovery mode active (any in-scan source change will trigger rediscovery)",
|
|
6108
|
+
err?.message
|
|
5774
6109
|
);
|
|
5775
6110
|
} finally {
|
|
5776
6111
|
debugDiscovery?.(
|
|
@@ -5780,6 +6115,25 @@ ${err.stack}`
|
|
|
5780
6115
|
}
|
|
5781
6116
|
});
|
|
5782
6117
|
};
|
|
6118
|
+
const forceCloudflareWorkerReload = (rscEnv) => {
|
|
6119
|
+
if (!rscEnv?.hot) return;
|
|
6120
|
+
try {
|
|
6121
|
+
const graph = rscEnv.moduleGraph;
|
|
6122
|
+
if (graph?.invalidateAll) {
|
|
6123
|
+
graph.invalidateAll();
|
|
6124
|
+
debugDiscovery?.("hmr: invalidated workerd rsc module graph");
|
|
6125
|
+
}
|
|
6126
|
+
rscEnv.hot.send({ type: "full-reload" });
|
|
6127
|
+
debugDiscovery?.(
|
|
6128
|
+
"hmr: forced workerd rsc env reload (full-reload)"
|
|
6129
|
+
);
|
|
6130
|
+
} catch (err) {
|
|
6131
|
+
debugDiscovery?.(
|
|
6132
|
+
"hmr: workerd reload failed: %s",
|
|
6133
|
+
err?.message ?? err
|
|
6134
|
+
);
|
|
6135
|
+
}
|
|
6136
|
+
};
|
|
5783
6137
|
const scheduleRouteRegeneration = () => {
|
|
5784
6138
|
clearTimeout(routeChangeTimer);
|
|
5785
6139
|
routeChangeTimer = setTimeout(() => {
|
|
@@ -5799,9 +6153,7 @@ ${err.stack}`
|
|
|
5799
6153
|
}
|
|
5800
6154
|
}
|
|
5801
6155
|
} catch (err) {
|
|
5802
|
-
console.error(
|
|
5803
|
-
`[rsc-router] Route regeneration error: ${err.message}`
|
|
5804
|
-
);
|
|
6156
|
+
console.error(`[rango] Route regeneration error: ${err.message}`);
|
|
5805
6157
|
}
|
|
5806
6158
|
debugDiscovery?.(
|
|
5807
6159
|
"watcher: regenerated gen files (%sms)",
|
|
@@ -5810,7 +6162,7 @@ ${err.stack}`
|
|
|
5810
6162
|
if (s.perRouterManifests.length > 0) {
|
|
5811
6163
|
refreshRuntimeDiscovery().catch((err) => {
|
|
5812
6164
|
console.warn(
|
|
5813
|
-
`[
|
|
6165
|
+
`[rango] Runtime re-discovery error: ${err.message}`
|
|
5814
6166
|
);
|
|
5815
6167
|
resolveDiscoveryGate();
|
|
5816
6168
|
});
|
|
@@ -5819,23 +6171,56 @@ ${err.stack}`
|
|
|
5819
6171
|
};
|
|
5820
6172
|
const handleRouteFileChange = (filePath) => {
|
|
5821
6173
|
if (maybeHandleGeneratedRouteFileMutation(filePath)) return;
|
|
5822
|
-
if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx") && !filePath.endsWith(".js") && !filePath.endsWith(".jsx"))
|
|
6174
|
+
if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx") && !filePath.endsWith(".js") && !filePath.endsWith(".jsx")) {
|
|
6175
|
+
if (s.lastDiscoveryError) {
|
|
6176
|
+
debugDiscovery?.(
|
|
6177
|
+
"watcher: skip non-source %s [LASTERR %s]",
|
|
6178
|
+
filePath,
|
|
6179
|
+
s.lastDiscoveryError.message
|
|
6180
|
+
);
|
|
6181
|
+
}
|
|
5823
6182
|
return;
|
|
5824
|
-
|
|
6183
|
+
}
|
|
6184
|
+
if (s.scanFilter && !s.scanFilter(filePath)) {
|
|
6185
|
+
if (s.lastDiscoveryError) {
|
|
6186
|
+
debugDiscovery?.(
|
|
6187
|
+
"watcher: skip scan-filter %s [LASTERR %s]",
|
|
6188
|
+
filePath,
|
|
6189
|
+
s.lastDiscoveryError.message
|
|
6190
|
+
);
|
|
6191
|
+
}
|
|
6192
|
+
return;
|
|
6193
|
+
}
|
|
6194
|
+
const inRecoveryMode = !!s.lastDiscoveryError;
|
|
5825
6195
|
try {
|
|
5826
6196
|
const source = readFileSync6(filePath, "utf-8");
|
|
5827
6197
|
const trimmed = source.trimStart();
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
if (
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
6198
|
+
const isUseClient = trimmed.startsWith('"use client"') || trimmed.startsWith("'use client'");
|
|
6199
|
+
if (!inRecoveryMode && isUseClient) return;
|
|
6200
|
+
let hasUrls = source.includes("urls(");
|
|
6201
|
+
let hasCreateRouter = /\bcreateRouter\s*[<(]/.test(source);
|
|
6202
|
+
if (hasUrls) hasUrls = firstCodeMatchIndex(source, /urls\(/g) >= 0;
|
|
6203
|
+
if (hasCreateRouter) {
|
|
6204
|
+
hasCreateRouter = firstCodeMatchIndex(source, /\bcreateRouter\s*[<(]/g) >= 0;
|
|
6205
|
+
}
|
|
6206
|
+
if (!inRecoveryMode && !hasUrls && !hasCreateRouter) return;
|
|
6207
|
+
if (inRecoveryMode) {
|
|
6208
|
+
debugDiscovery?.(
|
|
6209
|
+
"watcher: recovery rediscovery for %s (urls=%s, router=%s, useClient=%s) [LASTERR %s]",
|
|
6210
|
+
filePath,
|
|
6211
|
+
hasUrls,
|
|
6212
|
+
hasCreateRouter,
|
|
6213
|
+
isUseClient,
|
|
6214
|
+
s.lastDiscoveryError.message
|
|
6215
|
+
);
|
|
6216
|
+
} else {
|
|
6217
|
+
debugDiscovery?.(
|
|
6218
|
+
"watcher: %s matches (urls=%s, router=%s)",
|
|
6219
|
+
filePath,
|
|
6220
|
+
hasUrls,
|
|
6221
|
+
hasCreateRouter
|
|
6222
|
+
);
|
|
6223
|
+
}
|
|
5839
6224
|
if (hasCreateRouter) {
|
|
5840
6225
|
const nestedRouterConflict = findNestedRouterConflict([
|
|
5841
6226
|
...s.cachedRouterFiles ?? [],
|
|
@@ -5853,7 +6238,15 @@ ${err.stack}`
|
|
|
5853
6238
|
gate.noteRouteEvent();
|
|
5854
6239
|
}
|
|
5855
6240
|
scheduleRouteRegeneration();
|
|
5856
|
-
} catch {
|
|
6241
|
+
} catch (readErr) {
|
|
6242
|
+
if (s.lastDiscoveryError) {
|
|
6243
|
+
debugDiscovery?.(
|
|
6244
|
+
"watcher: read error %s: %s [LASTERR %s]",
|
|
6245
|
+
filePath,
|
|
6246
|
+
readErr?.message,
|
|
6247
|
+
s.lastDiscoveryError.message
|
|
6248
|
+
);
|
|
6249
|
+
}
|
|
5857
6250
|
}
|
|
5858
6251
|
};
|
|
5859
6252
|
server.watcher.on("add", handleRouteFileChange);
|
|
@@ -5899,7 +6292,7 @@ ${err.stack}`
|
|
|
5899
6292
|
const rscEnv = tempServer.environments?.rsc;
|
|
5900
6293
|
if (!rscEnv?.runner) {
|
|
5901
6294
|
console.warn(
|
|
5902
|
-
"[
|
|
6295
|
+
"[rango] RSC environment runner not available during build, skipping manifest generation"
|
|
5903
6296
|
);
|
|
5904
6297
|
return;
|
|
5905
6298
|
}
|
|
@@ -5931,8 +6324,9 @@ ${err.stack}`
|
|
|
5931
6324
|
${err.stack}` : null
|
|
5932
6325
|
].filter(Boolean).join("\n");
|
|
5933
6326
|
throw new Error(
|
|
5934
|
-
`[
|
|
5935
|
-
${details}
|
|
6327
|
+
`[rango] Build-time router discovery failed:
|
|
6328
|
+
${details}`,
|
|
6329
|
+
{ cause: err }
|
|
5936
6330
|
);
|
|
5937
6331
|
} finally {
|
|
5938
6332
|
delete globalThis.__rscRouterDiscoveryActive;
|
|
@@ -5960,7 +6354,7 @@ ${details}`
|
|
|
5960
6354
|
// `consumeSelfGenWrite` inside `maybeHandleGeneratedRouteFileMutation`),
|
|
5961
6355
|
// AND vite's own HMR pipeline (which invalidates the gen file's
|
|
5962
6356
|
// importers and triggers a second workerd full reload — visible to the
|
|
5963
|
-
// user as a duplicate "[
|
|
6357
|
+
// user as a duplicate "[Rango] HMR: version changed" on the client).
|
|
5964
6358
|
//
|
|
5965
6359
|
// `peekSelfGenWrite` is the authoritative filter: its map only contains
|
|
5966
6360
|
// paths that `markSelfGenWrite` has registered, so it natively works
|
|
@@ -6120,6 +6514,10 @@ async function rango(options) {
|
|
|
6120
6514
|
const resolvedOptions = options ?? { preset: "node" };
|
|
6121
6515
|
const preset = resolvedOptions.preset ?? "node";
|
|
6122
6516
|
const showBanner = resolvedOptions.banner ?? true;
|
|
6517
|
+
const clientChunksOption = resolvedOptions.clientChunks ?? true;
|
|
6518
|
+
const useBuiltInClientChunks = clientChunksOption === true;
|
|
6519
|
+
const clientChunkCtx = useBuiltInClientChunks ? { fallbackRefs: /* @__PURE__ */ new Set() } : void 0;
|
|
6520
|
+
const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
|
|
6123
6521
|
debugConfig?.("rango(%s) setup start", preset);
|
|
6124
6522
|
const plugins = [];
|
|
6125
6523
|
const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
|
|
@@ -6155,10 +6553,18 @@ async function rango(options) {
|
|
|
6155
6553
|
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
6156
6554
|
optimizeDeps: {
|
|
6157
6555
|
exclude: excludeDeps,
|
|
6158
|
-
|
|
6556
|
+
rolldownOptions: sharedRolldownOptions
|
|
6159
6557
|
},
|
|
6160
6558
|
resolve: {
|
|
6161
|
-
alias: rangoAliases
|
|
6559
|
+
alias: rangoAliases,
|
|
6560
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
6561
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
6562
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
6563
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
6564
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
6565
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
6566
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
6567
|
+
dedupe: ["react", "react-dom"]
|
|
6162
6568
|
},
|
|
6163
6569
|
build: {
|
|
6164
6570
|
rollupOptions: { onwarn }
|
|
@@ -6167,6 +6573,14 @@ async function rango(options) {
|
|
|
6167
6573
|
client: {
|
|
6168
6574
|
build: {
|
|
6169
6575
|
rollupOptions: {
|
|
6576
|
+
// FILE_NAME_CONFLICT (and any other client-build warning) is
|
|
6577
|
+
// emitted by the CLIENT environment build, which consults THIS
|
|
6578
|
+
// env's onwarn -- Vite 8's environment builds do NOT propagate
|
|
6579
|
+
// the top-level build.rollupOptions.onwarn into the client env.
|
|
6580
|
+
// Wire it here so the suppression runs where the conflicts
|
|
6581
|
+
// originate (the top-level handler is invoked 0x for these; the
|
|
6582
|
+
// client-env handler is invoked for all of them).
|
|
6583
|
+
onwarn,
|
|
6170
6584
|
output: {
|
|
6171
6585
|
manualChunks: getManualChunks
|
|
6172
6586
|
}
|
|
@@ -6177,7 +6591,7 @@ async function rango(options) {
|
|
|
6177
6591
|
optimizeDeps: {
|
|
6178
6592
|
include: [nested("rsc-html-stream/client")],
|
|
6179
6593
|
exclude: excludeDeps,
|
|
6180
|
-
|
|
6594
|
+
rolldownOptions: sharedRolldownOptions
|
|
6181
6595
|
}
|
|
6182
6596
|
},
|
|
6183
6597
|
ssr: {
|
|
@@ -6185,10 +6599,6 @@ async function rango(options) {
|
|
|
6185
6599
|
build: {
|
|
6186
6600
|
outDir: "./dist/rsc/ssr"
|
|
6187
6601
|
},
|
|
6188
|
-
resolve: {
|
|
6189
|
-
// Ensure single React instance in SSR child environment
|
|
6190
|
-
dedupe: ["react", "react-dom"]
|
|
6191
|
-
},
|
|
6192
6602
|
// Pre-bundle SSR entry and React for proper module linking with childEnvironments
|
|
6193
6603
|
// All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
6194
6604
|
optimizeDeps: {
|
|
@@ -6206,7 +6616,7 @@ async function rango(options) {
|
|
|
6206
6616
|
)
|
|
6207
6617
|
],
|
|
6208
6618
|
exclude: excludeDeps,
|
|
6209
|
-
|
|
6619
|
+
rolldownOptions: sharedRolldownOptions
|
|
6210
6620
|
}
|
|
6211
6621
|
},
|
|
6212
6622
|
rsc: {
|
|
@@ -6223,7 +6633,7 @@ async function rango(options) {
|
|
|
6223
6633
|
)
|
|
6224
6634
|
],
|
|
6225
6635
|
exclude: excludeDeps,
|
|
6226
|
-
|
|
6636
|
+
rolldownOptions: sharedRolldownOptions
|
|
6227
6637
|
}
|
|
6228
6638
|
}
|
|
6229
6639
|
}
|
|
@@ -6241,7 +6651,8 @@ async function rango(options) {
|
|
|
6241
6651
|
plugins.push(
|
|
6242
6652
|
rsc({
|
|
6243
6653
|
entries: finalEntries,
|
|
6244
|
-
serverHandler: false
|
|
6654
|
+
serverHandler: false,
|
|
6655
|
+
clientChunks
|
|
6245
6656
|
})
|
|
6246
6657
|
);
|
|
6247
6658
|
plugins.push(clientRefDedup());
|
|
@@ -6259,7 +6670,7 @@ async function rango(options) {
|
|
|
6259
6670
|
const list = candidates.map(
|
|
6260
6671
|
(f) => " - " + (f.startsWith(root) ? f.slice(root.length + 1) : f)
|
|
6261
6672
|
).join("\n");
|
|
6262
|
-
throw new Error(`[
|
|
6673
|
+
throw new Error(`[rango] Multiple routers found:
|
|
6263
6674
|
${list}`);
|
|
6264
6675
|
}
|
|
6265
6676
|
}
|
|
@@ -6278,18 +6689,34 @@ ${list}`);
|
|
|
6278
6689
|
return {
|
|
6279
6690
|
optimizeDeps: {
|
|
6280
6691
|
exclude: excludeDeps,
|
|
6281
|
-
|
|
6692
|
+
rolldownOptions: sharedRolldownOptions
|
|
6282
6693
|
},
|
|
6283
6694
|
build: {
|
|
6284
6695
|
rollupOptions: { onwarn }
|
|
6285
6696
|
},
|
|
6286
6697
|
resolve: {
|
|
6287
|
-
alias: rangoAliases
|
|
6698
|
+
alias: rangoAliases,
|
|
6699
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
6700
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
6701
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
6702
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
6703
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
6704
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
6705
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
6706
|
+
dedupe: ["react", "react-dom"]
|
|
6288
6707
|
},
|
|
6289
6708
|
environments: {
|
|
6290
6709
|
client: {
|
|
6291
6710
|
build: {
|
|
6292
6711
|
rollupOptions: {
|
|
6712
|
+
// FILE_NAME_CONFLICT (and any other client-build warning) is
|
|
6713
|
+
// emitted by the CLIENT environment build, which consults THIS
|
|
6714
|
+
// env's onwarn -- Vite 8's environment builds do NOT propagate
|
|
6715
|
+
// the top-level build.rollupOptions.onwarn into the client env.
|
|
6716
|
+
// Wire it here so the suppression runs where the conflicts
|
|
6717
|
+
// originate (the top-level handler is invoked 0x for these; the
|
|
6718
|
+
// client-env handler is invoked for all of them).
|
|
6719
|
+
onwarn,
|
|
6293
6720
|
output: {
|
|
6294
6721
|
manualChunks: getManualChunks
|
|
6295
6722
|
}
|
|
@@ -6304,7 +6731,7 @@ ${list}`);
|
|
|
6304
6731
|
nested("rsc-html-stream/client")
|
|
6305
6732
|
],
|
|
6306
6733
|
exclude: excludeDeps,
|
|
6307
|
-
|
|
6734
|
+
rolldownOptions: sharedRolldownOptions,
|
|
6308
6735
|
entries: [VIRTUAL_IDS.browser]
|
|
6309
6736
|
}
|
|
6310
6737
|
},
|
|
@@ -6323,7 +6750,7 @@ ${list}`);
|
|
|
6323
6750
|
)
|
|
6324
6751
|
],
|
|
6325
6752
|
exclude: excludeDeps,
|
|
6326
|
-
|
|
6753
|
+
rolldownOptions: sharedRolldownOptions
|
|
6327
6754
|
}
|
|
6328
6755
|
},
|
|
6329
6756
|
rsc: {
|
|
@@ -6337,7 +6764,7 @@ ${list}`);
|
|
|
6337
6764
|
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge"
|
|
6338
6765
|
)
|
|
6339
6766
|
],
|
|
6340
|
-
|
|
6767
|
+
rolldownOptions: sharedRolldownOptions
|
|
6341
6768
|
}
|
|
6342
6769
|
}
|
|
6343
6770
|
}
|
|
@@ -6354,7 +6781,7 @@ ${list}`);
|
|
|
6354
6781
|
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
6355
6782
|
hasWarnedDuplicate = true;
|
|
6356
6783
|
console.warn(
|
|
6357
|
-
"[
|
|
6784
|
+
"[rango] Duplicate @vitejs/plugin-rsc detected. Remove rsc() from your vite config \u2014 rango() includes it automatically."
|
|
6358
6785
|
);
|
|
6359
6786
|
}
|
|
6360
6787
|
}
|
|
@@ -6363,7 +6790,8 @@ ${list}`);
|
|
|
6363
6790
|
plugins.push(performanceTracksPlugin());
|
|
6364
6791
|
plugins.push(
|
|
6365
6792
|
rsc({
|
|
6366
|
-
entries: finalEntries
|
|
6793
|
+
entries: finalEntries,
|
|
6794
|
+
clientChunks
|
|
6367
6795
|
})
|
|
6368
6796
|
);
|
|
6369
6797
|
plugins.push(clientRefDedup());
|
|
@@ -6402,7 +6830,8 @@ ${list}`);
|
|
|
6402
6830
|
routerPathRef: discoveryRouterRef,
|
|
6403
6831
|
enableBuildPrerender: prerenderEnabled,
|
|
6404
6832
|
buildEnv: options?.buildEnv,
|
|
6405
|
-
preset
|
|
6833
|
+
preset,
|
|
6834
|
+
clientChunkCtx
|
|
6406
6835
|
})
|
|
6407
6836
|
);
|
|
6408
6837
|
debugConfig?.(
|