@ethisyscore/vite-plugin 1.120.0 → 1.122.0

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/dist/index.cjs CHANGED
@@ -938,6 +938,36 @@ var PLATFORM_REACT_EXTERNALS = [
938
938
  "react-dom",
939
939
  "@mui/material",
940
940
  "@mui/icons-material",
941
+ // MUI X. Every plugin previously shipped its own copy on top of the host's.
942
+ //
943
+ // EXACT STRINGS, and that is load-bearing rather than stylistic. Rolldown matches
944
+ // a string `external` by equality, verified by building an entry that imports both
945
+ // `date-fns` and `date-fns/addDays` against `external: ["date-fns"]`: the bare
946
+ // import stayed external, the subpath was bundled. So a prefix or regex matcher
947
+ // here would externalise `@mui/x-data-grid/style.css` and
948
+ // `@mui/x-date-pickers/AdapterDayjs` too, which the host does NOT register, and an
949
+ // external the host does not serve is an unresolvable bare import that kills the
950
+ // bundle before any plugin code runs. `startsWith("@mui/x-charts")` additionally
951
+ // swallows `@mui/x-charts-pro`. Add specifiers one at a time; never widen the match.
952
+ //
953
+ // THE CONSUMER-SIDE GATE: exact matching makes this safe but PARTIAL. A plugin that
954
+ // imports the package root AND a subpath of the same package gets TWO module
955
+ // instances, host-served and bundled, and React context does not cross that seam.
956
+ // The concrete break is `LocalizationProvider` from "@mui/x-date-pickers" (host)
957
+ // with `DatePicker` from "@mui/x-date-pickers/DatePicker" (bundled): the picker
958
+ // cannot see the provider's context and MUI throws "Can not find the date and time
959
+ // pickers localization context". Every root-exported symbol must therefore be
960
+ // imported from the ROOT once its package is externalised.
961
+ //
962
+ // `@mui/x-date-pickers/AdapterDayjs` is the deliberate exception and stays a
963
+ // sub-path import, because the root does not re-export it. That is safe here and it
964
+ // was checked rather than assumed: `LocalizationProvider` validates the adapter with
965
+ // `if (!dateAdapter.isMUIAdapter)`, a duck-typed flag, so a bundled adapter instance
966
+ // handed to the host's provider passes. Contrast `instanceof`, which would not.
967
+ "@mui/x-data-grid",
968
+ "@mui/x-charts",
969
+ "@mui/x-charts-pro",
970
+ "@mui/x-date-pickers",
941
971
  "@emotion/react",
942
972
  "@emotion/styled",
943
973
  "date-fns",
@@ -1029,6 +1059,34 @@ function rewriteAliasedExternalImports() {
1029
1059
  }
1030
1060
  };
1031
1061
  }
1062
+ function assertHostResolvableExternals(external) {
1063
+ return {
1064
+ name: "assert-host-resolvable-externals",
1065
+ renderChunk(code, chunk) {
1066
+ const offences = [];
1067
+ for (const spec of external) {
1068
+ const q = escapeRegExp(spec);
1069
+ const reExport = new RegExp(`\\bexport\\s[^;]{0,200}?from\\s*["']${q}["']`);
1070
+ const dynamic = new RegExp(`\\bimport\\s*\\(\\s*["']${q}["']\\s*\\)`);
1071
+ if (reExport.test(code)) {
1072
+ offences.push(`re-export of "${spec}" (export \u2026 from)`);
1073
+ }
1074
+ if (dynamic.test(code)) {
1075
+ offences.push(`dynamic import of "${spec}"`);
1076
+ }
1077
+ }
1078
+ if (offences.length > 0) {
1079
+ throw new Error(
1080
+ `[build-pages] ${chunk.fileName ?? "bundle"} emits host-provided specifiers in a form the host loader cannot rewrite, so the surface would fail to load at mount:
1081
+ ` + offences.map((o) => ` - ${o}`).join("\n") + `
1082
+
1083
+ Use a STATIC top-level import of the package root instead. A dynamic import of a host-provided package is never needed: the host already loads its namespaces on demand, per bundle. For a re-export, import the symbols and export them explicitly.`
1084
+ );
1085
+ }
1086
+ return null;
1087
+ }
1088
+ };
1089
+ }
1032
1090
  function virtualPageEntry(page, config) {
1033
1091
  const VIRTUAL_ID = `\0virtual:surface/${page.id}`;
1034
1092
  const views = page.views ?? {};
@@ -1117,7 +1175,9 @@ function makeDefaultBuild(viteBuild) {
1117
1175
  ctx.surfacePlugin,
1118
1176
  ...ctx.plugins,
1119
1177
  scopePluginCssPlugin(),
1120
- rewriteAliasedExternalImports()
1178
+ rewriteAliasedExternalImports(),
1179
+ // Last, so it sees exactly the bytes the host will fetch.
1180
+ assertHostResolvableExternals(ctx.external)
1121
1181
  ],
1122
1182
  resolve: {
1123
1183
  dedupe: [...ctx.dedupe],
@@ -1348,7 +1408,11 @@ function assertHostOriginRelativePath2(value, label) {
1348
1408
  }
1349
1409
  }
1350
1410
  function ethisysPlatformReactPlugin(options = {}) {
1351
- return [ethisysPlatformReactPagesPlugin(options), scopePluginCssPlugin()];
1411
+ return [
1412
+ ethisysPlatformReactPagesPlugin(options),
1413
+ scopePluginCssPlugin(),
1414
+ assertHostResolvableExternals([...PLATFORM_REACT_EXTERNALS, "@ethisyscore/host-ui-externals"])
1415
+ ];
1352
1416
  }
1353
1417
  function ethisysPlatformReactPagesPlugin(options = {}) {
1354
1418
  const explicitRoot = options.root;
@@ -2294,6 +2358,7 @@ exports.EHX_PLUGIN_SCOPE_ROOTS = EHX_PLUGIN_SCOPE_ROOTS;
2294
2358
  exports.EHX_SCOPED_CSS_LAYERS = EHX_SCOPED_CSS_LAYERS;
2295
2359
  exports.PLATFORM_REACT_DEDUPE = PLATFORM_REACT_DEDUPE;
2296
2360
  exports.PLATFORM_REACT_EXTERNALS = PLATFORM_REACT_EXTERNALS;
2361
+ exports.assertHostResolvableExternals = assertHostResolvableExternals;
2297
2362
  exports.buildIframeSandboxPages = buildIframeSandboxPages;
2298
2363
  exports.buildPlatformReactPages = buildPlatformReactPages;
2299
2364
  exports.computePlatformReactPages = computePlatformReactPages;