veryfront 0.0.92 → 0.0.93

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.
Files changed (37) hide show
  1. package/esm/deno.js +1 -1
  2. package/esm/src/build/production-build/static-generation.d.ts +2 -0
  3. package/esm/src/build/production-build/static-generation.d.ts.map +1 -1
  4. package/esm/src/build/production-build/static-generation.js +2 -1
  5. package/esm/src/html/utils.d.ts.map +1 -1
  6. package/esm/src/html/utils.js +8 -5
  7. package/esm/src/modules/react-loader/unified-loader.d.ts.map +1 -1
  8. package/esm/src/modules/react-loader/unified-loader.js +4 -2
  9. package/esm/src/modules/server/ssr-import-rewriter.d.ts.map +1 -1
  10. package/esm/src/modules/server/ssr-import-rewriter.js +11 -4
  11. package/esm/src/react/compat/config-generator.d.ts.map +1 -1
  12. package/esm/src/react/compat/config-generator.js +8 -26
  13. package/esm/src/server/build-app-route-renderer.d.ts +1 -0
  14. package/esm/src/server/build-app-route-renderer.d.ts.map +1 -1
  15. package/esm/src/server/build-app-route-renderer.js +3 -10
  16. package/esm/src/transforms/esm/import-rewriter.d.ts +1 -1
  17. package/esm/src/transforms/esm/import-rewriter.d.ts.map +1 -1
  18. package/esm/src/transforms/esm/import-rewriter.js +5 -10
  19. package/esm/src/transforms/esm/package-registry.d.ts +8 -0
  20. package/esm/src/transforms/esm/package-registry.d.ts.map +1 -1
  21. package/esm/src/transforms/esm/package-registry.js +7 -3
  22. package/esm/src/transforms/pipeline/stages/resolve-bare.js +1 -1
  23. package/esm/src/utils/constants/cdn.d.ts +10 -7
  24. package/esm/src/utils/constants/cdn.d.ts.map +1 -1
  25. package/esm/src/utils/constants/cdn.js +14 -45
  26. package/package.json +1 -1
  27. package/src/deno.js +1 -1
  28. package/src/src/build/production-build/static-generation.ts +4 -0
  29. package/src/src/html/utils.ts +8 -5
  30. package/src/src/modules/react-loader/unified-loader.ts +7 -2
  31. package/src/src/modules/server/ssr-import-rewriter.ts +12 -3
  32. package/src/src/react/compat/config-generator.ts +12 -26
  33. package/src/src/server/build-app-route-renderer.ts +4 -10
  34. package/src/src/transforms/esm/import-rewriter.ts +10 -14
  35. package/src/src/transforms/esm/package-registry.ts +7 -3
  36. package/src/src/transforms/pipeline/stages/resolve-bare.ts +1 -1
  37. package/src/src/utils/constants/cdn.ts +20 -44
package/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.0.92",
3
+ "version": "0.0.93",
4
4
  "nodeModulesDir": "auto",
