@ethisyscore/vite-plugin 1.121.0 → 1.123.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.d.cts CHANGED
@@ -198,7 +198,7 @@ interface ContractBPluginOptions {
198
198
  * Behaviour:
199
199
  * - For `renderMode: "remote-runtime"`: declares a single ESM worker entry as
200
200
  * the Rollup input table. The output is forced to `format: "es"` and
201
- * `inlineDynamicImports: true` so a Contract B plugin always ships as ONE
201
+ * `codeSplitting: false` so a Contract B plugin always ships as ONE
202
202
  * bundled module — no chunk splitting, no shared chunks, no async imports
203
203
  * spread across multiple files. This is the precondition for E4.S4's
204
204
  * frozen import map.
@@ -299,7 +299,7 @@ interface PlatformReactPluginOptions {
299
299
  * Behaviour:
300
300
  * - For each declared page: registers `{ "platform-react/<id>": <moduleSpecifier> }`
301
301
  * in Rollup's input table. Output is forced to `format: "es"` and
302
- * `inlineDynamicImports: true` so each page ships as ONE bundled module.
302
+ * `codeSplitting: false` so each page ships as ONE bundled module.
303
303
  * - Emits a `platform-react/platform-react-pages.json` companion asset listing
304
304
  * the declared pages so the host (and the `.ccpkg` packaging step) can
305
305
  * inspect what the build produced.
@@ -592,13 +592,37 @@ interface PlatformReactBuildSummary {
592
592
  * while a feature component pulls in the `components/ui/dialog` wrapper of the
593
593
  * same name). The host loader handles `import * as X`, plain `import { Y }`,
594
594
  * default imports, and aliased EXPORTS — but throws "Unexpected identifier 'as'"
595
- * on aliased named IMPORTS `{ X as Y }`. In a final `inlineDynamicImports`
595
+ * on aliased named IMPORTS `{ X as Y }`. In a final single-chunk
596
596
  * bundle every remaining `import { … } from "…"` is an EXTERNAL import, so
597
597
  * rewriting any that contain `as` into `import * as ns from "…"; const local =
598
598
  * ns.imported, …;` is safe and removes the only construct the loader rejects.
599
599
  * Runs in `renderChunk`, before the host-verified digest is computed.
600
600
  */
601
601
  declare function rewriteAliasedExternalImports(): Plugin;
602
+ /**
603
+ * Fail the BUILD when a bundle emits an externalised specifier in a form the host's
604
+ * loader cannot rewrite.
605
+ *
606
+ * The host fetches a bundle as text, finds its imports with `es-module-lexer`, and
607
+ * rewrites each import of a REGISTERED specifier into a read from its module registry.
608
+ * That rewriter deliberately handles only a closed set of forms. It SKIPS:
609
+ *
610
+ * - dynamic `import("spec")` (`record.d !== -1`)
611
+ * - import attributes (`with { … }`) (`record.a !== -1`)
612
+ * - anything no `IMPORT_FORMS` regex matches, notably `export … from "spec"`
613
+ *
614
+ * and a skipped statement is left VERBATIM. A bare specifier that survives into a Blob
615
+ * URL module is unresolvable, so the surface dies at mount, before any plugin code runs
616
+ * — with no build-time signal and a stack trace that points at the host, not the plugin
617
+ * that caused it.
618
+ *
619
+ * Today no plugin in the estate emits either form, so this guard is quiet. It exists so
620
+ * that the day someone writes `const { DataGrid } = await import("@mui/x-data-grid")` or
621
+ * re-exports a host package from a barrel, they get a build error naming the file instead
622
+ * of a blank surface in production. The check is on EMITTED syntax rather than source,
623
+ * because whether a source-level re-export survives bundling depends on the entry shape.
624
+ */
625
+ declare function assertHostResolvableExternals(external: readonly string[]): Plugin;
602
626
  /**
603
627
  * Synthesise one isolated PlatformReact entry per surface straight from its
604
628
  * manifest declaration: `definePluginPage(Page, { …views })`, importing ONLY
@@ -620,8 +644,8 @@ declare function virtualPageEntry(page: PlatformReactPageInput, config: {
620
644
  * per-asset SHA-256 `platform-react-digest-map.json` the host's verified loader
621
645
  * and the `.ccpkg` packaging step read.
622
646
  *
623
- * Each PlatformReact page must be ONE bundle (`inlineDynamicImports: true`), and
624
- * Rollup rejects that with more than one input — so this runs one Vite sub-build
647
+ * Each PlatformReact page must be ONE bundle (`codeSplitting: false`), and
648
+ * the bundler rejects that with more than one input — so this runs one Vite sub-build
625
649
  * per surface, each with a single synthesised virtual entry (see
626
650
  * {@link virtualPageEntry}). The generic seams (host externals, dedupe, the
627
651
  * host-loader aliased-import rewrite, the digest/summary contract) live here;
@@ -1132,4 +1156,4 @@ interface EthisysPluginOptions {
1132
1156
  */
1133
1157
  declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
1134
1158
 
1135
- export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
1159
+ export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, assertHostResolvableExternals, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
package/dist/index.d.ts CHANGED
@@ -198,7 +198,7 @@ interface ContractBPluginOptions {
198
198
  * Behaviour:
199
199
  * - For `renderMode: "remote-runtime"`: declares a single ESM worker entry as
200
200
  * the Rollup input table. The output is forced to `format: "es"` and
201
- * `inlineDynamicImports: true` so a Contract B plugin always ships as ONE
201
+ * `codeSplitting: false` so a Contract B plugin always ships as ONE
202
202
  * bundled module — no chunk splitting, no shared chunks, no async imports
203
203
  * spread across multiple files. This is the precondition for E4.S4's
204
204
  * frozen import map.
@@ -299,7 +299,7 @@ interface PlatformReactPluginOptions {
299
299
  * Behaviour:
300
300
  * - For each declared page: registers `{ "platform-react/<id>": <moduleSpecifier> }`
301
301
  * in Rollup's input table. Output is forced to `format: "es"` and
302
- * `inlineDynamicImports: true` so each page ships as ONE bundled module.
302
+ * `codeSplitting: false` so each page ships as ONE bundled module.
303
303
  * - Emits a `platform-react/platform-react-pages.json` companion asset listing
304
304
  * the declared pages so the host (and the `.ccpkg` packaging step) can
305
305
  * inspect what the build produced.
@@ -592,13 +592,37 @@ interface PlatformReactBuildSummary {
592
592
  * while a feature component pulls in the `components/ui/dialog` wrapper of the
593
593
  * same name). The host loader handles `import * as X`, plain `import { Y }`,
594
594
  * default imports, and aliased EXPORTS — but throws "Unexpected identifier 'as'"
595
- * on aliased named IMPORTS `{ X as Y }`. In a final `inlineDynamicImports`
595
+ * on aliased named IMPORTS `{ X as Y }`. In a final single-chunk
596
596
  * bundle every remaining `import { … } from "…"` is an EXTERNAL import, so
597
597
  * rewriting any that contain `as` into `import * as ns from "…"; const local =
598
598
  * ns.imported, …;` is safe and removes the only construct the loader rejects.
599
599
  * Runs in `renderChunk`, before the host-verified digest is computed.
600
600
  */
601
601
  declare function rewriteAliasedExternalImports(): Plugin;
602
+ /**
603
+ * Fail the BUILD when a bundle emits an externalised specifier in a form the host's
604
+ * loader cannot rewrite.
605
+ *
606
+ * The host fetches a bundle as text, finds its imports with `es-module-lexer`, and
607
+ * rewrites each import of a REGISTERED specifier into a read from its module registry.
608
+ * That rewriter deliberately handles only a closed set of forms. It SKIPS:
609
+ *
610
+ * - dynamic `import("spec")` (`record.d !== -1`)
611
+ * - import attributes (`with { … }`) (`record.a !== -1`)
612
+ * - anything no `IMPORT_FORMS` regex matches, notably `export … from "spec"`
613
+ *
614
+ * and a skipped statement is left VERBATIM. A bare specifier that survives into a Blob
615
+ * URL module is unresolvable, so the surface dies at mount, before any plugin code runs
616
+ * — with no build-time signal and a stack trace that points at the host, not the plugin
617
+ * that caused it.
618
+ *
619
+ * Today no plugin in the estate emits either form, so this guard is quiet. It exists so
620
+ * that the day someone writes `const { DataGrid } = await import("@mui/x-data-grid")` or
621
+ * re-exports a host package from a barrel, they get a build error naming the file instead
622
+ * of a blank surface in production. The check is on EMITTED syntax rather than source,
623
+ * because whether a source-level re-export survives bundling depends on the entry shape.
624
+ */
625
+ declare function assertHostResolvableExternals(external: readonly string[]): Plugin;
602
626
  /**
603
627
  * Synthesise one isolated PlatformReact entry per surface straight from its
604
628
  * manifest declaration: `definePluginPage(Page, { …views })`, importing ONLY
@@ -620,8 +644,8 @@ declare function virtualPageEntry(page: PlatformReactPageInput, config: {
620
644
  * per-asset SHA-256 `platform-react-digest-map.json` the host's verified loader
621
645
  * and the `.ccpkg` packaging step read.
622
646
  *
623
- * Each PlatformReact page must be ONE bundle (`inlineDynamicImports: true`), and
624
- * Rollup rejects that with more than one input — so this runs one Vite sub-build
647
+ * Each PlatformReact page must be ONE bundle (`codeSplitting: false`), and
648
+ * the bundler rejects that with more than one input — so this runs one Vite sub-build
625
649
  * per surface, each with a single synthesised virtual entry (see
626
650
  * {@link virtualPageEntry}). The generic seams (host externals, dedupe, the
627
651
  * host-loader aliased-import rewrite, the digest/summary contract) live here;
@@ -1132,4 +1156,4 @@ interface EthisysPluginOptions {
1132
1156
  */
1133
1157
  declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
1134
1158
 
1135
- export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
1159
+ export { type BuildPlatformReactPagesOptions, CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ComputePlatformReactPagesInput, type ComputePlatformReactPagesResult, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, type EthisysPluginOptions, type GeneratePlatformReactManifestConfig, type GeneratePlatformReactManifestResult, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, type ParsePlatformReactPagesOptions, type PlatformReactAlias, type PlatformReactBuildContext, type PlatformReactBuildSummary, type PlatformReactManifest, type PlatformReactManifestMeta, type PlatformReactManifestPaths, type PlatformReactPageDeclaration, type PlatformReactPageEntry, type PlatformReactPageInput, type PlatformReactPageOverride, type PlatformReactPageSource, type PlatformReactPluginOptions, type PlatformReactViteBuild, type ResolvedPlatformReactPage, type RouteMetaEntry, type ScopePluginCssOptions, type ValidationFailure, type ValidationResult, type ViteBuildFn, assertHostResolvableExternals, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
package/dist/index.js CHANGED
@@ -454,7 +454,7 @@ function ethisysContractBPlugin(options = {}) {
454
454
  const externalSpecifiers = new Set(CONTRACT_B_IMPORT_MAP_ALLOWLIST);
455
455
  return {
456
456
  build: {
457
- rollupOptions: {
457
+ rolldownOptions: {
458
458
  input: { worker: slash(workerEntryAbs) },
459
459
  external: (id) => externalSpecifiers.has(id),
460
460
  // CRITICAL: single-file output for the worker bundle. The
@@ -462,7 +462,7 @@ function ethisysContractBPlugin(options = {}) {
462
462
  // chunk splitting or dynamic-import shards would defeat it.
463
463
  output: {
464
464
  format: "es",
465
- inlineDynamicImports: true,
465
+ codeSplitting: false,
466
466
  entryFileNames: `${outputPrefix}[name].js`,
467
467
  chunkFileNames: `${outputPrefix}[name]-[hash].js`,
468
468
  assetFileNames: `${outputPrefix}[name][extname]`
@@ -596,6 +596,48 @@ function ethisysContractBPlugin(options = {}) {
596
596
  };
597
597
  }
598
598
 
599
+ // src/utils/inline-css-sourcemap-log.ts
600
+ var PRE_CSS_POST_PLUGIN = /^(?:@tailwindcss\/vite:|vite:css$)/;
601
+ function isInlineCssSourcemapNoise(log) {
602
+ return log.code === "SOURCEMAP_BROKEN" && PRE_CSS_POST_PLUGIN.test(log.plugin ?? "") && /\.css\?(?:[^#]*&)?inline(?:[&=#]|$)/.test(log.id ?? "");
603
+ }
604
+ function dropInlineCssSourcemapNoise(next) {
605
+ const filtered = (level, log, handler) => {
606
+ if (isInlineCssSourcemapNoise(log)) {
607
+ return;
608
+ }
609
+ if (next) {
610
+ next(level, log, handler);
611
+ return;
612
+ }
613
+ handler(level, log);
614
+ };
615
+ return Object.assign(filtered, { [WRAPPED]: true });
616
+ }
617
+ var WRAPPED = /* @__PURE__ */ Symbol.for("ethisys.vite-plugin.inline-css-sourcemap-noise");
618
+ function wrapResolvedOnLog(config) {
619
+ const writable = config;
620
+ writable.build ??= {};
621
+ writable.build.rolldownOptions ??= {};
622
+ const current = writable.build.rolldownOptions.onLog;
623
+ if (current && current[WRAPPED]) {
624
+ return;
625
+ }
626
+ writable.build.rolldownOptions.onLog = dropInlineCssSourcemapNoise(current);
627
+ }
628
+ function inlineCssSourcemapNoisePlugin() {
629
+ return {
630
+ name: "ethisys-inline-css-sourcemap-noise",
631
+ apply: "build",
632
+ buildStart() {
633
+ const config = this?.environment?.config;
634
+ if (config) {
635
+ wrapResolvedOnLog(config);
636
+ }
637
+ }
638
+ };
639
+ }
640
+
599
641
  // src/utils/strings.ts
600
642
  function slash2(p) {
601
643
  return p.replace(/\\/g, "/");
@@ -936,6 +978,36 @@ var PLATFORM_REACT_EXTERNALS = [
936
978
  "react-dom",
937
979
  "@mui/material",
938
980
  "@mui/icons-material",
981
+ // MUI X. Every plugin previously shipped its own copy on top of the host's.
982
+ //
983
+ // EXACT STRINGS, and that is load-bearing rather than stylistic. Rolldown matches
984
+ // a string `external` by equality, verified by building an entry that imports both
985
+ // `date-fns` and `date-fns/addDays` against `external: ["date-fns"]`: the bare
986
+ // import stayed external, the subpath was bundled. So a prefix or regex matcher
987
+ // here would externalise `@mui/x-data-grid/style.css` and
988
+ // `@mui/x-date-pickers/AdapterDayjs` too, which the host does NOT register, and an
989
+ // external the host does not serve is an unresolvable bare import that kills the
990
+ // bundle before any plugin code runs. `startsWith("@mui/x-charts")` additionally
991
+ // swallows `@mui/x-charts-pro`. Add specifiers one at a time; never widen the match.
992
+ //
993
+ // THE CONSUMER-SIDE GATE: exact matching makes this safe but PARTIAL. A plugin that
994
+ // imports the package root AND a subpath of the same package gets TWO module
995
+ // instances, host-served and bundled, and React context does not cross that seam.
996
+ // The concrete break is `LocalizationProvider` from "@mui/x-date-pickers" (host)
997
+ // with `DatePicker` from "@mui/x-date-pickers/DatePicker" (bundled): the picker
998
+ // cannot see the provider's context and MUI throws "Can not find the date and time
999
+ // pickers localization context". Every root-exported symbol must therefore be
1000
+ // imported from the ROOT once its package is externalised.
1001
+ //
1002
+ // `@mui/x-date-pickers/AdapterDayjs` is the deliberate exception and stays a
1003
+ // sub-path import, because the root does not re-export it. That is safe here and it
1004
+ // was checked rather than assumed: `LocalizationProvider` validates the adapter with
1005
+ // `if (!dateAdapter.isMUIAdapter)`, a duck-typed flag, so a bundled adapter instance
1006
+ // handed to the host's provider passes. Contrast `instanceof`, which would not.
1007
+ "@mui/x-data-grid",
1008
+ "@mui/x-charts",
1009
+ "@mui/x-charts-pro",
1010
+ "@mui/x-date-pickers",
939
1011
  "@emotion/react",
940
1012
  "@emotion/styled",
941
1013
  "date-fns",
@@ -1027,6 +1099,34 @@ function rewriteAliasedExternalImports() {
1027
1099
  }
1028
1100
  };
1029
1101
  }
1102
+ function assertHostResolvableExternals(external) {
1103
+ return {
1104
+ name: "assert-host-resolvable-externals",
1105
+ renderChunk(code, chunk) {
1106
+ const offences = [];
1107
+ for (const spec of external) {
1108
+ const q = escapeRegExp(spec);
1109
+ const reExport = new RegExp(`\\bexport\\s[^;]{0,200}?from\\s*["']${q}["']`);
1110
+ const dynamic = new RegExp(`\\bimport\\s*\\(\\s*["']${q}["']\\s*\\)`);
1111
+ if (reExport.test(code)) {
1112
+ offences.push(`re-export of "${spec}" (export \u2026 from)`);
1113
+ }
1114
+ if (dynamic.test(code)) {
1115
+ offences.push(`dynamic import of "${spec}"`);
1116
+ }
1117
+ }
1118
+ if (offences.length > 0) {
1119
+ throw new Error(
1120
+ `[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:
1121
+ ` + offences.map((o) => ` - ${o}`).join("\n") + `
1122
+
1123
+ 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.`
1124
+ );
1125
+ }
1126
+ return null;
1127
+ }
1128
+ };
1129
+ }
1030
1130
  function virtualPageEntry(page, config) {
1031
1131
  const VIRTUAL_ID = `\0virtual:surface/${page.id}`;
1032
1132
  const views = page.views ?? {};
@@ -1115,7 +1215,10 @@ function makeDefaultBuild(viteBuild) {
1115
1215
  ctx.surfacePlugin,
1116
1216
  ...ctx.plugins,
1117
1217
  scopePluginCssPlugin(),
1118
- rewriteAliasedExternalImports()
1218
+ rewriteAliasedExternalImports(),
1219
+ // Last, so it sees exactly the bytes the host will fetch.
1220
+ assertHostResolvableExternals(ctx.external),
1221
+ inlineCssSourcemapNoisePlugin()
1119
1222
  ],
1120
1223
  resolve: {
1121
1224
  dedupe: [...ctx.dedupe],
@@ -1143,13 +1246,13 @@ function makeDefaultBuild(viteBuild) {
1143
1246
  cssMinify: ctx.cssMinify ?? true,
1144
1247
  reportCompressedSize: ctx.reportCompressedSize ?? false,
1145
1248
  sourcemap: ctx.sourcemap,
1146
- rollupOptions: {
1249
+ rolldownOptions: {
1147
1250
  input: { [ctx.pageId]: ctx.entryId },
1148
1251
  preserveEntrySignatures: "strict",
1149
1252
  external: [...ctx.external],
1150
1253
  output: {
1151
1254
  format: "es",
1152
- inlineDynamicImports: true,
1255
+ codeSplitting: false,
1153
1256
  sourcemapExcludeSources: ctx.sourcemapExcludeSources ?? true,
1154
1257
  entryFileNames: `${ctx.outputPrefix}/[name].js`,
1155
1258
  chunkFileNames: `${ctx.outputPrefix}/[name]-[hash].js`,
@@ -1346,7 +1449,11 @@ function assertHostOriginRelativePath2(value, label) {
1346
1449
  }
1347
1450
  }
1348
1451
  function ethisysPlatformReactPlugin(options = {}) {
1349
- return [ethisysPlatformReactPagesPlugin(options), scopePluginCssPlugin()];
1452
+ return [
1453
+ ethisysPlatformReactPagesPlugin(options),
1454
+ scopePluginCssPlugin(),
1455
+ assertHostResolvableExternals([...PLATFORM_REACT_EXTERNALS, "@ethisyscore/host-ui-externals"])
1456
+ ];
1350
1457
  }
1351
1458
  function ethisysPlatformReactPagesPlugin(options = {}) {
1352
1459
  const explicitRoot = options.root;
@@ -1496,7 +1603,7 @@ function ethisysPlatformReactPagesPlugin(options = {}) {
1496
1603
  // throws on the first hook). Vite minifies production builds by
1497
1604
  // default, so this MUST be forced off for every PlatformReact surface.
1498
1605
  minify: false,
1499
- rollupOptions: {
1606
+ rolldownOptions: {
1500
1607
  // CRITICAL: single-file ESM output per page. The host loads each
1501
1608
  // page via `import(url)` at mount time and reads the declared
1502
1609
  // `exportName` from the resulting module namespace. Chunk-split
@@ -1504,7 +1611,7 @@ function ethisysPlatformReactPagesPlugin(options = {}) {
1504
1611
  // import-map surface to resolve sibling chunks.
1505
1612
  output: {
1506
1613
  format: "es",
1507
- inlineDynamicImports: true,
1614
+ codeSplitting: false,
1508
1615
  entryFileNames: `${outputPrefix}[name].js`,
1509
1616
  chunkFileNames: `${outputPrefix}[name]-[hash].js`,
1510
1617
  assetFileNames: `${outputPrefix}[name][extname]`
@@ -1557,25 +1664,29 @@ function ethisysPlatformReactPagesPlugin(options = {}) {
1557
1664
  }
1558
1665
  const writable = config;
1559
1666
  writable.build ??= {};
1560
- writable.build.rollupOptions ??= {};
1561
- const rollupOptions = writable.build.rollupOptions;
1562
- const existing = rollupOptions.input;
1667
+ writable.build.rolldownOptions ??= {};
1668
+ const rolldownOptions = writable.build.rolldownOptions;
1669
+ const existing = rolldownOptions.input;
1563
1670
  if (existing && typeof existing === "object" && !Array.isArray(existing)) {
1564
- rollupOptions.input = { ...existing, ...input };
1671
+ rolldownOptions.input = { ...existing, ...input };
1565
1672
  } else if (typeof existing === "string") {
1566
- rollupOptions.input = { _entry: existing, ...input };
1673
+ rolldownOptions.input = { _entry: existing, ...input };
1567
1674
  } else if (Array.isArray(existing)) {
1568
1675
  const indexed = {};
1569
1676
  existing.forEach((entry, idx) => {
1570
1677
  indexed[`_entry${idx}`] = entry;
1571
1678
  });
1572
- rollupOptions.input = { ...indexed, ...input };
1679
+ rolldownOptions.input = { ...indexed, ...input };
1573
1680
  } else {
1574
- rollupOptions.input = input;
1681
+ rolldownOptions.input = input;
1575
1682
  }
1576
1683
  },
1577
1684
  buildStart() {
1578
1685
  validate();
1686
+ const config = this?.environment?.config;
1687
+ if (isBuild && config) {
1688
+ wrapResolvedOnLog(config);
1689
+ }
1579
1690
  },
1580
1691
  /**
1581
1692
  * Emit the companion `platform-react-pages.json` listing every declared
@@ -1954,7 +2065,7 @@ var defaultBuild = async (page) => {
1954
2065
  build: {
1955
2066
  outDir: page.outDir,
1956
2067
  emptyOutDir: true,
1957
- rollupOptions: {
2068
+ rolldownOptions: {
1958
2069
  input: resolve(page.root, page.entryPath)
1959
2070
  }
1960
2071
  }
@@ -2174,7 +2285,7 @@ function ethisysManifestPlugin(options = {}) {
2174
2285
  }
2175
2286
  return {
2176
2287
  build: {
2177
- rollupOptions: {
2288
+ rolldownOptions: {
2178
2289
  input
2179
2290
  }
2180
2291
  }
@@ -2283,6 +2394,6 @@ function ethisysManifestPlugin(options = {}) {
2283
2394
  * comment-free.
2284
2395
  */
2285
2396
 
2286
- export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
2397
+ export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, EHX_PLUGIN_CSS_SCOPE, EHX_PLUGIN_ROOT_SCOPE, EHX_PLUGIN_SCOPE_ROOTS, EHX_SCOPED_CSS_LAYERS, PLATFORM_REACT_DEDUPE, PLATFORM_REACT_EXTERNALS, assertHostResolvableExternals, buildIframeSandboxPages, buildPlatformReactPages, computePlatformReactPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPagesPlugin, ethisysPlatformReactPlugin, findUnscopedSelectors, formatUnscopedSelectorError, generatePlatformReactManifest, isScopableCssId, parseExportedNames, parsePlatformReactPages, rewriteAliasedExternalImports, scopePluginCss, scopePluginCssPlugin, validateDeclarativeResource, validateReactiveRule, virtualPageEntry };
2287
2398
  //# sourceMappingURL=index.js.map
2288
2399
  //# sourceMappingURL=index.js.map