@ethisyscore/vite-plugin 1.9.2 → 1.11.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
@@ -352,6 +352,74 @@ interface ParsePlatformReactPagesOptions {
352
352
  */
353
353
  declare function parsePlatformReactPages(manifestPath: string, options?: ParsePlatformReactPagesOptions): ResolvedPlatformReactPage[];
354
354
 
355
+ /** One emitted artifact from a per-page Vite sub-build. */
356
+ type IframeBuildOutputItem = {
357
+ type: "chunk";
358
+ fileName: string;
359
+ code: string;
360
+ } | {
361
+ type: "asset";
362
+ fileName: string;
363
+ source: string | Uint8Array;
364
+ };
365
+ interface IframeBuildResult {
366
+ output: IframeBuildOutputItem[];
367
+ }
368
+ /** A single page handed to the (injectable) builder. */
369
+ interface IframeBuildContext {
370
+ id: string;
371
+ title: string;
372
+ entryPath: string;
373
+ root: string;
374
+ /** Per-page output directory (`<outputDir>/<id>`). */
375
+ outDir: string;
376
+ }
377
+ /** Injectable per-page builder. Defaults to a real Vite library build. */
378
+ type IframeViteBuild = (page: IframeBuildContext) => Promise<IframeBuildResult>;
379
+ interface IframeSandboxPluginOptions {
380
+ /** Root the manifest + entry paths resolve against. Defaults to Vite's resolved root / cwd. */
381
+ root?: string;
382
+ /** Manifest path (relative to `root`). Default `feature.manifest.json`. */
383
+ manifestPath?: string;
384
+ /** Output directory for per-page bundles + the digest map. Default `dist/iframe-sandbox`. */
385
+ outputDir?: string;
386
+ /** Inline manifest object (test injection). When omitted, the manifest is read from disk. */
387
+ manifest?: unknown;
388
+ /** Injectable per-page builder (test injection). When omitted, a real Vite build runs. */
389
+ build?: IframeViteBuild;
390
+ /** Injectable file writer (test injection). When omitted, writes via `fs` (creating dirs). */
391
+ writeFile?: (path: string, contents: string) => void;
392
+ }
393
+ interface IframeSandboxBuildSummary {
394
+ digests: Array<{
395
+ path: string;
396
+ sha256: string;
397
+ }>;
398
+ digestMapPath: string | null;
399
+ }
400
+ /**
401
+ * Build each `ui.iframeSandboxPages[]` declaration as its own Vite app bundle and
402
+ * emit a per-asset SHA-256 digest map in the SAME shape `ethisysPlatformReactPlugin`
403
+ * produces (`{ digests: [{ path, sha256 }] }`). Tier U surfaces are independent
404
+ * cross-origin apps, so each page is a separate sub-build under `<outputDir>/<id>/`;
405
+ * every emitted artifact is hashed (and validated against the protocol `AssetDigest`
406
+ * schema) so the edge integrity endpoint (sub-plan 5, Task 6) can verify served bytes.
407
+ *
408
+ * No-op when no pages are declared. Page shape is validated by the protocol
409
+ * `IframeSandboxPageDeclaration` schema (a malformed entry rejects the build).
410
+ */
411
+ declare function buildIframeSandboxPages(options?: IframeSandboxPluginOptions): Promise<IframeSandboxBuildSummary>;
412
+ /**
413
+ * Tier U (iframe-sandbox) Vite build pass (WI 4858 sub-plan 5). Mirrors
414
+ * `ethisysPlatformReactPlugin`: keyed off `ui.iframeSandboxPages[]` and a no-op
415
+ * when absent, so a single Vite config can compose every render-mode pass.
416
+ *
417
+ * Unlike Tier T (ESM modules in the parent build), each Tier U page is an
418
+ * independent cross-origin app — so the pass runs a separate Vite sub-build per
419
+ * page in `closeBundle` and emits the integrity digest map the host verifies.
420
+ */
421
+ declare function ethisysIframeSandboxPlugin(options?: IframeSandboxPluginOptions): Plugin;
422
+
355
423
  interface EthisysPluginOptions {
356
424
  /**
357
425
  * Path to the manifest file, relative to Vite's root directory.
@@ -375,4 +443,4 @@ interface EthisysPluginOptions {
375
443
  */
376
444
  declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
377
445
 
378
- export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, ethisysContractAPlugin, ethisysContractBPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
446
+ export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, buildIframeSandboxPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
package/dist/index.d.ts CHANGED
@@ -352,6 +352,74 @@ interface ParsePlatformReactPagesOptions {
352
352
  */
353
353
  declare function parsePlatformReactPages(manifestPath: string, options?: ParsePlatformReactPagesOptions): ResolvedPlatformReactPage[];
354
354
 
355
+ /** One emitted artifact from a per-page Vite sub-build. */
356
+ type IframeBuildOutputItem = {
357
+ type: "chunk";
358
+ fileName: string;
359
+ code: string;
360
+ } | {
361
+ type: "asset";
362
+ fileName: string;
363
+ source: string | Uint8Array;
364
+ };
365
+ interface IframeBuildResult {
366
+ output: IframeBuildOutputItem[];
367
+ }
368
+ /** A single page handed to the (injectable) builder. */
369
+ interface IframeBuildContext {
370
+ id: string;
371
+ title: string;
372
+ entryPath: string;
373
+ root: string;
374
+ /** Per-page output directory (`<outputDir>/<id>`). */
375
+ outDir: string;
376
+ }
377
+ /** Injectable per-page builder. Defaults to a real Vite library build. */
378
+ type IframeViteBuild = (page: IframeBuildContext) => Promise<IframeBuildResult>;
379
+ interface IframeSandboxPluginOptions {
380
+ /** Root the manifest + entry paths resolve against. Defaults to Vite's resolved root / cwd. */
381
+ root?: string;
382
+ /** Manifest path (relative to `root`). Default `feature.manifest.json`. */
383
+ manifestPath?: string;
384
+ /** Output directory for per-page bundles + the digest map. Default `dist/iframe-sandbox`. */
385
+ outputDir?: string;
386
+ /** Inline manifest object (test injection). When omitted, the manifest is read from disk. */
387
+ manifest?: unknown;
388
+ /** Injectable per-page builder (test injection). When omitted, a real Vite build runs. */
389
+ build?: IframeViteBuild;
390
+ /** Injectable file writer (test injection). When omitted, writes via `fs` (creating dirs). */
391
+ writeFile?: (path: string, contents: string) => void;
392
+ }
393
+ interface IframeSandboxBuildSummary {
394
+ digests: Array<{
395
+ path: string;
396
+ sha256: string;
397
+ }>;
398
+ digestMapPath: string | null;
399
+ }
400
+ /**
401
+ * Build each `ui.iframeSandboxPages[]` declaration as its own Vite app bundle and
402
+ * emit a per-asset SHA-256 digest map in the SAME shape `ethisysPlatformReactPlugin`
403
+ * produces (`{ digests: [{ path, sha256 }] }`). Tier U surfaces are independent
404
+ * cross-origin apps, so each page is a separate sub-build under `<outputDir>/<id>/`;
405
+ * every emitted artifact is hashed (and validated against the protocol `AssetDigest`
406
+ * schema) so the edge integrity endpoint (sub-plan 5, Task 6) can verify served bytes.
407
+ *
408
+ * No-op when no pages are declared. Page shape is validated by the protocol
409
+ * `IframeSandboxPageDeclaration` schema (a malformed entry rejects the build).
410
+ */
411
+ declare function buildIframeSandboxPages(options?: IframeSandboxPluginOptions): Promise<IframeSandboxBuildSummary>;
412
+ /**
413
+ * Tier U (iframe-sandbox) Vite build pass (WI 4858 sub-plan 5). Mirrors
414
+ * `ethisysPlatformReactPlugin`: keyed off `ui.iframeSandboxPages[]` and a no-op
415
+ * when absent, so a single Vite config can compose every render-mode pass.
416
+ *
417
+ * Unlike Tier T (ESM modules in the parent build), each Tier U page is an
418
+ * independent cross-origin app — so the pass runs a separate Vite sub-build per
419
+ * page in `closeBundle` and emits the integrity digest map the host verifies.
420
+ */
421
+ declare function ethisysIframeSandboxPlugin(options?: IframeSandboxPluginOptions): Plugin;
422
+
355
423
  interface EthisysPluginOptions {
356
424
  /**
357
425
  * Path to the manifest file, relative to Vite's root directory.
@@ -375,4 +443,4 @@ interface EthisysPluginOptions {
375
443
  */
376
444
  declare function ethisysManifestPlugin(options?: EthisysPluginOptions): Plugin;
377
445
 
378
- export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, ethisysContractAPlugin, ethisysContractBPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
446
+ export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, type ContractAManifest, type ContractAPluginOptions, type ContractBManifest, type ContractBPluginOptions, type EthisysPluginOptions, type IframeBuildContext, type IframeBuildOutputItem, type IframeBuildResult, type IframeSandboxBuildSummary, type IframeSandboxPluginOptions, type IframeViteBuild, type ManifestReactiveRuleRef, type ManifestResourceRef, type ParsePlatformReactPagesOptions, type PlatformReactManifest, type PlatformReactPageDeclaration, type PlatformReactPluginOptions, type ResolvedPlatformReactPage, type ValidationFailure, type ValidationResult, buildIframeSandboxPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
- import { existsSync, readFileSync } from 'fs';
2
- import { isAbsolute, resolve, sep, normalize } from 'path';
3
- import { KNOWN_PRIMITIVES, KNOWN_OPERATORS, KNOWN_RULE_KINDS, SduiNode, ReactiveRule } from '@ethisyscore/protocol';
1
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
2
+ import { isAbsolute, resolve, sep, normalize, dirname } from 'path';
3
+ import { KNOWN_PRIMITIVES, KNOWN_OPERATORS, KNOWN_RULE_KINDS, SduiNode, ReactiveRule, IframeSandboxPageDeclaration, AssetDigest } from '@ethisyscore/protocol';
4
+ import { createHash } from 'crypto';
4
5
 
5
6
  // src/index.ts
6
7
  var KNOWN_PRIMITIVE_SET = new Set(KNOWN_PRIMITIVES);
@@ -121,7 +122,7 @@ function ethisysContractAPlugin(options = {}) {
121
122
  manifestAbsPath = isAbsolute(manifestRel) ? manifestRel : resolve(resolvedRoot, manifestRel);
122
123
  return resolvedRoot;
123
124
  }
124
- function readManifest() {
125
+ function readManifest2() {
125
126
  resolveRoot();
126
127
  if (!existsSync(manifestAbsPath)) {
127
128
  return null;
@@ -138,7 +139,7 @@ function ethisysContractAPlugin(options = {}) {
138
139
  function validate() {
139
140
  validatedResources = [];
140
141
  resourcePayloads.clear();
141
- const manifest = readManifest();
142
+ const manifest = readManifest2();
142
143
  if (manifest === null) {
143
144
  return;
144
145
  }
@@ -384,7 +385,7 @@ function ethisysContractBPlugin(options = {}) {
384
385
  manifestAbsPath = isAbsolute(manifestRel) ? manifestRel : resolve(resolvedRoot, manifestRel);
385
386
  return resolvedRoot;
386
387
  }
387
- function readManifest() {
388
+ function readManifest2() {
388
389
  resolveRoot();
389
390
  if (!existsSync(manifestAbsPath)) {
390
391
  return null;
@@ -401,7 +402,7 @@ function ethisysContractBPlugin(options = {}) {
401
402
  function validate() {
402
403
  workerEntryAbs = null;
403
404
  workerEntryRel = null;
404
- const manifest = readManifest();
405
+ const manifest = readManifest2();
405
406
  if (manifest === null) {
406
407
  return;
407
408
  }
@@ -632,7 +633,7 @@ function ethisysPlatformReactPlugin(options = {}) {
632
633
  manifestAbsPath = isAbsolute(manifestRel) ? manifestRel : resolve(resolvedRoot, manifestRel);
633
634
  return resolvedRoot;
634
635
  }
635
- function readManifest() {
636
+ function readManifest2() {
636
637
  resolveRoot();
637
638
  if (!existsSync(manifestAbsPath)) {
638
639
  return null;
@@ -648,7 +649,7 @@ function ethisysPlatformReactPlugin(options = {}) {
648
649
  }
649
650
  function validate() {
650
651
  pages = [];
651
- const manifest = readManifest();
652
+ const manifest = readManifest2();
652
653
  if (manifest === null) {
653
654
  return;
654
655
  }
@@ -727,7 +728,11 @@ function ethisysPlatformReactPlugin(options = {}) {
727
728
  entryFileNames: `${outputPrefix}[name].js`,
728
729
  chunkFileNames: `${outputPrefix}[name]-[hash].js`,
729
730
  assetFileNames: `${outputPrefix}[name][extname]`
730
- }
731
+ },
732
+ // Auto-externalise the host-ui-externals specifier so the host's
733
+ // module-registry rewriter resolves it to the live `@coreconnect/gogo-ui`
734
+ // instance at runtime — Tier T remotes never ship their own Gogo copy.
735
+ external: ["@ethisyscore/host-ui-externals"]
731
736
  }
732
737
  }
733
738
  };
@@ -785,10 +790,20 @@ function ethisysPlatformReactPlugin(options = {}) {
785
790
  * this file to discover which page modules ship in the bundle without
786
791
  * having to re-parse the manifest.
787
792
  */
788
- generateBundle() {
793
+ generateBundle(_options, bundle) {
789
794
  if (pages.length === 0) {
790
795
  return;
791
796
  }
797
+ const digests = [];
798
+ for (const chunk of Object.values(bundle ?? {})) {
799
+ if (chunk.type !== "chunk") {
800
+ continue;
801
+ }
802
+ const code = chunk.code;
803
+ const fileName = chunk.fileName;
804
+ const hash = createHash("sha256").update(code, "utf8").digest("hex");
805
+ digests.push({ path: fileName, sha256: hash });
806
+ }
792
807
  const summary = {
793
808
  pages: pages.map((p) => ({
794
809
  id: p.id,
@@ -803,6 +818,11 @@ function ethisysPlatformReactPlugin(options = {}) {
803
818
  fileName: `${outputPrefix}platform-react-pages.json`,
804
819
  source: JSON.stringify(summary, null, 2)
805
820
  });
821
+ this.emitFile({
822
+ type: "asset",
823
+ fileName: `${outputPrefix}platform-react-digest-map.json`,
824
+ source: JSON.stringify({ digests }, null, 2)
825
+ });
806
826
  }
807
827
  };
808
828
  }
@@ -894,9 +914,116 @@ function parsePlatformReactPages(manifestPath, options = {}) {
894
914
  }
895
915
  return result;
896
916
  }
917
+ var DEFAULT_MANIFEST = "feature.manifest.json";
918
+ var DEFAULT_OUTPUT_DIR = "dist/iframe-sandbox";
919
+ var DIGEST_MAP_FILENAME = "iframe-sandbox-digest-map.json";
920
+ function slash3(p) {
921
+ return sep === "\\" ? p.replace(/\\/g, "/") : p;
922
+ }
923
+ function defaultWriteFile(path, contents) {
924
+ mkdirSync(dirname(path), { recursive: true });
925
+ writeFileSync(path, contents);
926
+ }
927
+ var defaultBuild = async (page) => {
928
+ const { build } = await import('vite');
929
+ const result = await build({
930
+ root: page.root,
931
+ logLevel: "warn",
932
+ build: {
933
+ outDir: page.outDir,
934
+ emptyOutDir: true,
935
+ rollupOptions: {
936
+ input: resolve(page.root, page.entryPath)
937
+ }
938
+ }
939
+ });
940
+ const out = Array.isArray(result) ? result[0] : result;
941
+ return { output: out.output };
942
+ };
943
+ function digestOf(item) {
944
+ const bytes = item.type === "chunk" ? item.code : item.source;
945
+ return createHash("sha256").update(bytes).digest("hex");
946
+ }
947
+ function readManifest(options, root) {
948
+ if (options.manifest !== void 0) {
949
+ return options.manifest;
950
+ }
951
+ const rel = options.manifestPath ?? DEFAULT_MANIFEST;
952
+ const abs = isAbsolute(rel) ? rel : resolve(root, rel);
953
+ if (!existsSync(abs)) {
954
+ return null;
955
+ }
956
+ const raw = readFileSync(abs, "utf8");
957
+ try {
958
+ return JSON.parse(raw);
959
+ } catch (e) {
960
+ throw new Error(`[ethisys-iframe-sandbox] Failed to parse manifest at "${abs}": ${e.message}`);
961
+ }
962
+ }
963
+ async function buildIframeSandboxPages(options = {}) {
964
+ const root = options.root ?? process.cwd();
965
+ const manifest = readManifest(options, root);
966
+ const declared = manifest?.ui?.iframeSandboxPages;
967
+ if (!Array.isArray(declared) || declared.length === 0) {
968
+ return { digests: [], digestMapPath: null };
969
+ }
970
+ const pages = declared.map((raw, i) => {
971
+ try {
972
+ return IframeSandboxPageDeclaration.parse(raw);
973
+ } catch (e) {
974
+ throw new Error(
975
+ `[ethisys-iframe-sandbox] ui.iframeSandboxPages[${i}] is invalid: ${e.message}`
976
+ );
977
+ }
978
+ });
979
+ const seen = /* @__PURE__ */ new Set();
980
+ for (const p of pages) {
981
+ if (seen.has(p.id)) {
982
+ throw new Error(`[ethisys-iframe-sandbox] Duplicate iframe-sandbox page id "${p.id}".`);
983
+ }
984
+ seen.add(p.id);
985
+ }
986
+ const build = options.build ?? defaultBuild;
987
+ const write = options.writeFile ?? defaultWriteFile;
988
+ const outputDir = options.outputDir ?? DEFAULT_OUTPUT_DIR;
989
+ const outDirAbs = isAbsolute(outputDir) ? outputDir : resolve(root, outputDir);
990
+ const digests = [];
991
+ for (const page of pages) {
992
+ const result = await build({
993
+ id: page.id,
994
+ title: page.title,
995
+ entryPath: page.entryPath,
996
+ root,
997
+ outDir: resolve(outDirAbs, page.id)
998
+ });
999
+ for (const item of result.output) {
1000
+ const entry = { path: `${page.id}/${item.fileName}`, sha256: digestOf(item) };
1001
+ AssetDigest.parse(entry);
1002
+ digests.push(entry);
1003
+ }
1004
+ }
1005
+ const digestMapPath = resolve(outDirAbs, DIGEST_MAP_FILENAME);
1006
+ write(slash3(digestMapPath), JSON.stringify({ digests }, null, 2));
1007
+ return { digests, digestMapPath };
1008
+ }
1009
+ function ethisysIframeSandboxPlugin(options = {}) {
1010
+ let resolvedRoot = options.root;
1011
+ return {
1012
+ name: "ethisys-iframe-sandbox",
1013
+ enforce: "pre",
1014
+ configResolved(config) {
1015
+ if (!options.root) {
1016
+ resolvedRoot = config.root;
1017
+ }
1018
+ },
1019
+ async closeBundle() {
1020
+ await buildIframeSandboxPages({ ...options, root: options.root ?? resolvedRoot });
1021
+ }
1022
+ };
1023
+ }
897
1024
 
898
1025
  // src/index.ts
899
- function slash3(p) {
1026
+ function slash4(p) {
900
1027
  return sep === "\\" ? p.replace(/\\/g, "/") : p;
901
1028
  }
902
1029
  function escapeHtml(str) {
@@ -955,7 +1082,7 @@ function ethisysManifestPlugin(options = {}) {
955
1082
  </body>
956
1083
  </html>`;
957
1084
  }
958
- function readManifest() {
1085
+ function readManifest2() {
959
1086
  if (!existsSync(manifestAbsPath)) {
960
1087
  return [];
961
1088
  }
@@ -1007,7 +1134,7 @@ function ethisysManifestPlugin(options = {}) {
1007
1134
  config(config, { command }) {
1008
1135
  rootDir = config.root ?? process.cwd();
1009
1136
  manifestAbsPath = resolve(rootDir, manifestRelPath);
1010
- entries = readManifest();
1137
+ entries = readManifest2();
1011
1138
  if (entries.length === 0) {
1012
1139
  return;
1013
1140
  }
@@ -1021,7 +1148,7 @@ function ethisysManifestPlugin(options = {}) {
1021
1148
  }
1022
1149
  seen.add(entry.entrypoint);
1023
1150
  const name = entry.entrypoint.replace(/\.html$/, "");
1024
- input[name] = slash3(resolve(rootDir, entry.entrypoint));
1151
+ input[name] = slash4(resolve(rootDir, entry.entrypoint));
1025
1152
  }
1026
1153
  return {
1027
1154
  build: {
@@ -1086,9 +1213,9 @@ function ethisysManifestPlugin(options = {}) {
1086
1213
  // Entire handler is wrapped in try/catch so JSON syntax errors in the
1087
1214
  // manifest don't crash the dev server (common during active editing).
1088
1215
  handleHotUpdate({ file, server }) {
1089
- if (slash3(file) === slash3(manifestAbsPath)) {
1216
+ if (slash4(file) === slash4(manifestAbsPath)) {
1090
1217
  try {
1091
- entries = readManifest();
1218
+ entries = readManifest2();
1092
1219
  validateEntries();
1093
1220
  htmlCache.clear();
1094
1221
  } catch (e) {
@@ -1104,9 +1231,9 @@ function ethisysManifestPlugin(options = {}) {
1104
1231
  },
1105
1232
  // Build: resolve virtual HTML module IDs (no physical files exist on disk)
1106
1233
  resolveId(id) {
1107
- const normalizedId = slash3(id);
1234
+ const normalizedId = slash4(id);
1108
1235
  const match = entries.find(
1109
- (e) => slash3(resolve(rootDir, e.entrypoint)) === normalizedId
1236
+ (e) => slash4(resolve(rootDir, e.entrypoint)) === normalizedId
1110
1237
  );
1111
1238
  if (match) {
1112
1239
  return id;
@@ -1114,9 +1241,9 @@ function ethisysManifestPlugin(options = {}) {
1114
1241
  },
1115
1242
  // Build: provide virtual HTML content for Rollup
1116
1243
  load(id) {
1117
- const normalizedId = slash3(id);
1244
+ const normalizedId = slash4(id);
1118
1245
  const match = entries.find(
1119
- (e) => slash3(resolve(rootDir, e.entrypoint)) === normalizedId
1246
+ (e) => slash4(resolve(rootDir, e.entrypoint)) === normalizedId
1120
1247
  );
1121
1248
  if (match) {
1122
1249
  return generateHtml(match);
@@ -1125,6 +1252,6 @@ function ethisysManifestPlugin(options = {}) {
1125
1252
  };
1126
1253
  }
1127
1254
 
1128
- export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, ethisysContractAPlugin, ethisysContractBPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
1255
+ export { CONTRACT_B_IMPORT_MAP_ALLOWLIST, CONTRACT_B_RUNTIME_IMPORTS, CONTRACT_B_SEMANTIC_PRIMITIVES, buildIframeSandboxPages, ethisysContractAPlugin, ethisysContractBPlugin, ethisysIframeSandboxPlugin, ethisysManifestPlugin, ethisysPlatformReactPlugin, parsePlatformReactPages, validateDeclarativeResource, validateReactiveRule };
1129
1256
  //# sourceMappingURL=index.js.map
1130
1257
  //# sourceMappingURL=index.js.map