5
5
  "exclude": [
6
6
  "npm/",
@@ -40,6 +40,8 @@ export interface SSGOptions {
40
40
  baseUrl?: string;
41
41
  dryRun?: boolean;
42
42
  traceStep?: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
43
+ /** React version for import map generation */
44
+ reactVersion?: string;
43
45
  }
44
46
  export declare function buildPagesRoutes(routes: RouteInfo[], options: SSGOptions): Promise<SSGStats>;
45
47
  export declare function buildAppRoutes(appRoutes: AppRouteInfo[], options: SSGOptions): Promise<SSGStats>;
@@ -1 +1 @@
1
- {"version":3,"file":"static-generation.d.ts","sourceRoot":"","sources":["../../../../src/src/build/production-build/static-generation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAI3E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACnE;AAoBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CA+FnB;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,YAAY,EAAE,EACzB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CA0CnB"}
1
+ {"version":3,"file":"static-generation.d.ts","sourceRoot":"","sources":["../../../../src/src/build/production-build/static-generation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAI3E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAoBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CA+FnB;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,YAAY,EAAE,EACzB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CA4CnB"}
@@ -80,7 +80,7 @@ ${clientStyles}
80
80
  return stats;
81
81
  }
82
82
  export async function buildAppRoutes(appRoutes, options) {
83
- const { adapter, projectDir, outputDir, contentSourceId = "build-static", dryRun = false, traceStep = defaultTraceStep, } = options;
83
+ const { adapter, projectDir, outputDir, contentSourceId = "build-static", dryRun = false, traceStep = defaultTraceStep, reactVersion, } = options;
84
84
  const stats = { pages: 0, totalSize: 0, ssgPaths: [] };
85
85
  if (appRoutes.length === 0)
86
86
  return stats;
@@ -93,6 +93,7 @@ export async function buildAppRoutes(appRoutes, options) {
93
93
  routePath: route.path,
94
94
  pageFile: route.pageFile,
95
95
  contentSourceId,
96
+ reactVersion,
96
97
  }));
97
98
  const outputPath = getAppRouteOutputPath(outputDir, route.path);
98
99
  if (!dryRun) {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/html/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAO1D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAOzF;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAOR;AAED,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmBlF;AAqKD,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvD,OAAO,CAAC,MAAM,CAAC,CAuCjB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGjF;AAED,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAElF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/src/html/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQ1D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAOzF;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAOR;AAED,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmBlF;AAuKD,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,wBAAsB,kBAAkB,CACtC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvD,OAAO,CAAC,MAAM,CAAC,CAuCjB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAGjF;AAED,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAElF"}
@@ -1,5 +1,6 @@
1
1
  import { escapeHTML } from "./html-escape.js";
2
2
  import { REACT_DEFAULT_VERSION, VERYFRONT_VERSION } from "../utils/constants/cdn.js";
3
+ import { esmShReact } from "../transforms/esm/package-registry.js";
3
4
  function joinAttributes(attrs) {
4
5
  return attrs.filter(Boolean).join(" ");
5
6
  }
@@ -61,11 +62,13 @@ const PLATFORM_UTILITIES = {
61
62
  };
62
63
  const CDN_URL_TEMPLATES = {
63
64
  "esm.sh": {
64
- react: (v) => `https://esm.sh/react@${v}?target=es2022`,
65
- reactDom: (v) => `https://esm.sh/react-dom@${v}?external=react&target=es2022`,
66
- reactDomClient: (v) => `https://esm.sh/react-dom@${v}/client?external=react&target=es2022`,
67
- jsxRuntime: (v) => `https://esm.sh/react@${v}/jsx-runtime?target=es2022`,
68
- jsxDevRuntime: (v) => `https://esm.sh/react@${v}/jsx-dev-runtime?target=es2022`,
65
+ // Use centralized esmShReact() helper from package-registry.ts to ensure URL consistency
66
+ // Any URL mismatch causes esm.sh to serve different modules -> multiple React instances -> hooks fail
67
+ react: (v) => esmShReact("react", v),
68
+ reactDom: (v) => esmShReact("react-dom", v, "", true),
69
+ reactDomClient: (v) => esmShReact("react-dom", v, "/client", true),
70
+ jsxRuntime: (v) => esmShReact("react", v, "/jsx-runtime", true),
71
+ jsxDevRuntime: (v) => esmShReact("react", v, "/jsx-dev-runtime", true),
69
72
  veryfrontAgentReact: (v) => `https://esm.sh/veryfront@${v}/agent/react?external=react,react-dom&target=es2022`,
70
73
  veryfrontComponentsAi: (v) => `https://esm.sh/veryfront@${v}/components/ai?external=react,react-dom&target=es2022`,
71
74
  veryfrontPrimitives: (v) => `https://esm.sh/veryfront@${v}/primitives?external=react,react-dom&target=es2022`,
@@ -1 +1 @@
1
- {"version":3,"file":"unified-loader.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/react-loader/unified-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAMtE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKtF,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAmCvB"}
1
+ {"version":3,"file":"unified-loader.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/react-loader/unified-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAMtE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAQtF,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,YAAY,CAAC,CAmCvB"}
@@ -3,7 +3,7 @@ import { transformToESM } from "../../transforms/esm/index.js";
3
3
  import { rendererLogger as logger } from "../../utils/index.js";
4
4
  import { withSpan } from "../../observability/tracing/otlp-setup.js";
5
5
  import { getProjectTmpDir } from "./temp-directory.js";
6
- import { DEFAULT_REACT_VERSION } from "../../transforms/esm/package-registry.js";
6
+ import { DEFAULT_REACT_VERSION, getReactImportMap, } from "../../transforms/esm/package-registry.js";
7
7
  export function loadComponentsUnified(components, projectDir, adapter, options) {
8
8
  return withSpan("modules.loadComponentsUnified", async () => {
9
9
  const projectId = options?.projectId ?? projectDir;
@@ -38,12 +38,14 @@ async function writeComponentFiles(tmpDir, components, adapter) {
38
38
  }
39
39
  function generateEntryPoint(components, reactVersion) {
40
40
  const version = reactVersion ?? DEFAULT_REACT_VERSION;
41
+ // Use centralized React URL from package-registry to ensure consistency
42
+ const reactUrl = getReactImportMap(version).react;
41
43
  const imports = components
42
44
  .map((comp) => `import { default as ${comp.name} } from './${comp.name}.js'`)
43
45
  .join("\n");
44
46
  const exports = components.map((comp) => comp.name).join(", ");
45
47
  return `
46
- import * as React from 'https://esm.sh/react@${version}?target=es2022'
48
+ import * as React from '${reactUrl}'
47
49
  ${imports}
48
50
 
49
51
  export { ${exports} }
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-import-rewriter.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/ssr-import-rewriter.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAsFD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAK5F"}
1
+ {"version":3,"file":"ssr-import-rewriter.d.ts","sourceRoot":"","sources":["../../../../src/src/modules/server/ssr-import-rewriter.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8FD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAK5F"}
@@ -1,7 +1,12 @@
1
1
  import { getReactImportMap, getReactVersion } from "../../transforms/esm/package-registry.js";
2
+ import { isDeno } from "../../platform/compat/runtime.js";
2
3
  function shouldKeepBareSpecifier(specifier) {
3
- if (specifier.startsWith("npm:") ||
4
- specifier.startsWith("http://") ||
4
+ // npm: specifiers are only supported in Deno, not Node.js
5
+ // In Node.js, we need to convert them to esm.sh URLs (handled in rewriteBareImports)
6
+ if (specifier.startsWith("npm:")) {
7
+ return isDeno;
8
+ }
9
+ if (specifier.startsWith("http://") ||
5
10
  specifier.startsWith("https://") ||
6
11
  specifier.startsWith("file://") ||
7
12
  specifier.startsWith("node:")) {
@@ -37,13 +42,15 @@ function resolveReactForRuntime(specifier, version) {
37
42
  function rewriteBareImports(code, version) {
38
43
  const v = version ?? getReactVersion();
39
44
  return code.replace(/from\s+["']([^"'./][^"']*)["']/g, (_match, specifier) => {
40
- const reactUrl = resolveReactForRuntime(specifier, v);
45
+ // Strip npm: prefix for resolution (npm: is Deno-specific)
46
+ const bareSpecifier = specifier.startsWith("npm:") ? specifier.slice(4) : specifier;
47
+ const reactUrl = resolveReactForRuntime(bareSpecifier, v);
41
48
  if (reactUrl)
42
49
  return `from "${reactUrl}"`;
43
50
  if (shouldKeepBareSpecifier(specifier))
44
51
  return `from "${specifier}"`;
45
52
  // For third-party packages: Use esm.sh with external=react
46
- return `from "https://esm.sh/${specifier}?external=react&target=es2022"`;
53
+ return `from "https://esm.sh/${bareSpecifier}?external=react&target=es2022"`;
47
54
  });
48
55
  }
49
56
  function rewritePathAliases(code, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"config-generator.d.ts","sourceRoot":"","sources":["../../../../src/src/react/compat/config-generator.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,iBAAiB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClD,oBAAoB,IAAI,YAAY,EAAE,CAAC;CACxC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAoClE,CAAC;AAcF,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,YAAY,EAC3B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAO,GACvE,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE7E;AAED,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAsB9B;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAsBnF"}
1
+ {"version":3,"file":"config-generator.d.ts","sourceRoot":"","sources":["../../../../src/src/react/compat/config-generator.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,iBAAiB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClD,oBAAoB,IAAI,YAAY,EAAE,CAAC;CACxC;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,YAAY,EAAE,kBAAkB,CAgBlE,CAAC;AAcF,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,YAAY,EAC3B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAO,GACvE,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE7E;AAED,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAsB9B;AAED,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAsBnF"}
@@ -2,41 +2,23 @@ import { rendererLogger as logger } from "../../utils/index.js";
2
2
  import { join } from "../../platform/compat/path/index.js";
3
3
  import { createError, toError } from "../../errors/veryfront-error.js";
4
4
  import { createFileSystem } from "../../platform/compat/fs.js";
5
+ import { getReactUrls } from "../../transforms/esm/package-registry.js";
6
+ import { REACT_VERSION_17, REACT_VERSION_18_2, REACT_VERSION_19_RC, } from "../../utils/constants/cdn.js";
5
7
  export const REACT_CONFIGS = {
6
8
  "17": {
7
9
  version: "17",
8
- exact: "17.0.2",
9
- imports: {
10
- react: "https://esm.sh/react@17.0.2",
11
- "react-dom": "https://esm.sh/react-dom@17.0.2",
12
- "react-dom/server": "https://esm.sh/react-dom@17.0.2/server",
13
- "react/jsx-runtime": "https://esm.sh/react@17.0.2/jsx-runtime",
14
- "react/jsx-dev-runtime": "https://esm.sh/react@17.0.2/jsx-dev-runtime",
15
- },
10
+ exact: REACT_VERSION_17,
11
+ imports: getReactUrls(REACT_VERSION_17),
16
12
  },
17
13
  "18": {
18
14
  version: "18",
19
- exact: "18.2.0",
20
- imports: {
21
- react: "https://esm.sh/react@18.2.0",
22
- "react-dom": "https://esm.sh/react-dom@18.2.0",
23
- "react-dom/server": "https://esm.sh/react-dom@18.2.0/server",
24
- "react-dom/client": "https://esm.sh/react-dom@18.2.0/client",
25
- "react/jsx-runtime": "https://esm.sh/react@18.2.0/jsx-runtime",
26
- "react/jsx-dev-runtime": "https://esm.sh/react@18.2.0/jsx-dev-runtime",
27
- },
15
+ exact: REACT_VERSION_18_2,
16
+ imports: getReactUrls(REACT_VERSION_18_2),
28
17
  },
29
18
  "19": {
30
19
  version: "19",
31
- exact: "19.0.0-rc.0",
32
- imports: {
33
- react: "https://esm.sh/react@19.0.0-rc.0",
34
- "react-dom": "https://esm.sh/react-dom@19.0.0-rc.0",
35
- "react-dom/server": "https://esm.sh/react-dom@19.0.0-rc.0/server",
36
- "react-dom/client": "https://esm.sh/react-dom@19.0.0-rc.0/client",
37
- "react/jsx-runtime": "https://esm.sh/react@19.0.0-rc.0/jsx-runtime",
38
- "react/jsx-dev-runtime": "https://esm.sh/react@19.0.0-rc.0/jsx-dev-runtime",
39
- },
20
+ exact: REACT_VERSION_19_RC,
21
+ imports: getReactUrls(REACT_VERSION_19_RC),
40
22
  },
41
23
  };
42
24
  function getReactConfig(version) {
@@ -11,5 +11,6 @@ export declare function renderAppRouteToHTML(args: {
11
11
  routePath: string;
12
12
  pageFile: string;
13
13
  contentSourceId: string;
14
+ reactVersion?: string;
14
15
  }): Promise<string>;
15
16
  //# sourceMappingURL=build-app-route-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-app-route-renderer.d.ts","sourceRoot":"","sources":["../../../src/src/server/build-app-route-renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA+BnE;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyMlB"}
1
+ {"version":3,"file":"build-app-route-renderer.d.ts","sourceRoot":"","sources":["../../../src/src/server/build-app-route-renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAgCnE;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiMlB"}
@@ -6,6 +6,7 @@ import { join } from "../platform/compat/path/index.js";
6
6
  import { getProjectReact, renderToStringAdapter } from "../react/index.js";
7
7
  import { loadComponentFromSource } from "../modules/react-loader/index.js";
8
8
  import { CompilationError } from "../errors/index.js";
9
+ import { DEFAULT_REACT_VERSION, getReactUrls } from "../transforms/esm/package-registry.js";
9
10
  async function fileExists(adapter, filePath) {
10
11
  try {
11
12
  const st = await adapter.fs.stat(filePath);
@@ -28,7 +29,7 @@ async function loadComponent(adapter, filePath, projectDir, contentSourceId) {
28
29
  * Render an App Router route to HTML
29
30
  */
30
31
  export async function renderAppRouteToHTML(args) {
31
- const { adapter, projectDir, routePath, pageFile, contentSourceId } = args;
32
+ const { adapter, projectDir, routePath, pageFile, contentSourceId, reactVersion } = args;
32
33
  const appRoot = join(projectDir, "app");
33
34
  const layouts = [];
34
35
  const rootLayout = join(appRoot, "layout.tsx");
@@ -74,15 +75,7 @@ export async function renderAppRouteToHTML(args) {
74
75
 
75
76
  <!-- Import map for React dependencies -->
76
77
  <script type="importmap">
77
- {
78
- "imports": {
79
- "react": "https://esm.sh/react@18.3.1",
80
- "react-dom": "https://esm.sh/react-dom@18.3.1",
81
- "react-dom/client": "https://esm.sh/react-dom@18.3.1/client",
82
- "react/jsx-runtime": "https://esm.sh/react@18.3.1/jsx-runtime",
83
- "react/jsx-dev-runtime": "https://esm.sh/react@18.3.1/jsx-dev-runtime"
84
- }
85
- }
78
+ ${JSON.stringify({ imports: getReactUrls(reactVersion ?? DEFAULT_REACT_VERSION) }, null, 4)}
86
79
  </script>
87
80
 
88
81
  <!-- Basic styles -->
@@ -1,4 +1,4 @@
1
1
  export declare function addHMRTimestamps(code: string, timestamp: string | number): Promise<string>;
2
- export declare function rewriteBareImports(code: string, _moduleServerUrl?: string): Promise<string>;
2
+ export declare function rewriteBareImports(code: string, _moduleServerUrl?: string, reactVersion?: string): Promise<string>;
3
3
  export declare function rewriteVendorImports(code: string, moduleServerUrl: string, vendorBundleHash: string): Promise<string>;
4
4
  //# sourceMappingURL=import-rewriter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/import-rewriter.ts"],"names":[],"mappings":"AAKA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB1F;AAoDD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuB3F;AAWD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,CAgEjB"}
1
+ {"version":3,"file":"import-rewriter.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/import-rewriter.ts"],"names":[],"mappings":"AAMA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmB1F;AAwCD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,gBAAgB,CAAC,EAAE,MAAM,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAWD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,CAgEjB"}
@@ -2,6 +2,7 @@ import { parseImports, replaceSpecifiers, rewriteImports } from "./lexer.js";
2
2
  import { REACT_DEFAULT_VERSION, TAILWIND_VERSION } from "../../utils/constants/cdn.js";
3
3
  import { rendererLogger as logger } from "../../utils/index.js";
4
4
  import { withSpan } from "../../observability/tracing/otlp-setup.js";
5
+ import { getReactImportMap } from "./package-registry.js";
5
6
  export function addHMRTimestamps(code, timestamp) {
6
7
  return withSpan("transforms.esm.addHMRTimestamps", () => replaceSpecifiers(code, (specifier) => {
7
8
  const isLocalImport = specifier.startsWith("./") ||
@@ -38,14 +39,6 @@ function warnUnversionedImport(specifier) {
38
39
  function normalizeVersionedSpecifier(specifier) {
39
40
  return specifier.replace(/@[\d^~x][\d.x^~-]*(?=\/|$)/, "");
40
41
  }
41
- const REACT_IMPORT_MAP = {
42
- react: `https://esm.sh/react@${REACT_DEFAULT_VERSION}?target=es2022`,
43
- "react-dom": `https://esm.sh/react-dom@${REACT_DEFAULT_VERSION}?external=react&target=es2022`,
44
- "react-dom/client": `https://esm.sh/react-dom@${REACT_DEFAULT_VERSION}/client?external=react&target=es2022`,
45
- "react-dom/server": `https://esm.sh/react-dom@${REACT_DEFAULT_VERSION}/server?external=react&target=es2022`,
46
- "react/jsx-runtime": `https://esm.sh/react@${REACT_DEFAULT_VERSION}/jsx-runtime?target=es2022`,
47
- "react/jsx-dev-runtime": `https://esm.sh/react@${REACT_DEFAULT_VERSION}/jsx-dev-runtime?target=es2022`,
48
- };
49
42
  function shouldSkipRewrite(specifier) {
50
43
  return (specifier.startsWith("http://") ||
51
44
  specifier.startsWith("https://") ||
@@ -56,9 +49,11 @@ function shouldSkipRewrite(specifier) {
56
49
  specifier.startsWith("#") ||
57
50
  specifier.startsWith("veryfront"));
58
51
  }
59
- export function rewriteBareImports(code, _moduleServerUrl) {
52
+ export function rewriteBareImports(code, _moduleServerUrl, reactVersion) {
53
+ // Get React import map for the specified version (uses centralized URL builder)
54
+ const reactImportMap = getReactImportMap(reactVersion ?? REACT_DEFAULT_VERSION);
60
55
  return withSpan("transforms.esm.rewriteBareImports", () => replaceSpecifiers(code, (specifier) => {
61
- const mapped = REACT_IMPORT_MAP[specifier];
56
+ const mapped = reactImportMap[specifier];
62
57
  if (mapped)
63
58
  return mapped;
64
59
  if (shouldSkipRewrite(specifier))
@@ -44,6 +44,14 @@ export declare const REACT_VERSION = "19.1.1";
44
44
  * v12: Store HTTP bundle code by hash for direct recovery (code:{hash})
45
45
  */
46
46
  export declare const TRANSFORM_CACHE_VERSION = 12;
47
+ /** csstype version - must match deno.json for type consistency */
48
+ export declare const CSSTYPE_VERSION = "3.2.3";
49
+ /**
50
+ * Build esm.sh URL with deps=csstype for React packages (ensures type consistency).
51
+ * CRITICAL: This is the single source of truth for React URLs. All other files
52
+ * (html/utils.ts, import-rewriter.ts, etc.) must use this or getReactImportMap().
53
+ */
54
+ export declare function esmShReact(pkg: string, version: string, path?: string, external?: boolean): string;
47
55
  /**
48
56
  * Generate esm.sh URL for browser.
49
57
  * Uses ?external= so browser import map provides React (ensures single instance).
@@ -1 +1 @@
1
- {"version":3,"file":"package-registry.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/package-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAOzE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,iEAAiE;AACjE,eAAO,MAAM,aAAa,WAAwB,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAa1C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAI9F;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO1E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU3E"}
1
+ {"version":3,"file":"package-registry.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/esm/package-registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAOzE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,iEAAiE;AACjE,eAAO,MAAM,aAAa,WAAwB,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,kEAAkE;AAClE,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,SAAK,EAAE,QAAQ,UAAQ,GAAG,MAAM,CAK5F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAI9F;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO1E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU3E"}
@@ -56,9 +56,13 @@ export const REACT_VERSION = DEFAULT_REACT_VERSION;
56
56
  */
57
57
  export const TRANSFORM_CACHE_VERSION = 12;
58
58
  /** csstype version - must match deno.json for type consistency */
59
- const CSSTYPE_VERSION = "3.2.3";
60
- /** Build esm.sh URL with deps=csstype for React packages (ensures type consistency) */
61
- function esmShReact(pkg, version, path = "", external = false) {
59
+ export const CSSTYPE_VERSION = "3.2.3";
60
+ /**
61
+ * Build esm.sh URL with deps=csstype for React packages (ensures type consistency).
62
+ * CRITICAL: This is the single source of truth for React URLs. All other files
63
+ * (html/utils.ts, import-rewriter.ts, etc.) must use this or getReactImportMap().
64
+ */
65
+ export function esmShReact(pkg, version, path = "", external = false) {
62
66
  const params = external
63
67
  ? [`external=react`, `target=es2022`, `deps=csstype@${CSSTYPE_VERSION}`]
64
68
  : [`target=es2022`, `deps=csstype@${CSSTYPE_VERSION}`];
@@ -18,7 +18,7 @@ export const resolveBarePlugin = {
18
18
  if (ctx.moduleServerUrl && ctx.vendorBundleHash) {
19
19
  return rewriteVendorImports(ctx.code, ctx.moduleServerUrl, ctx.vendorBundleHash);
20
20
  }
21
- return rewriteBareImports(ctx.code, ctx.moduleServerUrl);
21
+ return rewriteBareImports(ctx.code, ctx.moduleServerUrl, ctx.reactVersion);
22
22
  },
23
23
  };
24
24
  export default resolveBarePlugin;
@@ -7,13 +7,16 @@ export declare const REACT_VERSION_18_3 = "18.3.1";
7
7
  export declare const REACT_VERSION_19_RC = "19.0.0-rc.0";
8
8
  export declare const REACT_VERSION_19 = "19.1.1";
9
9
  export declare const REACT_DEFAULT_VERSION = "19.1.1";
10
- export declare function getReactCDNUrl(version?: string): string;
11
- export declare function getReactDOMCDNUrl(version?: string): string;
12
- export declare function getReactDOMClientCDNUrl(version?: string): string;
13
- export declare function getReactDOMServerCDNUrl(version?: string): string;
14
- export declare function getReactJSXRuntimeCDNUrl(version?: string): string;
15
- export declare function getReactJSXDevRuntimeCDNUrl(version?: string): string;
16
- export declare function getReactImportMap(version?: string): Record<string, string>;
10
+ import * as ReactRegistry from "../../transforms/esm/package-registry.js";
11
+ export declare const esmShReact: typeof ReactRegistry.esmShReact;
12
+ export declare const getReactImportMap: typeof ReactRegistry.getReactImportMap;
13
+ export declare const getReactUrls: typeof ReactRegistry.getReactUrls;
14
+ export declare const getReactCDNUrl: (version?: string) => string;
15
+ export declare const getReactDOMCDNUrl: (version?: string) => string;
16
+ export declare const getReactDOMClientCDNUrl: (version?: string) => string;
17
+ export declare const getReactDOMServerCDNUrl: (version?: string) => string;
18
+ export declare const getReactJSXRuntimeCDNUrl: (version?: string) => string;
19
+ export declare const getReactJSXDevRuntimeCDNUrl: (version?: string) => string;
17
20
  export declare const DEFAULT_ALLOWED_CDN_HOSTS: string[];
18
21
  export declare const DENO_STD_VERSION = "0.220.0";
19
22
  export declare function getDenoStdNodeBase(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/constants/cdn.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAC5D,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAEjD,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAC3C,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAC3C,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AACjD,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,eAAO,MAAM,qBAAqB,WAAmB,CAAC;AAmBtD,wBAAgB,cAAc,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAE9E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAEjF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAEvF;AAED,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAEvF;AAED,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAExF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAE3F;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,MAA8B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASjG;AAED,eAAO,MAAM,yBAAyB,UAAgC,CAAC;AAEvE,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/constants/cdn.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAC5D,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAEjD,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAC3C,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAC3C,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AACjD,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,eAAO,MAAM,qBAAqB,WAAmB,CAAC;AAKtD,OAAO,KAAK,aAAa,MAAM,0CAA0C,CAAC;AAE1E,eAAO,MAAM,UAAU,iCAA2B,CAAC;AACnD,eAAO,MAAM,iBAAiB,wCAAkC,CAAC;AACjE,eAAO,MAAM,YAAY,mCAA6B,CAAC;AAGvD,eAAO,MAAM,cAAc,GAAI,gBAA+B,WAClB,CAAC;AAE7C,eAAO,MAAM,iBAAiB,GAAI,gBAA+B,WACd,CAAC;AAEpD,eAAO,MAAM,uBAAuB,GAAI,gBAA+B,WACb,CAAC;AAE3D,eAAO,MAAM,uBAAuB,GAAI,gBAA+B,WACb,CAAC;AAE3D,eAAO,MAAM,wBAAwB,GAAI,gBAA+B,WACb,CAAC;AAE5D,eAAO,MAAM,2BAA2B,GAAI,gBAA+B,WACZ,CAAC;AAEhE,eAAO,MAAM,yBAAyB,UAAgC,CAAC;AAEvE,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
@@ -7,51 +7,20 @@ export const REACT_VERSION_18_3 = "18.3.1";
7
7
  export const REACT_VERSION_19_RC = "19.0.0-rc.0";
8
8
  export const REACT_VERSION_19 = "19.1.1";
9
9
  export const REACT_DEFAULT_VERSION = REACT_VERSION_19;
10
- /**
11
- * esm.sh URL builder with consistent query params.
12
- *
13
- * For React packages (react-dom, jsx-runtime), we only need external=react:
14
- * - react-dom depends on react → external=react makes it import "react" as bare specifier
15
- * - react-dom doesn't need external=react-dom because it IS react-dom
16
- * - jsx-runtime depends on react core → external=react
17
- *
18
- * Third-party packages (e.g., @tanstack/react-query) need external=react,react-dom
19
- * because they may depend on BOTH. That's handled by bundleHttpImports() separately.
20
- */
21
- function esmSh(pkg, version, path = "", external = false) {
22
- const params = ["target=es2022"];
23
- if (external)
24
- params.push("external=react");
25
- return `${ESM_CDN_BASE}/${pkg}@${version}${path}?${params.join("&")}`;
26
- }
27
- export function getReactCDNUrl(version = REACT_DEFAULT_VERSION) {
28
- return esmSh("react", version);
29
- }
30
- export function getReactDOMCDNUrl(version = REACT_DEFAULT_VERSION) {
31
- return esmSh("react-dom", version, "", true);
32
- }
33
- export function getReactDOMClientCDNUrl(version = REACT_DEFAULT_VERSION) {
34
- return esmSh("react-dom", version, "/client", true);
35
- }
36
- export function getReactDOMServerCDNUrl(version = REACT_DEFAULT_VERSION) {
37
- return esmSh("react-dom", version, "/server", true);
38
- }
39
- export function getReactJSXRuntimeCDNUrl(version = REACT_DEFAULT_VERSION) {
40
- return esmSh("react", version, "/jsx-runtime", true);
41
- }
42
- export function getReactJSXDevRuntimeCDNUrl(version = REACT_DEFAULT_VERSION) {
43
- return esmSh("react", version, "/jsx-dev-runtime", true);
44
- }
45
- export function getReactImportMap(version = REACT_DEFAULT_VERSION) {
46
- return {
47
- react: getReactCDNUrl(version),
48
- "react-dom": getReactDOMCDNUrl(version),
49
- "react-dom/client": getReactDOMClientCDNUrl(version),
50
- "react-dom/server": getReactDOMServerCDNUrl(version),
51
- "react/jsx-runtime": getReactJSXRuntimeCDNUrl(version),
52
- "react/jsx-dev-runtime": getReactJSXDevRuntimeCDNUrl(version),
53
- };
54
- }
10
+ // Re-export from package-registry.ts - the SINGLE SOURCE OF TRUTH for React URLs.
11
+ // This ensures all React URLs include deps=csstype and match exactly.
12
+ // DO NOT add duplicate URL builders here - use package-registry.ts instead.
13
+ import * as ReactRegistry from "../../transforms/esm/package-registry.js";
14
+ export const esmShReact = ReactRegistry.esmShReact;
15
+ export const getReactImportMap = ReactRegistry.getReactImportMap;
16
+ export const getReactUrls = ReactRegistry.getReactUrls;
17
+ // Named getters for convenience - delegate to ReactRegistry
18
+ export const getReactCDNUrl = (version = REACT_DEFAULT_VERSION) => ReactRegistry.getReactUrls(version).react;
19
+ export const getReactDOMCDNUrl = (version = REACT_DEFAULT_VERSION) => ReactRegistry.getReactUrls(version)["react-dom"];
20
+ export const getReactDOMClientCDNUrl = (version = REACT_DEFAULT_VERSION) => ReactRegistry.getReactUrls(version)["react-dom/client"];
21
+ export const getReactDOMServerCDNUrl = (version = REACT_DEFAULT_VERSION) => ReactRegistry.getReactUrls(version)["react-dom/server"];
22
+ export const getReactJSXRuntimeCDNUrl = (version = REACT_DEFAULT_VERSION) => ReactRegistry.getReactUrls(version)["react/jsx-runtime"];
23
+ export const getReactJSXDevRuntimeCDNUrl = (version = REACT_DEFAULT_VERSION) => ReactRegistry.getReactUrls(version)["react/jsx-dev-runtime"];
55
24
  export const DEFAULT_ALLOWED_CDN_HOSTS = [ESM_CDN_BASE, DENO_STD_BASE];
56
25
  export const DENO_STD_VERSION = "0.220.0";
57
26
  export function getDenoStdNodeBase() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.0.92",
3
+ "version": "0.0.93",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.0.92",
3
+ "version": "0.0.93",
4
4
  "nodeModulesDir": "auto",
5
5
  "exclude": [
6
6
  "npm/",
@@ -45,6 +45,8 @@ export interface SSGOptions {
45
45
  baseUrl?: string;
46
46
  dryRun?: boolean;
47
47
  traceStep?: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
48
+ /** React version for import map generation */
49
+ reactVersion?: string;
48
50
  }
49
51
 
50
52
  function getOutputPath(outputDir: string, slug: string): string {
@@ -176,6 +178,7 @@ export async function buildAppRoutes(
176
178
  contentSourceId = "build-static",
177
179
  dryRun = false,
178
180
  traceStep = defaultTraceStep,
181
+ reactVersion,
179
182
  } = options;
180
183
 
181
184
  const stats: SSGStats = { pages: 0, totalSize: 0, ssgPaths: [] };
@@ -192,6 +195,7 @@ export async function buildAppRoutes(
192
195
  routePath: route.path,
193
196
  pageFile: route.pageFile,
194
197
  contentSourceId,
198
+ reactVersion,
195
199
  }));
196
200
 
197
201
  const outputPath = getAppRouteOutputPath(outputDir, route.path);
@@ -1,6 +1,7 @@
1
1
  import { escapeHTML } from "./html-escape.js";
2
2
  import type { VeryfrontConfig } from "../config/types.js";
3
3
  import { REACT_DEFAULT_VERSION, VERYFRONT_VERSION } from "../utils/constants/cdn.js";
4
+ import { esmShReact } from "../transforms/esm/package-registry.js";
4
5
 
5
6
  function joinAttributes(attrs: Array<string | false | undefined | null | "">): string {
6
7
  return attrs.filter(Boolean).join(" ");
@@ -96,11 +97,13 @@ interface CdnUrlTemplates {
96
97
 
97
98
  const CDN_URL_TEMPLATES: Record<CdnProvider, CdnUrlTemplates> = {
98
99
  "esm.sh": {
99
- react: (v) => `https://esm.sh/react@${v}?target=es2022`,
100
- reactDom: (v) => `https://esm.sh/react-dom@${v}?external=react&target=es2022`,
101
- reactDomClient: (v) => `https://esm.sh/react-dom@${v}/client?external=react&target=es2022`,
102
- jsxRuntime: (v) => `https://esm.sh/react@${v}/jsx-runtime?target=es2022`,
103
- jsxDevRuntime: (v) => `https://esm.sh/react@${v}/jsx-dev-runtime?target=es2022`,
100
+ // Use centralized esmShReact() helper from package-registry.ts to ensure URL consistency
101
+ // Any URL mismatch causes esm.sh to serve different modules -> multiple React instances -> hooks fail
102
+ react: (v) => esmShReact("react", v),
103
+ reactDom: (v) => esmShReact("react-dom", v, "", true),
104
+ reactDomClient: (v) => esmShReact("react-dom", v, "/client", true),
105
+ jsxRuntime: (v) => esmShReact("react", v, "/jsx-runtime", true),
106
+ jsxDevRuntime: (v) => esmShReact("react", v, "/jsx-dev-runtime", true),
104
107
  veryfrontAgentReact: (v) =>
105
108
  `https://esm.sh/veryfront@${v}/agent/react?external=react,react-dom&target=es2022`,
106
109
  veryfrontComponentsAi: (v) =>
@@ -6,7 +6,10 @@ import { rendererLogger as logger } from "../../utils/index.js";
6
6
  import { withSpan } from "../../observability/tracing/otlp-setup.js";
7
7
  import { getProjectTmpDir } from "./temp-directory.js";
8
8
  import type { ComponentMap, ComponentSource, LoadComponentOptions } from "./types.js";
9
- import { DEFAULT_REACT_VERSION } from "../../transforms/esm/package-registry.js";
9
+ import {
10
+ DEFAULT_REACT_VERSION,
11
+ getReactImportMap,
12
+ } from "../../transforms/esm/package-registry.js";
10
13
 
11
14
  type TransformedComponent = { name: string; code: string };
12
15
 
@@ -78,6 +81,8 @@ async function writeComponentFiles(
78
81
 
79
82
  function generateEntryPoint(components: TransformedComponent[], reactVersion?: string): string {
80
83
  const version = reactVersion ?? DEFAULT_REACT_VERSION;
84
+ // Use centralized React URL from package-registry to ensure consistency
85
+ const reactUrl = getReactImportMap(version).react;
81
86
  const imports = components
82
87
  .map((comp) => `import { default as ${comp.name} } from './${comp.name}.js'`)
83
88
  .join("\n");
@@ -85,7 +90,7 @@ function generateEntryPoint(components: TransformedComponent[], reactVersion?: s
85
90
  const exports = components.map((comp) => comp.name).join(", ");
86
91
 
87
92
  return `
88
- import * as React from 'https://esm.sh/react@${version}?target=es2022'
93
+ import * as React from '${reactUrl}'
89
94
  ${imports}
90
95
 
91
96
  export { ${exports} }
@@ -1,4 +1,5 @@
1
1
  import { getReactImportMap, getReactVersion } from "../../transforms/esm/package-registry.js";
2
+ import { isDeno } from "../../platform/compat/runtime.js";
2
3
 
3
4
  export interface SSRRewriteOptions {
4
5
  /** Project slug for multi-project routing */
@@ -14,8 +15,13 @@ export interface SSRRewriteOptions {
14
15
  }
15
16
 
16
17
  function shouldKeepBareSpecifier(specifier: string): boolean {
18
+ // npm: specifiers are only supported in Deno, not Node.js
19
+ // In Node.js, we need to convert them to esm.sh URLs (handled in rewriteBareImports)
20
+ if (specifier.startsWith("npm:")) {
21
+ return isDeno;
22
+ }
23
+
17
24
  if (
18
- specifier.startsWith("npm:") ||
19
25
  specifier.startsWith("http://") ||
20
26
  specifier.startsWith("https://") ||
21
27
  specifier.startsWith("file://") ||
@@ -60,12 +66,15 @@ function resolveReactForRuntime(specifier: string, version?: string): string | n
60
66
  function rewriteBareImports(code: string, version?: string): string {
61
67
  const v = version ?? getReactVersion();
62
68
  return code.replace(/from\s+["']([^"'./][^"']*)["']/g, (_match, specifier: string) => {
63
- const reactUrl = resolveReactForRuntime(specifier, v);
69
+ // Strip npm: prefix for resolution (npm: is Deno-specific)
70
+ const bareSpecifier = specifier.startsWith("npm:") ? specifier.slice(4) : specifier;
71
+
72
+ const reactUrl = resolveReactForRuntime(bareSpecifier, v);
64
73
  if (reactUrl) return `from "${reactUrl}"`;
65
74
  if (shouldKeepBareSpecifier(specifier)) return `from "${specifier}"`;
66
75
 
67
76
  // For third-party packages: Use esm.sh with external=react
68
- return `from "https://esm.sh/${specifier}?external=react&target=es2022"`;
77
+ return `from "https://esm.sh/${bareSpecifier}?external=react&target=es2022"`;
69
78
  });
70
79
  }
71
80
 
@@ -2,6 +2,12 @@ import { rendererLogger as logger } from "../../utils/index.js";
2
2
  import { join } from "../../platform/compat/path/index.js";
3
3
  import { createError, toError } from "../../errors/veryfront-error.js";
4
4
  import { createFileSystem } from "../../platform/compat/fs.js";
5
+ import { getReactUrls } from "../../transforms/esm/package-registry.js";
6
+ import {
7
+ REACT_VERSION_17,
8
+ REACT_VERSION_18_2,
9
+ REACT_VERSION_19_RC,
10
+ } from "../../utils/constants/cdn.js";
5
11
 
6
12
  export type ReactVersion = "17" | "18" | "19";
7
13
 
@@ -20,38 +26,18 @@ export interface ReactVersionSwitcher {
20
26
  export const REACT_CONFIGS: Record<ReactVersion, ReactVersionConfig> = {
21
27
  "17": {
22
28
  version: "17",
23
- exact: "17.0.2",
24
- imports: {
25
- react: "https://esm.sh/react@17.0.2",
26
- "react-dom": "https://esm.sh/react-dom@17.0.2",
27
- "react-dom/server": "https://esm.sh/react-dom@17.0.2/server",
28
- "react/jsx-runtime": "https://esm.sh/react@17.0.2/jsx-runtime",
29
- "react/jsx-dev-runtime": "https://esm.sh/react@17.0.2/jsx-dev-runtime",
30
- },
29
+ exact: REACT_VERSION_17,
30
+ imports: getReactUrls(REACT_VERSION_17),
31
31
  },
32
32
  "18": {
33
33
  version: "18",
34
- exact: "18.2.0",
35
- imports: {
36
- react: "https://esm.sh/react@18.2.0",
37
- "react-dom": "https://esm.sh/react-dom@18.2.0",
38
- "react-dom/server": "https://esm.sh/react-dom@18.2.0/server",
39
- "react-dom/client": "https://esm.sh/react-dom@18.2.0/client",
40
- "react/jsx-runtime": "https://esm.sh/react@18.2.0/jsx-runtime",
41
- "react/jsx-dev-runtime": "https://esm.sh/react@18.2.0/jsx-dev-runtime",
42
- },
34
+ exact: REACT_VERSION_18_2,
35
+ imports: getReactUrls(REACT_VERSION_18_2),
43
36
  },
44
37
  "19": {
45
38
  version: "19",
46
- exact: "19.0.0-rc.0",
47
- imports: {
48
- react: "https://esm.sh/react@19.0.0-rc.0",
49
- "react-dom": "https://esm.sh/react-dom@19.0.0-rc.0",
50
- "react-dom/server": "https://esm.sh/react-dom@19.0.0-rc.0/server",
51
- "react-dom/client": "https://esm.sh/react-dom@19.0.0-rc.0/client",
52
- "react/jsx-runtime": "https://esm.sh/react@19.0.0-rc.0/jsx-runtime",
53
- "react/jsx-dev-runtime": "https://esm.sh/react@19.0.0-rc.0/jsx-dev-runtime",
54
- },
39
+ exact: REACT_VERSION_19_RC,
40
+ imports: getReactUrls(REACT_VERSION_19_RC),
55
41
  },
56
42
  };
57
43
 
@@ -8,6 +8,7 @@ import type { RuntimeAdapter } from "../platform/adapters/base.js";
8
8
  import { getProjectReact, renderToStringAdapter } from "../react/index.js";
9
9
  import { loadComponentFromSource } from "../modules/react-loader/index.js";
10
10
  import { CompilationError } from "../errors/index.js";
11
+ import { DEFAULT_REACT_VERSION, getReactUrls } from "../transforms/esm/package-registry.js";
11
12
 
12
13
  type ReactComponentLike = import("react").ComponentType<{ children?: import("react").ReactNode }>;
13
14
 
@@ -44,8 +45,9 @@ export async function renderAppRouteToHTML(args: {
44
45
  routePath: string;
45
46
  pageFile: string;
46
47
  contentSourceId: string;
48
+ reactVersion?: string;
47
49
  }): Promise<string> {
48
- const { adapter, projectDir, routePath, pageFile, contentSourceId } = args;
50
+ const { adapter, projectDir, routePath, pageFile, contentSourceId, reactVersion } = args;
49
51
 
50
52
  const appRoot = join(projectDir, "app");
51
53
  const layouts: string[] = [];
@@ -101,15 +103,7 @@ export async function renderAppRouteToHTML(args: {
101
103
 
102
104
  <!-- Import map for React dependencies -->
103
105
  <script type="importmap">
104
- {
105
- "imports": {
106
- "react": "https://esm.sh/react@18.3.1",
107
- "react-dom": "https://esm.sh/react-dom@18.3.1",
108
- "react-dom/client": "https://esm.sh/react-dom@18.3.1/client",
109
- "react/jsx-runtime": "https://esm.sh/react@18.3.1/jsx-runtime",
110
- "react/jsx-dev-runtime": "https://esm.sh/react@18.3.1/jsx-dev-runtime"
111
- }
112
- }
106
+ ${JSON.stringify({ imports: getReactUrls(reactVersion ?? DEFAULT_REACT_VERSION) }, null, 4)}
113
107
  </script>
114
108
 
115
109
  <!-- Basic styles -->
@@ -2,6 +2,7 @@ import { parseImports, replaceSpecifiers, rewriteImports } from "./lexer.js";
2
2
  import { REACT_DEFAULT_VERSION, TAILWIND_VERSION } from "../../utils/constants/cdn.js";
3
3
  import { rendererLogger as logger } from "../../utils/index.js";
4
4
  import { withSpan } from "../../observability/tracing/otlp-setup.js";
5
+ import { getReactImportMap } from "./package-registry.js";
5
6
 
6
7
  export function addHMRTimestamps(code: string, timestamp: string | number): Promise<string> {
7
8
  return withSpan(
@@ -49,18 +50,6 @@ function normalizeVersionedSpecifier(specifier: string): string {
49
50
  return specifier.replace(/@[\d^~x][\d.x^~-]*(?=\/|$)/, "");
50
51
  }
51
52
 
52
- const REACT_IMPORT_MAP: Record<string, string> = {
53
- react: `https://esm.sh/react@${REACT_DEFAULT_VERSION}?target=es2022`,
54
- "react-dom": `https://esm.sh/react-dom@${REACT_DEFAULT_VERSION}?external=react&target=es2022`,
55
- "react-dom/client":
56
- `https://esm.sh/react-dom@${REACT_DEFAULT_VERSION}/client?external=react&target=es2022`,
57
- "react-dom/server":
58
- `https://esm.sh/react-dom@${REACT_DEFAULT_VERSION}/server?external=react&target=es2022`,
59
- "react/jsx-runtime": `https://esm.sh/react@${REACT_DEFAULT_VERSION}/jsx-runtime?target=es2022`,
60
- "react/jsx-dev-runtime":
61
- `https://esm.sh/react@${REACT_DEFAULT_VERSION}/jsx-dev-runtime?target=es2022`,
62
- };
63
-
64
53
  function shouldSkipRewrite(specifier: string): boolean {
65
54
  return (
66
55
  specifier.startsWith("http://") ||
@@ -74,12 +63,19 @@ function shouldSkipRewrite(specifier: string): boolean {
74
63
  );
75
64
  }
76
65
 
77
- export function rewriteBareImports(code: string, _moduleServerUrl?: string): Promise<string> {
66
+ export function rewriteBareImports(
67
+ code: string,
68
+ _moduleServerUrl?: string,
69
+ reactVersion?: string,
70
+ ): Promise<string> {
71
+ // Get React import map for the specified version (uses centralized URL builder)
72
+ const reactImportMap = getReactImportMap(reactVersion ?? REACT_DEFAULT_VERSION);
73
+
78
74
  return withSpan(
79
75
  "transforms.esm.rewriteBareImports",
80
76
  () =>
81
77
  replaceSpecifiers(code, (specifier) => {
82
- const mapped = REACT_IMPORT_MAP[specifier];
78
+ const mapped = reactImportMap[specifier];
83
79
  if (mapped) return mapped;
84
80
 
85
81
  if (shouldSkipRewrite(specifier)) return null;
@@ -63,10 +63,14 @@ export const REACT_VERSION = DEFAULT_REACT_VERSION;
63
63
  export const TRANSFORM_CACHE_VERSION = 12;
64
64
 
65
65
  /** csstype version - must match deno.json for type consistency */
66
- const CSSTYPE_VERSION = "3.2.3";
66
+ export const CSSTYPE_VERSION = "3.2.3";
67
67
 
68
- /** Build esm.sh URL with deps=csstype for React packages (ensures type consistency) */
69
- function esmShReact(pkg: string, version: string, path = "", external = false): string {
68
+ /**
69
+ * Build esm.sh URL with deps=csstype for React packages (ensures type consistency).
70
+ * CRITICAL: This is the single source of truth for React URLs. All other files
71
+ * (html/utils.ts, import-rewriter.ts, etc.) must use this or getReactImportMap().
72
+ */
73
+ export function esmShReact(pkg: string, version: string, path = "", external = false): string {
70
74
  const params = external
71
75
  ? [`external=react`, `target=es2022`, `deps=csstype@${CSSTYPE_VERSION}`]
72
76
  : [`target=es2022`, `deps=csstype@${CSSTYPE_VERSION}`];
@@ -24,7 +24,7 @@ export const resolveBarePlugin: TransformPlugin = {
24
24
  return rewriteVendorImports(ctx.code, ctx.moduleServerUrl, ctx.vendorBundleHash);
25
25
  }
26
26
 
27
- return rewriteBareImports(ctx.code, ctx.moduleServerUrl);
27
+ return rewriteBareImports(ctx.code, ctx.moduleServerUrl, ctx.reactVersion);
28
28
  },
29
29
  };
30
30
 
@@ -10,57 +10,33 @@ export const REACT_VERSION_19 = "19.1.1";
10
10
 
11
11
  export const REACT_DEFAULT_VERSION = REACT_VERSION_19;
12
12
 
13
- /**
14
- * esm.sh URL builder with consistent query params.
15
- *
16
- * For React packages (react-dom, jsx-runtime), we only need external=react:
17
- * - react-dom depends on react → external=react makes it import "react" as bare specifier
18
- * - react-dom doesn't need external=react-dom because it IS react-dom
19
- * - jsx-runtime depends on react core → external=react
20
- *
21
- * Third-party packages (e.g., @tanstack/react-query) need external=react,react-dom
22
- * because they may depend on BOTH. That's handled by bundleHttpImports() separately.
23
- */
24
- function esmSh(pkg: string, version: string, path = "", external = false): string {
25
- const params = ["target=es2022"];
26
- if (external) params.push("external=react");
27
- return `${ESM_CDN_BASE}/${pkg}@${version}${path}?${params.join("&")}`;
28
- }
13
+ // Re-export from package-registry.ts - the SINGLE SOURCE OF TRUTH for React URLs.
14
+ // This ensures all React URLs include deps=csstype and match exactly.
15
+ // DO NOT add duplicate URL builders here - use package-registry.ts instead.
16
+ import * as ReactRegistry from "../../transforms/esm/package-registry.js";
29
17
 
30
- export function getReactCDNUrl(version: string = REACT_DEFAULT_VERSION): string {
31
- return esmSh("react", version);
32
- }
18
+ export const esmShReact = ReactRegistry.esmShReact;
19
+ export const getReactImportMap = ReactRegistry.getReactImportMap;
20
+ export const getReactUrls = ReactRegistry.getReactUrls;
33
21
 
34
- export function getReactDOMCDNUrl(version: string = REACT_DEFAULT_VERSION): string {
35
- return esmSh("react-dom", version, "", true);
36
- }
22
+ // Named getters for convenience - delegate to ReactRegistry
23
+ export const getReactCDNUrl = (version = REACT_DEFAULT_VERSION) =>
24
+ ReactRegistry.getReactUrls(version).react!;
37
25
 
38
- export function getReactDOMClientCDNUrl(version: string = REACT_DEFAULT_VERSION): string {
39
- return esmSh("react-dom", version, "/client", true);
40
- }
26
+ export const getReactDOMCDNUrl = (version = REACT_DEFAULT_VERSION) =>
27
+ ReactRegistry.getReactUrls(version)["react-dom"]!;
41
28
 
42
- export function getReactDOMServerCDNUrl(version: string = REACT_DEFAULT_VERSION): string {
43
- return esmSh("react-dom", version, "/server", true);
44
- }
29
+ export const getReactDOMClientCDNUrl = (version = REACT_DEFAULT_VERSION) =>
30
+ ReactRegistry.getReactUrls(version)["react-dom/client"]!;
45
31
 
46
- export function getReactJSXRuntimeCDNUrl(version: string = REACT_DEFAULT_VERSION): string {
47
- return esmSh("react", version, "/jsx-runtime", true);
48
- }
32
+ export const getReactDOMServerCDNUrl = (version = REACT_DEFAULT_VERSION) =>
33
+ ReactRegistry.getReactUrls(version)["react-dom/server"]!;
49
34
 
50
- export function getReactJSXDevRuntimeCDNUrl(version: string = REACT_DEFAULT_VERSION): string {
51
- return esmSh("react", version, "/jsx-dev-runtime", true);
52
- }
35
+ export const getReactJSXRuntimeCDNUrl = (version = REACT_DEFAULT_VERSION) =>
36
+ ReactRegistry.getReactUrls(version)["react/jsx-runtime"]!;
53
37
 
54
- export function getReactImportMap(version: string = REACT_DEFAULT_VERSION): Record<string, string> {
55
- return {
56
- react: getReactCDNUrl(version),
57
- "react-dom": getReactDOMCDNUrl(version),
58
- "react-dom/client": getReactDOMClientCDNUrl(version),
59
- "react-dom/server": getReactDOMServerCDNUrl(version),
60
- "react/jsx-runtime": getReactJSXRuntimeCDNUrl(version),
61
- "react/jsx-dev-runtime": getReactJSXDevRuntimeCDNUrl(version),
62
- };
63
- }
38
+ export const getReactJSXDevRuntimeCDNUrl = (version = REACT_DEFAULT_VERSION) =>
39
+ ReactRegistry.getReactUrls(version)["react/jsx-dev-runtime"]!;
64
40
 
65
41
  export const DEFAULT_ALLOWED_CDN_HOSTS = [ESM_CDN_BASE, DENO_STD_BASE];
66
42