@ethisyscore/vite-plugin 1.15.0 → 1.17.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
@@ -124,7 +124,7 @@ function ethisysContractAPlugin(options = {}) {
124
124
  manifestAbsPath = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(resolvedRoot, manifestRel);
125
125
  return resolvedRoot;
126
126
  }
127
- function readManifest2() {
127
+ function readManifest3() {
128
128
  resolveRoot();
129
129
  if (!fs.existsSync(manifestAbsPath)) {
130
130
  return null;
@@ -141,7 +141,7 @@ function ethisysContractAPlugin(options = {}) {
141
141
  function validate() {
142
142
  validatedResources = [];
143
143
  resourcePayloads.clear();
144
- const manifest = readManifest2();
144
+ const manifest = readManifest3();
145
145
  if (manifest === null) {
146
146
  return;
147
147
  }
@@ -387,7 +387,7 @@ function ethisysContractBPlugin(options = {}) {
387
387
  manifestAbsPath = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(resolvedRoot, manifestRel);
388
388
  return resolvedRoot;
389
389
  }
390
- function readManifest2() {
390
+ function readManifest3() {
391
391
  resolveRoot();
392
392
  if (!fs.existsSync(manifestAbsPath)) {
393
393
  return null;
@@ -404,7 +404,7 @@ function ethisysContractBPlugin(options = {}) {
404
404
  function validate() {
405
405
  workerEntryAbs = null;
406
406
  workerEntryRel = null;
407
- const manifest = readManifest2();
407
+ const manifest = readManifest3();
408
408
  if (manifest === null) {
409
409
  return;
410
410
  }
@@ -635,7 +635,7 @@ function ethisysPlatformReactPlugin(options = {}) {
635
635
  manifestAbsPath = path.isAbsolute(manifestRel) ? manifestRel : path.resolve(resolvedRoot, manifestRel);
636
636
  return resolvedRoot;
637
637
  }
638
- function readManifest2() {
638
+ function readManifest3() {
639
639
  resolveRoot();
640
640
  if (!fs.existsSync(manifestAbsPath)) {
641
641
  return null;
@@ -651,7 +651,7 @@ function ethisysPlatformReactPlugin(options = {}) {
651
651
  }
652
652
  function validate() {
653
653
  pages = [];
654
- const manifest = readManifest2();
654
+ const manifest = readManifest3();
655
655
  if (manifest === null) {
656
656
  return;
657
657
  }
@@ -916,13 +916,231 @@ function parsePlatformReactPages(manifestPath, options = {}) {
916
916
  }
917
917
  return result;
918
918
  }
919
+ var PLATFORM_REACT_EXTERNALS = [
920
+ "react",
921
+ "react/jsx-runtime",
922
+ "react-dom",
923
+ "@mui/material",
924
+ "@mui/icons-material",
925
+ "@emotion/react",
926
+ "@emotion/styled",
927
+ "date-fns",
928
+ "@ethisyscore/components-react",
929
+ "@ethisyscore/extension-runtime",
930
+ "@ethisyscore/extension-runtime/plugin"
931
+ ];
932
+ var PLATFORM_REACT_DEDUPE = [
933
+ "@tanstack/react-query",
934
+ "react",
935
+ "react-dom",
936
+ "@ethisyscore/extension-runtime"
937
+ ];
938
+ var DEFAULT_OUT_DIR = "dist";
939
+ var DEFAULT_OUTPUT_PREFIX = "platform-react";
940
+ var DEFAULT_DEFINE_PLUGIN_PAGE = "@/app/definePluginPage";
941
+ var DEFAULT_SRC_DIR = "src";
942
+ var DEFAULT_ALIAS_PREFIX = "@";
943
+ var SUMMARY_FILENAME = "platform-react-pages.json";
944
+ var DIGEST_MAP_FILENAME = "platform-react-digest-map.json";
945
+ function rewriteAliasedExternalImports() {
946
+ return {
947
+ name: "rewrite-aliased-external-imports",
948
+ renderChunk(code) {
949
+ let counter = 0;
950
+ let changed = false;
951
+ const out = code.replace(
952
+ // Optional default binding (`import Foo, { … }`) then the named braces.
953
+ /\bimport\s+(?:([\w$]+)\s*,\s*)?\{([^{}]*)\}\s*from\s*("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')\s*;?/g,
954
+ (full, def, specs, mod) => {
955
+ if (!/\sas\s/.test(specs)) return full;
956
+ changed = true;
957
+ const ns = `__ns_imp_${counter++}`;
958
+ const decls = specs.split(",").map((s) => s.trim()).filter(Boolean).map((s) => {
959
+ const [imported, local] = s.split(/\s+as\s+/).map((t) => t.trim());
960
+ return `${local ?? imported} = ${ns}.${imported}`;
961
+ }).join(", ");
962
+ const defPart = def ? `import ${def} from ${mod}; ` : "";
963
+ return `${defPart}import * as ${ns} from ${mod}; const ${decls};`;
964
+ }
965
+ );
966
+ return changed ? { code: out, map: null } : null;
967
+ }
968
+ };
969
+ }
970
+ function virtualPageEntry(page, config) {
971
+ const VIRTUAL_ID = `\0virtual:surface/${page.id}`;
972
+ const views = page.views ?? {};
973
+ const names = Object.keys(views);
974
+ const viewImports = names.map((n) => `import { ${n} } from ${JSON.stringify(config.toAlias(views[n]))};`).join("\n");
975
+ const src = `import Page from ${JSON.stringify(config.toAlias(page.moduleSpecifier))};
976
+ ${viewImports}
977
+ import { definePluginPage } from ${JSON.stringify(config.definePluginPageSpecifier)};
978
+ export default definePluginPage(Page, { ${names.join(", ")} });
979
+ `;
980
+ return {
981
+ id: VIRTUAL_ID,
982
+ plugin: {
983
+ name: `virtual-surface-${page.id}`,
984
+ resolveId: (id) => id === VIRTUAL_ID ? VIRTUAL_ID : null,
985
+ load: (id) => id === VIRTUAL_ID ? src : null
986
+ }
987
+ };
988
+ }
989
+ function defaultWriteFile(path$1, contents) {
990
+ fs.mkdirSync(path.dirname(path$1), { recursive: true });
991
+ fs.writeFileSync(path$1, contents);
992
+ }
993
+ function escapeRegExp(s) {
994
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
995
+ }
996
+ function readManifest(options, root) {
997
+ if (options.manifest !== void 0) {
998
+ return options.manifest;
999
+ }
1000
+ const rel = options.manifestPath ?? "feature.manifest.json";
1001
+ const abs = path.isAbsolute(rel) ? rel : path.resolve(root, rel);
1002
+ if (!fs.existsSync(abs)) {
1003
+ return null;
1004
+ }
1005
+ const raw = fs.readFileSync(abs, "utf-8");
1006
+ try {
1007
+ return JSON.parse(raw);
1008
+ } catch (e) {
1009
+ throw new Error(
1010
+ `[ethisys-platform-react] Failed to parse manifest at "${abs}": ${e.message}`
1011
+ );
1012
+ }
1013
+ }
1014
+ function makeDefaultBuild(viteBuild) {
1015
+ return async (ctx) => {
1016
+ const build = viteBuild ?? (await import('vite')).build;
1017
+ await build({
1018
+ root: ctx.root,
1019
+ configFile: false,
1020
+ plugins: [ctx.surfacePlugin, ...ctx.plugins, rewriteAliasedExternalImports()],
1021
+ resolve: {
1022
+ dedupe: [...ctx.dedupe],
1023
+ alias: ctx.alias
1024
+ },
1025
+ build: {
1026
+ target: ctx.target,
1027
+ outDir: ctx.outDir,
1028
+ emptyOutDir: false,
1029
+ assetsDir: "",
1030
+ minify: ctx.minify,
1031
+ sourcemap: ctx.sourcemap,
1032
+ rollupOptions: {
1033
+ input: { [ctx.pageId]: ctx.entryId },
1034
+ preserveEntrySignatures: "strict",
1035
+ external: [...ctx.external],
1036
+ output: {
1037
+ format: "es",
1038
+ inlineDynamicImports: true,
1039
+ entryFileNames: `${ctx.outputPrefix}/[name].js`,
1040
+ chunkFileNames: `${ctx.outputPrefix}/[name]-[hash].js`,
1041
+ assetFileNames: `${ctx.outputPrefix}/[name][extname]`
1042
+ }
1043
+ }
1044
+ },
1045
+ logLevel: "warn"
1046
+ });
1047
+ };
1048
+ }
1049
+ async function buildPlatformReactPages(options = {}) {
1050
+ const root = options.root ?? process.cwd();
1051
+ const logger = options.logger ?? console;
1052
+ const manifest = readManifest(options, root);
1053
+ const declared = manifest?.ui?.platformReactPages;
1054
+ if (!Array.isArray(declared) || declared.length === 0) {
1055
+ logger.warn("[build-pages] no platformReactPages declared \u2014 nothing to build");
1056
+ return { pages: [], digests: [], summaryPath: null, digestMapPath: null };
1057
+ }
1058
+ const seen = /* @__PURE__ */ new Set();
1059
+ const pages = declared.map((raw, i) => {
1060
+ const decl = raw;
1061
+ if (typeof decl?.id !== "string" || decl.id.length === 0) {
1062
+ throw new Error(`[build-pages] ui.platformReactPages[${i}].id is required (non-empty string).`);
1063
+ }
1064
+ if (seen.has(decl.id)) {
1065
+ throw new Error(`[build-pages] Duplicate page id "${decl.id}".`);
1066
+ }
1067
+ seen.add(decl.id);
1068
+ if (typeof decl.moduleSpecifier !== "string" || decl.moduleSpecifier.length === 0) {
1069
+ throw new Error(`[build-pages] surface "${decl.id}" has no moduleSpecifier in the manifest.`);
1070
+ }
1071
+ return decl;
1072
+ });
1073
+ const outDir = options.outDir ?? DEFAULT_OUT_DIR;
1074
+ const outDirAbs = path.isAbsolute(outDir) ? outDir : path.resolve(root, outDir);
1075
+ const outputPrefix = (options.outputPrefix ?? DEFAULT_OUTPUT_PREFIX).replace(/^\/+|\/+$/g, "");
1076
+ const outputPrefixDir = path.resolve(outDirAbs, outputPrefix);
1077
+ const external = options.external ?? PLATFORM_REACT_EXTERNALS;
1078
+ const dedupe = options.dedupe ?? PLATFORM_REACT_DEDUPE;
1079
+ const alias = options.alias ?? [];
1080
+ const plugins = options.plugins ?? [];
1081
+ const definePluginPageSpecifier = options.definePluginPageSpecifier ?? DEFAULT_DEFINE_PLUGIN_PAGE;
1082
+ const srcDir = options.srcDir ?? DEFAULT_SRC_DIR;
1083
+ const aliasPrefix = options.aliasPrefix ?? DEFAULT_ALIAS_PREFIX;
1084
+ const srcRe = new RegExp(`^${escapeRegExp(srcDir)}/`);
1085
+ const toAlias = (p) => `${aliasPrefix}/${p.replace(srcRe, "")}`;
1086
+ const write = options.writeFile ?? defaultWriteFile;
1087
+ const read = options.readFile ?? ((p) => fs.readFileSync(p, "utf-8"));
1088
+ const runBuild = options.build ?? makeDefaultBuild(options.viteBuild);
1089
+ if (options.clean ?? true) {
1090
+ if (fs.existsSync(outDirAbs)) {
1091
+ fs.rmSync(outDirAbs, { recursive: true, force: true });
1092
+ }
1093
+ fs.mkdirSync(outputPrefixDir, { recursive: true });
1094
+ }
1095
+ for (const page of pages) {
1096
+ const { id: entryId, plugin: surfacePlugin } = virtualPageEntry(page, {
1097
+ definePluginPageSpecifier,
1098
+ toAlias
1099
+ });
1100
+ logger.log(`[build-pages] ${page.id} \u2190 ${page.moduleSpecifier}`);
1101
+ await runBuild({
1102
+ pageId: page.id,
1103
+ entryId,
1104
+ surfacePlugin,
1105
+ root,
1106
+ outDir: outDirAbs,
1107
+ outputPrefix,
1108
+ external,
1109
+ dedupe,
1110
+ alias,
1111
+ plugins,
1112
+ target: options.target ?? "es2022",
1113
+ minify: options.minify ?? false,
1114
+ sourcemap: options.sourcemap ?? true
1115
+ });
1116
+ }
1117
+ const summaryPages = pages.map((p) => ({
1118
+ id: p.id,
1119
+ exportName: p.exportName ?? "default",
1120
+ title: p.title ?? null,
1121
+ bundlePath: `${outputPrefix}/${p.id}.js`,
1122
+ source: p.moduleSpecifier
1123
+ }));
1124
+ const summaryPath = path.resolve(outputPrefixDir, SUMMARY_FILENAME);
1125
+ write(summaryPath, JSON.stringify({ pages: summaryPages }, null, 2));
1126
+ const digests = pages.map((p) => `${outputPrefix}/${p.id}.js`).sort().map((relPath) => {
1127
+ const code = read(path.resolve(outDirAbs, relPath));
1128
+ return { path: relPath, sha256: crypto.createHash("sha256").update(code, "utf8").digest("hex") };
1129
+ });
1130
+ const digestMapPath = path.resolve(outputPrefixDir, DIGEST_MAP_FILENAME);
1131
+ write(digestMapPath, JSON.stringify({ digests }, null, 2));
1132
+ logger.log(
1133
+ `[build-pages] emitted ${pages.length} page(s) + summary + digest map (${digests.length} digests)`
1134
+ );
1135
+ return { pages: summaryPages, digests, summaryPath, digestMapPath };
1136
+ }
919
1137
  var DEFAULT_MANIFEST = "feature.manifest.json";
920
1138
  var DEFAULT_OUTPUT_DIR = "dist/iframe-sandbox";
921
- var DIGEST_MAP_FILENAME = "iframe-sandbox-digest-map.json";
1139
+ var DIGEST_MAP_FILENAME2 = "iframe-sandbox-digest-map.json";
922
1140
  function slash3(p) {
923
1141
  return path.sep === "\\" ? p.replace(/\\/g, "/") : p;
924
1142
  }
925
- function defaultWriteFile(path$1, contents) {
1143
+ function defaultWriteFile2(path$1, contents) {
926
1144
  fs.mkdirSync(path.dirname(path$1), { recursive: true });
927
1145
  fs.writeFileSync(path$1, contents);
928
1146
  }
@@ -946,7 +1164,7 @@ function digestOf(item) {
946
1164
  const bytes = item.type === "chunk" ? item.code : item.source;
947
1165
  return crypto.createHash("sha256").update(bytes).digest("hex");
948
1166
  }
949
- function readManifest(options, root) {
1167
+ function readManifest2(options, root) {
950
1168
  if (options.manifest !== void 0) {
951
1169
  return options.manifest;
952
1170
  }
@@ -964,7 +1182,7 @@ function readManifest(options, root) {
964
1182
  }
965
1183
  async function buildIframeSandboxPages(options = {}) {
966
1184
  const root = options.root ?? process.cwd();
967
- const manifest = readManifest(options, root);
1185
+ const manifest = readManifest2(options, root);
968
1186
  const declared = manifest?.ui?.iframeSandboxPages;
969
1187
  if (!Array.isArray(declared) || declared.length === 0) {
970
1188
  return { digests: [], digestMapPath: null };
@@ -986,7 +1204,7 @@ async function buildIframeSandboxPages(options = {}) {
986
1204
  seen.add(p.id);
987
1205
  }
988
1206
  const build = options.build ?? defaultBuild;
989
- const write = options.writeFile ?? defaultWriteFile;
1207
+ const write = options.writeFile ?? defaultWriteFile2;
990
1208
  const outputDir = options.outputDir ?? DEFAULT_OUTPUT_DIR;
991
1209
  const outDirAbs = path.isAbsolute(outputDir) ? outputDir : path.resolve(root, outputDir);
992
1210
  const digests = [];
@@ -1004,7 +1222,7 @@ async function buildIframeSandboxPages(options = {}) {
1004
1222
  digests.push(entry);
1005
1223
  }
1006
1224
  }
1007
- const digestMapPath = path.resolve(outDirAbs, DIGEST_MAP_FILENAME);
1225
+ const digestMapPath = path.resolve(outDirAbs, DIGEST_MAP_FILENAME2);
1008
1226
  write(slash3(digestMapPath), JSON.stringify({ digests }, null, 2));
1009
1227
  return { digests, digestMapPath };
1010
1228
  }
@@ -1084,7 +1302,7 @@ function ethisysManifestPlugin(options = {}) {
1084
1302
  </body>
1085
1303
  </html>`;
1086
1304
  }
1087
- function readManifest2() {
1305
+ function readManifest3() {
1088
1306
  if (!fs.existsSync(manifestAbsPath)) {
1089
1307
  return [];
1090
1308
  }
@@ -1136,7 +1354,7 @@ function ethisysManifestPlugin(options = {}) {
1136
1354
  config(config, { command }) {
1137
1355
  rootDir = config.root ?? process.cwd();
1138
1356
  manifestAbsPath = path.resolve(rootDir, manifestRelPath);
1139
- entries = readManifest2();
1357
+ entries = readManifest3();
1140
1358
  if (entries.length === 0) {
1141
1359
  return;
1142
1360
  }
@@ -1217,7 +1435,7 @@ function ethisysManifestPlugin(options = {}) {
1217
1435
  handleHotUpdate({ file, server }) {
1218
1436
  if (slash4(file) === slash4(manifestAbsPath)) {
1219
1437
  try {
1220
- entries = readManifest2();
1438
+ entries = readManifest3();
1221
1439
  validateEntries();
1222
1440
  htmlCache.clear();
1223
1441
  } catch (e) {
@@ -1257,14 +1475,19 @@ function ethisysManifestPlugin(options = {}) {
1257
1475
  exports.CONTRACT_B_IMPORT_MAP_ALLOWLIST = CONTRACT_B_IMPORT_MAP_ALLOWLIST;
1258
1476
  exports.CONTRACT_B_RUNTIME_IMPORTS = CONTRACT_B_RUNTIME_IMPORTS;
1259
1477
  exports.CONTRACT_B_SEMANTIC_PRIMITIVES = CONTRACT_B_SEMANTIC_PRIMITIVES;
1478
+ exports.PLATFORM_REACT_DEDUPE = PLATFORM_REACT_DEDUPE;
1479
+ exports.PLATFORM_REACT_EXTERNALS = PLATFORM_REACT_EXTERNALS;
1260
1480
  exports.buildIframeSandboxPages = buildIframeSandboxPages;
1481
+ exports.buildPlatformReactPages = buildPlatformReactPages;
1261
1482
  exports.ethisysContractAPlugin = ethisysContractAPlugin;
1262
1483
  exports.ethisysContractBPlugin = ethisysContractBPlugin;
1263
1484
  exports.ethisysIframeSandboxPlugin = ethisysIframeSandboxPlugin;
1264
1485
  exports.ethisysManifestPlugin = ethisysManifestPlugin;
1265
1486
  exports.ethisysPlatformReactPlugin = ethisysPlatformReactPlugin;
1266
1487
  exports.parsePlatformReactPages = parsePlatformReactPages;
1488
+ exports.rewriteAliasedExternalImports = rewriteAliasedExternalImports;
1267
1489
  exports.validateDeclarativeResource = validateDeclarativeResource;
1268
1490
  exports.validateReactiveRule = validateReactiveRule;
1491
+ exports.virtualPageEntry = virtualPageEntry;
1269
1492
  //# sourceMappingURL=index.cjs.map
1270
1493
  //# sourceMappingURL=index.cjs.map