@aprovan/patchwork-compiler 0.1.2-dev.ba8f277 → 0.1.2-dev.c1ac1dc

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
@@ -49,8 +49,8 @@ __export(index_exports, {
49
49
  cdnTransformPlugin: () => cdnTransformPlugin,
50
50
  createCompiler: () => createCompiler,
51
51
  createFieldAccessProxy: () => createFieldAccessProxy,
52
- createHttpServiceProxy: () => createHttpServiceProxy,
53
- createIframeServiceProxy: () => createIframeServiceProxy,
52
+ createHttpProxy: () => createHttpProxy,
53
+ createIframeProxy: () => createIframeProxy,
54
54
  createImageRegistry: () => createImageRegistry,
55
55
  createProjectFromFiles: () => createProjectFromFiles,
56
56
  createSingleFileProject: () => createSingleFileProject,
@@ -81,55 +81,13 @@ __export(index_exports, {
81
81
  });
82
82
  module.exports = __toCommonJS(index_exports);
83
83
 
84
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
84
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.15_tsx@4.22.4_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
85
85
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
86
86
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
87
87
 
88
88
  // src/compiler.ts
89
89
  var esbuild = __toESM(require("esbuild-wasm"), 1);
90
90
 
91
- // src/vfs/project.ts
92
- function createProjectFromFiles(files, id = crypto.randomUUID()) {
93
- const fileMap = /* @__PURE__ */ new Map();
94
- for (const file of files) {
95
- fileMap.set(file.path, file);
96
- }
97
- return { id, entry: resolveEntry(fileMap), files: fileMap };
98
- }
99
- function resolveEntry(files) {
100
- const paths = Array.from(files.keys());
101
- const mainFile = paths.find((p) => /\bmain\.(tsx?|jsx?)$/.test(p));
102
- if (mainFile) return mainFile;
103
- const indexFile = paths.find((p) => /\bindex\.(tsx?|jsx?)$/.test(p));
104
- if (indexFile) return indexFile;
105
- const firstTsx = paths.find((p) => /\.(tsx|jsx)$/.test(p));
106
- if (firstTsx) return firstTsx;
107
- return paths[0] || "main.tsx";
108
- }
109
- function detectMainFile(language) {
110
- switch (language) {
111
- case "tsx":
112
- case "typescript":
113
- return "main.tsx";
114
- case "jsx":
115
- case "javascript":
116
- return "main.jsx";
117
- case "ts":
118
- return "main.ts";
119
- case "js":
120
- return "main.js";
121
- default:
122
- return "main.tsx";
123
- }
124
- }
125
- function createSingleFileProject(content, entry = "main.tsx", id = "inline") {
126
- return {
127
- id,
128
- entry,
129
- files: /* @__PURE__ */ new Map([[entry, { path: entry, content }]])
130
- };
131
- }
132
-
133
91
  // src/schemas.ts
134
92
  var import_zod = require("zod");
135
93
  var PlatformSchema = import_zod.z.enum(["browser", "cli"]);
@@ -420,381 +378,23 @@ var ImageRegistry = class {
420
378
  getLoadedNames() {
421
379
  return Array.from(this.images.keys());
422
380
  }
423
- };
424
- var globalRegistry = null;
425
- function getImageRegistry() {
426
- if (!globalRegistry) {
427
- globalRegistry = new ImageRegistry();
428
- }
429
- return globalRegistry;
430
- }
431
- function createImageRegistry() {
432
- return new ImageRegistry();
433
- }
434
-
435
- // src/transforms/cdn.ts
436
- var DEFAULT_CDN_BASE2 = "https://esm.sh";
437
- var cdnBaseUrl2 = DEFAULT_CDN_BASE2;
438
- function setCdnBaseUrl2(url) {
439
- cdnBaseUrl2 = url;
440
- }
441
- var EXTERNAL_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom", "ink"]);
442
- var NODE_BUILTINS = /* @__PURE__ */ new Set([
443
- "assert",
444
- "buffer",
445
- "child_process",
446
- "cluster",
447
- "crypto",
448
- "dgram",
449
- "dns",
450
- "events",
451
- "fs",
452
- "http",
453
- "http2",
454
- "https",
455
- "net",
456
- "os",
457
- "path",
458
- "perf_hooks",
459
- "process",
460
- "querystring",
461
- "readline",
462
- "stream",
463
- "string_decoder",
464
- "timers",
465
- "tls",
466
- "tty",
467
- "url",
468
- "util",
469
- "v8",
470
- "vm",
471
- "worker_threads",
472
- "zlib"
473
- ]);
474
- function toEsmShUrl(packageName, version, subpath, deps) {
475
- let url = `${cdnBaseUrl2}/${packageName}`;
476
- if (version) {
477
- url += `@${version}`;
478
- }
479
- if (subpath) {
480
- url += `/${subpath}`;
481
- }
482
- if (deps && Object.keys(deps).length > 0) {
483
- const depsStr = Object.entries(deps).map(([name, ver]) => `${name}@${ver}`).join(",");
484
- url += `?deps=${depsStr}`;
485
- }
486
- return url;
487
- }
488
- function isBareImport(path) {
489
- if (path.startsWith(".") || path.startsWith("/") || path.startsWith("http://") || path.startsWith("https://")) {
490
- return false;
491
- }
492
- return true;
493
- }
494
- function parseImportPath(importPath) {
495
- if (importPath.startsWith("@")) {
496
- const parts2 = importPath.split("/");
497
- if (parts2.length >= 2) {
498
- const packageName2 = `${parts2[0]}/${parts2[1]}`;
499
- const subpath2 = parts2.slice(2).join("/");
500
- return { packageName: packageName2, subpath: subpath2 || void 0 };
501
- }
502
- }
503
- const parts = importPath.split("/");
504
- const packageName = parts[0];
505
- const subpath = parts.slice(1).join("/");
506
- return { packageName, subpath: subpath || void 0 };
507
- }
508
- function matchAlias(importPath, aliases) {
509
- for (const [pattern, target] of Object.entries(aliases)) {
510
- if (pattern.endsWith("/*")) {
511
- const prefix = pattern.slice(0, -2);
512
- if (importPath === prefix || importPath.startsWith(prefix + "/")) {
513
- return target;
514
- }
515
- }
516
- if (importPath === pattern) {
517
- return target;
518
- }
519
- }
520
- return null;
521
- }
522
- function cdnTransformPlugin(options = {}) {
523
- const {
524
- packages = {},
525
- external = [],
526
- bundle = false,
527
- globals = {},
528
- deps = {},
529
- aliases = {}
530
- } = options;
531
- const externalSet = /* @__PURE__ */ new Set([...EXTERNAL_PACKAGES, ...external]);
532
- const globalsSet = new Set(Object.keys(globals));
533
- return {
534
- name: "cdn-transform",
535
- setup(build2) {
536
- build2.onResolve({ filter: /.*/ }, (args) => {
537
- const aliasTarget = matchAlias(args.path, aliases);
538
- if (aliasTarget) {
539
- const { packageName, subpath } = parseImportPath(aliasTarget);
540
- if (globalsSet.has(packageName)) {
541
- return {
542
- path: aliasTarget,
543
- namespace: "global-inject"
544
- };
545
- }
546
- const version = packages[packageName];
547
- let url = toEsmShUrl(
548
- packageName,
549
- version,
550
- subpath,
551
- Object.keys(deps).length > 0 ? deps : void 0
552
- );
553
- if (bundle) {
554
- url += url.includes("?") ? "&bundle" : "?bundle";
555
- }
556
- return {
557
- path: url,
558
- external: true
559
- };
560
- }
561
- return null;
562
- });
563
- build2.onResolve({ filter: /.*/ }, (args) => {
564
- if (!isBareImport(args.path)) {
565
- return null;
566
- }
567
- const { packageName } = parseImportPath(args.path);
568
- if (globalsSet.has(packageName)) {
569
- return {
570
- path: args.path,
571
- namespace: "global-inject"
572
- };
573
- }
574
- return null;
575
- });
576
- build2.onLoad({ filter: /.*/, namespace: "global-inject" }, (args) => {
577
- const { packageName, subpath } = parseImportPath(args.path);
578
- const globalName = globals[packageName];
579
- if (!globalName) return null;
580
- if (subpath) {
581
- return {
582
- contents: `export * from '${packageName}'; export { default } from '${packageName}';`,
583
- loader: "js"
584
- };
585
- }
586
- const contents = `
587
- const mod = window.${globalName};
588
- export default mod;
589
- // Re-export all properties as named exports
590
- const { ${getCommonExports(packageName).join(", ")} } = mod;
591
- export { ${getCommonExports(packageName).join(", ")} };
592
- `;
593
- return {
594
- contents,
595
- loader: "js"
596
- };
597
- });
598
- build2.onResolve({ filter: /.*/ }, (args) => {
599
- if (!isBareImport(args.path)) {
600
- return null;
601
- }
602
- if (NODE_BUILTINS.has(args.path)) {
603
- return { external: true };
604
- }
605
- const { packageName, subpath } = parseImportPath(args.path);
606
- if (globalsSet.has(packageName)) {
607
- return null;
608
- }
609
- if (externalSet.has(packageName)) {
610
- return { external: true };
611
- }
612
- const version = packages[packageName];
613
- let url = toEsmShUrl(
614
- packageName,
615
- version,
616
- subpath,
617
- Object.keys(deps).length > 0 ? deps : void 0
618
- );
619
- if (bundle) {
620
- url += url.includes("?") ? "&bundle" : "?bundle";
621
- }
622
- return {
623
- path: url,
624
- external: true
625
- };
626
- });
627
- }
628
- };
629
- }
630
- function getCommonExports(packageName) {
631
- const exports2 = {
632
- react: [
633
- "useState",
634
- "useEffect",
635
- "useCallback",
636
- "useMemo",
637
- "useRef",
638
- "useContext",
639
- "useReducer",
640
- "useLayoutEffect",
641
- "useId",
642
- "createContext",
643
- "createElement",
644
- "cloneElement",
645
- "createRef",
646
- "forwardRef",
647
- "lazy",
648
- "memo",
649
- "Fragment",
650
- "Suspense",
651
- "StrictMode",
652
- "Component",
653
- "PureComponent",
654
- "Children",
655
- "isValidElement"
656
- ],
657
- "react-dom": [
658
- "createPortal",
659
- "flushSync",
660
- "render",
661
- "hydrate",
662
- "unmountComponentAtNode"
663
- ]
664
- };
665
- return exports2[packageName] || [];
666
- }
667
- function generateImportMap(packages) {
668
- const imports = {};
669
- for (const [name, version] of Object.entries(packages)) {
670
- imports[name] = toEsmShUrl(name, version);
671
- }
672
- return imports;
673
- }
674
-
675
- // src/transforms/vfs.ts
676
- function dirname(path) {
677
- const idx = path.lastIndexOf("/");
678
- return idx === -1 ? "." : path.slice(0, idx) || ".";
679
- }
680
- function normalizePath(path) {
681
- const parts = [];
682
- for (const segment of path.split("/")) {
683
- if (segment === "..") parts.pop();
684
- else if (segment && segment !== ".") parts.push(segment);
685
- }
686
- return parts.join("/");
687
- }
688
- function inferLoader(path, language) {
689
- if (language) {
690
- switch (language) {
691
- case "typescript":
692
- case "ts":
693
- return "ts";
694
- case "tsx":
695
- return "tsx";
696
- case "javascript":
697
- case "js":
698
- return "js";
699
- case "jsx":
700
- return "jsx";
701
- case "json":
702
- return "json";
703
- case "css":
704
- return "css";
705
- }
706
- }
707
- const ext = path.split(".").pop();
708
- switch (ext) {
709
- case "ts":
710
- return "ts";
711
- case "tsx":
712
- return "tsx";
713
- case "js":
714
- return "js";
715
- case "jsx":
716
- return "jsx";
717
- case "json":
718
- return "json";
719
- case "css":
720
- return "css";
721
- default:
722
- return "tsx";
723
- }
724
- }
725
- function normalizeVFSPath(path) {
726
- if (path.startsWith("@/")) {
727
- return path.slice(2);
728
- }
729
- return path;
730
- }
731
- function resolveRelativePath(importer, target) {
732
- const importerDir = dirname(normalizeVFSPath(importer));
733
- const combined = importerDir === "." ? target : `${importerDir}/${target}`;
734
- return normalizePath(combined);
735
- }
736
- function matchAlias2(importPath, aliases) {
737
- if (!aliases) return null;
738
- for (const [pattern, target] of Object.entries(aliases)) {
739
- if (pattern.endsWith("/*")) {
740
- const prefix = pattern.slice(0, -2);
741
- if (importPath === prefix || importPath.startsWith(prefix + "/")) {
742
- return target;
743
- }
744
- }
745
- if (importPath === pattern) {
746
- return target;
747
- }
748
- }
749
- return null;
750
- }
751
- function findFile(project, path) {
752
- if (project.files.has(path)) return path;
753
- const extensions = [".tsx", ".ts", ".jsx", ".js", ".json"];
754
- for (const ext of extensions) {
755
- if (project.files.has(path + ext)) return path + ext;
756
- }
757
- for (const ext of extensions) {
758
- const indexPath = `${path}/index${ext}`;
759
- if (project.files.has(indexPath)) return indexPath;
381
+ };
382
+ var globalRegistry = null;
383
+ function getImageRegistry() {
384
+ if (!globalRegistry) {
385
+ globalRegistry = new ImageRegistry();
760
386
  }
761
- return null;
387
+ return globalRegistry;
762
388
  }
763
- function vfsPlugin(project, options = {}) {
764
- return {
765
- name: "patchwork-vfs",
766
- setup(build2) {
767
- build2.onResolve({ filter: /^@\// }, (args) => {
768
- const aliased = matchAlias2(args.path, options.aliases);
769
- if (aliased) return null;
770
- return { path: args.path, namespace: "vfs" };
771
- });
772
- build2.onResolve({ filter: /^\./ }, (args) => {
773
- if (args.namespace !== "vfs") return null;
774
- const resolved = resolveRelativePath(args.importer, args.path);
775
- return { path: resolved, namespace: "vfs" };
776
- });
777
- build2.onLoad({ filter: /.*/, namespace: "vfs" }, (args) => {
778
- const normalPath = normalizeVFSPath(args.path);
779
- const filePath = findFile(project, normalPath);
780
- if (!filePath) {
781
- throw new Error(`File not found in VFS: ${args.path}`);
782
- }
783
- const file = project.files.get(filePath);
784
- return {
785
- contents: file.content,
786
- loader: inferLoader(filePath, file.language)
787
- };
788
- });
789
- }
790
- };
389
+ function createImageRegistry() {
390
+ return new ImageRegistry();
791
391
  }
792
392
 
793
393
  // src/mount/bridge.ts
794
394
  function generateMessageId() {
795
395
  return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
796
396
  }
797
- function createHttpServiceProxy(proxyUrl) {
397
+ function createHttpProxy(proxyUrl) {
798
398
  return {
799
399
  async call(namespace, procedure, args) {
800
400
  const url = `${proxyUrl}/${namespace}/${procedure}`;
@@ -938,7 +538,7 @@ var ParentBridge = class {
938
538
  this.pendingCalls.clear();
939
539
  }
940
540
  };
941
- function createIframeServiceProxy() {
541
+ function createIframeProxy() {
942
542
  const pendingCalls = /* @__PURE__ */ new Map();
943
543
  if (typeof window !== "undefined") {
944
544
  window.addEventListener("message", (event) => {
@@ -1192,48 +792,288 @@ async function mountEmbedded(widget, options, image, proxy) {
1192
792
  if (typeof root.unmount === "function") {
1193
793
  moduleCleanup = () => root.unmount();
1194
794
  }
1195
- } else if (createElement && renderer?.kind === "render") {
1196
- renderer.render(createElement(Component, inputs), container);
1197
- } else {
1198
- const result = Component(inputs);
1199
- if (result instanceof HTMLElement) {
1200
- container.appendChild(result);
1201
- } else if (typeof result === "string") {
1202
- container.innerHTML = result;
795
+ } else if (createElement && renderer?.kind === "render") {
796
+ renderer.render(createElement(Component, inputs), container);
797
+ } else {
798
+ const result = Component(inputs);
799
+ if (result instanceof HTMLElement) {
800
+ container.appendChild(result);
801
+ } else if (typeof result === "string") {
802
+ container.innerHTML = result;
803
+ }
804
+ }
805
+ }
806
+ } finally {
807
+ URL.revokeObjectURL(scriptUrl);
808
+ }
809
+ const unmount = () => {
810
+ if (moduleCleanup) {
811
+ moduleCleanup();
812
+ }
813
+ removeNamespaceGlobals(window, namespaceNames);
814
+ const style = document.getElementById(`${mountId}-style`);
815
+ if (style) {
816
+ style.remove();
817
+ }
818
+ container.remove();
819
+ };
820
+ return {
821
+ id: mountId,
822
+ widget,
823
+ mode: "embedded",
824
+ target,
825
+ inputs,
826
+ unmount
827
+ };
828
+ }
829
+ async function reloadEmbedded(mounted, widget, image, proxy) {
830
+ mounted.unmount();
831
+ return mountEmbedded(
832
+ widget,
833
+ { target: mounted.target, mode: "embedded", inputs: mounted.inputs },
834
+ image,
835
+ proxy
836
+ );
837
+ }
838
+
839
+ // src/transforms/cdn.ts
840
+ var DEFAULT_CDN_BASE2 = "https://esm.sh";
841
+ var cdnBaseUrl2 = DEFAULT_CDN_BASE2;
842
+ function setCdnBaseUrl2(url) {
843
+ cdnBaseUrl2 = url;
844
+ }
845
+ var EXTERNAL_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom", "ink"]);
846
+ var NODE_BUILTINS = /* @__PURE__ */ new Set([
847
+ "assert",
848
+ "buffer",
849
+ "child_process",
850
+ "cluster",
851
+ "crypto",
852
+ "dgram",
853
+ "dns",
854
+ "events",
855
+ "fs",
856
+ "http",
857
+ "http2",
858
+ "https",
859
+ "net",
860
+ "os",
861
+ "path",
862
+ "perf_hooks",
863
+ "process",
864
+ "querystring",
865
+ "readline",
866
+ "stream",
867
+ "string_decoder",
868
+ "timers",
869
+ "tls",
870
+ "tty",
871
+ "url",
872
+ "util",
873
+ "v8",
874
+ "vm",
875
+ "worker_threads",
876
+ "zlib"
877
+ ]);
878
+ function toEsmShUrl(packageName, version, subpath, deps) {
879
+ let url = `${cdnBaseUrl2}/${packageName}`;
880
+ if (version) {
881
+ url += `@${version}`;
882
+ }
883
+ if (subpath) {
884
+ url += `/${subpath}`;
885
+ }
886
+ if (deps && Object.keys(deps).length > 0) {
887
+ const depsStr = Object.entries(deps).map(([name, ver]) => `${name}@${ver}`).join(",");
888
+ url += `?deps=${depsStr}`;
889
+ }
890
+ return url;
891
+ }
892
+ function isBareImport(path) {
893
+ if (path.startsWith(".") || path.startsWith("/") || path.startsWith("http://") || path.startsWith("https://")) {
894
+ return false;
895
+ }
896
+ return true;
897
+ }
898
+ function parseImportPath(importPath) {
899
+ if (importPath.startsWith("@")) {
900
+ const parts2 = importPath.split("/");
901
+ if (parts2.length >= 2) {
902
+ const packageName2 = `${parts2[0]}/${parts2[1]}`;
903
+ const subpath2 = parts2.slice(2).join("/");
904
+ return { packageName: packageName2, subpath: subpath2 || void 0 };
905
+ }
906
+ }
907
+ const parts = importPath.split("/");
908
+ const packageName = parts[0];
909
+ const subpath = parts.slice(1).join("/");
910
+ return { packageName, subpath: subpath || void 0 };
911
+ }
912
+ function matchAlias(importPath, aliases) {
913
+ for (const [pattern, target] of Object.entries(aliases)) {
914
+ if (pattern.endsWith("/*")) {
915
+ const prefix = pattern.slice(0, -2);
916
+ if (importPath === prefix || importPath.startsWith(prefix + "/")) {
917
+ return target;
918
+ }
919
+ }
920
+ if (importPath === pattern) {
921
+ return target;
922
+ }
923
+ }
924
+ return null;
925
+ }
926
+ function cdnTransformPlugin(options = {}) {
927
+ const {
928
+ packages = {},
929
+ external = [],
930
+ bundle = false,
931
+ globals = {},
932
+ deps = {},
933
+ aliases = {}
934
+ } = options;
935
+ const externalSet = /* @__PURE__ */ new Set([...EXTERNAL_PACKAGES, ...external]);
936
+ const globalsSet = new Set(Object.keys(globals));
937
+ return {
938
+ name: "cdn-transform",
939
+ setup(build2) {
940
+ build2.onResolve({ filter: /.*/ }, (args) => {
941
+ const aliasTarget = matchAlias(args.path, aliases);
942
+ if (aliasTarget) {
943
+ const { packageName, subpath } = parseImportPath(aliasTarget);
944
+ if (globalsSet.has(packageName)) {
945
+ return {
946
+ path: aliasTarget,
947
+ namespace: "global-inject"
948
+ };
949
+ }
950
+ const version = packages[packageName];
951
+ let url = toEsmShUrl(
952
+ packageName,
953
+ version,
954
+ subpath,
955
+ Object.keys(deps).length > 0 ? deps : void 0
956
+ );
957
+ if (bundle) {
958
+ url += url.includes("?") ? "&bundle" : "?bundle";
959
+ }
960
+ return {
961
+ path: url,
962
+ external: true
963
+ };
964
+ }
965
+ return null;
966
+ });
967
+ build2.onResolve({ filter: /.*/ }, (args) => {
968
+ if (!isBareImport(args.path)) {
969
+ return null;
970
+ }
971
+ const { packageName } = parseImportPath(args.path);
972
+ if (globalsSet.has(packageName)) {
973
+ return {
974
+ path: args.path,
975
+ namespace: "global-inject"
976
+ };
977
+ }
978
+ return null;
979
+ });
980
+ build2.onLoad({ filter: /.*/, namespace: "global-inject" }, (args) => {
981
+ const { packageName, subpath } = parseImportPath(args.path);
982
+ const globalName = globals[packageName];
983
+ if (!globalName) return null;
984
+ if (subpath) {
985
+ return {
986
+ contents: `export * from '${packageName}'; export { default } from '${packageName}';`,
987
+ loader: "js"
988
+ };
989
+ }
990
+ const contents = `
991
+ const mod = window.${globalName};
992
+ export default mod;
993
+ // Re-export all properties as named exports
994
+ const { ${getCommonExports(packageName).join(", ")} } = mod;
995
+ export { ${getCommonExports(packageName).join(", ")} };
996
+ `;
997
+ return {
998
+ contents,
999
+ loader: "js"
1000
+ };
1001
+ });
1002
+ build2.onResolve({ filter: /.*/ }, (args) => {
1003
+ if (!isBareImport(args.path)) {
1004
+ return null;
1005
+ }
1006
+ if (NODE_BUILTINS.has(args.path)) {
1007
+ return { external: true };
1008
+ }
1009
+ const { packageName, subpath } = parseImportPath(args.path);
1010
+ if (globalsSet.has(packageName)) {
1011
+ return null;
1012
+ }
1013
+ if (externalSet.has(packageName)) {
1014
+ return { external: true };
1015
+ }
1016
+ const version = packages[packageName];
1017
+ let url = toEsmShUrl(
1018
+ packageName,
1019
+ version,
1020
+ subpath,
1021
+ Object.keys(deps).length > 0 ? deps : void 0
1022
+ );
1023
+ if (bundle) {
1024
+ url += url.includes("?") ? "&bundle" : "?bundle";
1203
1025
  }
1204
- }
1205
- }
1206
- } finally {
1207
- URL.revokeObjectURL(scriptUrl);
1208
- }
1209
- const unmount = () => {
1210
- if (moduleCleanup) {
1211
- moduleCleanup();
1212
- }
1213
- removeNamespaceGlobals(window, namespaceNames);
1214
- const style = document.getElementById(`${mountId}-style`);
1215
- if (style) {
1216
- style.remove();
1026
+ return {
1027
+ path: url,
1028
+ external: true
1029
+ };
1030
+ });
1217
1031
  }
1218
- container.remove();
1219
1032
  };
1220
- return {
1221
- id: mountId,
1222
- widget,
1223
- mode: "embedded",
1224
- target,
1225
- inputs,
1226
- unmount
1033
+ }
1034
+ function getCommonExports(packageName) {
1035
+ const exports2 = {
1036
+ react: [
1037
+ "useState",
1038
+ "useEffect",
1039
+ "useCallback",
1040
+ "useMemo",
1041
+ "useRef",
1042
+ "useContext",
1043
+ "useReducer",
1044
+ "useLayoutEffect",
1045
+ "useId",
1046
+ "createContext",
1047
+ "createElement",
1048
+ "cloneElement",
1049
+ "createRef",
1050
+ "forwardRef",
1051
+ "lazy",
1052
+ "memo",
1053
+ "Fragment",
1054
+ "Suspense",
1055
+ "StrictMode",
1056
+ "Component",
1057
+ "PureComponent",
1058
+ "Children",
1059
+ "isValidElement"
1060
+ ],
1061
+ "react-dom": [
1062
+ "createPortal",
1063
+ "flushSync",
1064
+ "render",
1065
+ "hydrate",
1066
+ "unmountComponentAtNode"
1067
+ ]
1227
1068
  };
1069
+ return exports2[packageName] || [];
1228
1070
  }
1229
- async function reloadEmbedded(mounted, widget, image, proxy) {
1230
- mounted.unmount();
1231
- return mountEmbedded(
1232
- widget,
1233
- { target: mounted.target, mode: "embedded", inputs: mounted.inputs },
1234
- image,
1235
- proxy
1236
- );
1071
+ function generateImportMap(packages) {
1072
+ const imports = {};
1073
+ for (const [name, version] of Object.entries(packages)) {
1074
+ imports[name] = toEsmShUrl(name, version);
1075
+ }
1076
+ return imports;
1237
1077
  }
1238
1078
 
1239
1079
  // src/mount/iframe.ts
@@ -1561,16 +1401,178 @@ function disposeIframeBridge() {
1561
1401
  }
1562
1402
  }
1563
1403
 
1404
+ // src/transforms/vfs.ts
1405
+ function dirname(path) {
1406
+ const idx = path.lastIndexOf("/");
1407
+ return idx === -1 ? "." : path.slice(0, idx) || ".";
1408
+ }
1409
+ function normalizePath(path) {
1410
+ const parts = [];
1411
+ for (const segment of path.split("/")) {
1412
+ if (segment === "..") parts.pop();
1413
+ else if (segment && segment !== ".") parts.push(segment);
1414
+ }
1415
+ return parts.join("/");
1416
+ }
1417
+ function inferLoader(path, language) {
1418
+ if (language) {
1419
+ switch (language) {
1420
+ case "typescript":
1421
+ case "ts":
1422
+ return "ts";
1423
+ case "tsx":
1424
+ return "tsx";
1425
+ case "javascript":
1426
+ case "js":
1427
+ return "js";
1428
+ case "jsx":
1429
+ return "jsx";
1430
+ case "json":
1431
+ return "json";
1432
+ case "css":
1433
+ return "css";
1434
+ }
1435
+ }
1436
+ const ext = path.split(".").pop();
1437
+ switch (ext) {
1438
+ case "ts":
1439
+ return "ts";
1440
+ case "tsx":
1441
+ return "tsx";
1442
+ case "js":
1443
+ return "js";
1444
+ case "jsx":
1445
+ return "jsx";
1446
+ case "json":
1447
+ return "json";
1448
+ case "css":
1449
+ return "css";
1450
+ default:
1451
+ return "tsx";
1452
+ }
1453
+ }
1454
+ function normalizeVFSPath(path) {
1455
+ if (path.startsWith("@/")) {
1456
+ return path.slice(2);
1457
+ }
1458
+ return path;
1459
+ }
1460
+ function resolveRelativePath(importer, target) {
1461
+ const importerDir = dirname(normalizeVFSPath(importer));
1462
+ const combined = importerDir === "." ? target : `${importerDir}/${target}`;
1463
+ return normalizePath(combined);
1464
+ }
1465
+ function matchAlias2(importPath, aliases) {
1466
+ if (!aliases) return null;
1467
+ for (const [pattern, target] of Object.entries(aliases)) {
1468
+ if (pattern.endsWith("/*")) {
1469
+ const prefix = pattern.slice(0, -2);
1470
+ if (importPath === prefix || importPath.startsWith(prefix + "/")) {
1471
+ return target;
1472
+ }
1473
+ }
1474
+ if (importPath === pattern) {
1475
+ return target;
1476
+ }
1477
+ }
1478
+ return null;
1479
+ }
1480
+ function findFile(project, path) {
1481
+ if (project.files.has(path)) return path;
1482
+ const extensions = [".tsx", ".ts", ".jsx", ".js", ".json"];
1483
+ for (const ext of extensions) {
1484
+ if (project.files.has(path + ext)) return path + ext;
1485
+ }
1486
+ for (const ext of extensions) {
1487
+ const indexPath = `${path}/index${ext}`;
1488
+ if (project.files.has(indexPath)) return indexPath;
1489
+ }
1490
+ return null;
1491
+ }
1492
+ function vfsPlugin(project, options = {}) {
1493
+ return {
1494
+ name: "patchwork-vfs",
1495
+ setup(build2) {
1496
+ build2.onResolve({ filter: /^@\// }, (args) => {
1497
+ const aliased = matchAlias2(args.path, options.aliases);
1498
+ if (aliased) return null;
1499
+ return { path: args.path, namespace: "vfs" };
1500
+ });
1501
+ build2.onResolve({ filter: /^\./ }, (args) => {
1502
+ if (args.namespace !== "vfs") return null;
1503
+ const resolved = resolveRelativePath(args.importer, args.path);
1504
+ return { path: resolved, namespace: "vfs" };
1505
+ });
1506
+ build2.onLoad({ filter: /.*/, namespace: "vfs" }, (args) => {
1507
+ const normalPath = normalizeVFSPath(args.path);
1508
+ const filePath = findFile(project, normalPath);
1509
+ if (!filePath) {
1510
+ throw new Error(`File not found in VFS: ${args.path}`);
1511
+ }
1512
+ const file = project.files.get(filePath);
1513
+ return {
1514
+ contents: file.content,
1515
+ loader: inferLoader(filePath, file.language)
1516
+ };
1517
+ });
1518
+ }
1519
+ };
1520
+ }
1521
+
1522
+ // src/vfs/project.ts
1523
+ function createProjectFromFiles(files, id = crypto.randomUUID()) {
1524
+ const fileMap = /* @__PURE__ */ new Map();
1525
+ for (const file of files) {
1526
+ fileMap.set(file.path, file);
1527
+ }
1528
+ return { id, entry: resolveEntry(fileMap), files: fileMap };
1529
+ }
1530
+ function resolveEntry(files) {
1531
+ const paths = Array.from(files.keys());
1532
+ const mainFile = paths.find((p) => /\bmain\.(tsx?|jsx?)$/.test(p));
1533
+ if (mainFile) return mainFile;
1534
+ const indexFile = paths.find((p) => /\bindex\.(tsx?|jsx?)$/.test(p));
1535
+ if (indexFile) return indexFile;
1536
+ const firstTsx = paths.find((p) => /\.(tsx|jsx)$/.test(p));
1537
+ if (firstTsx) return firstTsx;
1538
+ return paths[0] || "main.tsx";
1539
+ }
1540
+ function detectMainFile(language) {
1541
+ switch (language) {
1542
+ case "tsx":
1543
+ case "typescript":
1544
+ return "main.tsx";
1545
+ case "jsx":
1546
+ case "javascript":
1547
+ return "main.jsx";
1548
+ case "ts":
1549
+ return "main.ts";
1550
+ case "js":
1551
+ return "main.js";
1552
+ default:
1553
+ return "main.tsx";
1554
+ }
1555
+ }
1556
+ function createSingleFileProject(content, entry = "main.tsx", id = "inline") {
1557
+ return {
1558
+ id,
1559
+ entry,
1560
+ files: /* @__PURE__ */ new Map([[entry, { path: entry, content }]])
1561
+ };
1562
+ }
1563
+
1564
1564
  // src/compiler.ts
1565
1565
  var esbuildInitialized = false;
1566
1566
  var esbuildInitPromise = null;
1567
- async function initEsbuild() {
1567
+ var DEFAULT_ESBUILD_WASM_URL = "https://unpkg.com/esbuild-wasm/esbuild.wasm";
1568
+ async function initEsbuild(urlOverrides) {
1568
1569
  if (esbuildInitialized) return;
1569
1570
  if (esbuildInitPromise) return esbuildInitPromise;
1571
+ const wasmUrl = urlOverrides?.["esbuild-wasm/esbuild.wasm"] || DEFAULT_ESBUILD_WASM_URL;
1570
1572
  esbuildInitPromise = (async () => {
1571
1573
  try {
1572
1574
  await esbuild.initialize({
1573
- wasmURL: "https://unpkg.com/esbuild-wasm/esbuild.wasm"
1575
+ wasmURL: wasmUrl
1574
1576
  });
1575
1577
  esbuildInitialized = true;
1576
1578
  } catch (error) {
@@ -1593,7 +1595,7 @@ function hashContent(content) {
1593
1595
  return Math.abs(hash).toString(16).padStart(8, "0");
1594
1596
  }
1595
1597
  async function createCompiler(options) {
1596
- await initEsbuild();
1598
+ await initEsbuild(options.urlOverrides);
1597
1599
  const { image: imageSpec, proxyUrl, cdnBaseUrl: cdnBaseUrl3, widgetCdnBaseUrl } = options;
1598
1600
  if (cdnBaseUrl3) {
1599
1601
  setCdnBaseUrl(cdnBaseUrl3);
@@ -1605,7 +1607,7 @@ async function createCompiler(options) {
1605
1607
  }
1606
1608
  const registry = getImageRegistry();
1607
1609
  await registry.preload(imageSpec);
1608
- const proxy = createHttpServiceProxy(proxyUrl);
1610
+ const proxy = createHttpProxy(proxyUrl);
1609
1611
  return new PatchworkCompiler(proxy, registry);
1610
1612
  }
1611
1613
  var PatchworkCompiler = class {
@@ -2028,6 +2030,8 @@ var SyncEngineImpl = class {
2028
2030
  this.basePath = config.basePath ?? "";
2029
2031
  this.startRemoteWatch();
2030
2032
  }
2033
+ local;
2034
+ remote;
2031
2035
  status = "idle";
2032
2036
  intervalId;
2033
2037
  listeners = /* @__PURE__ */ new Map();
@@ -2333,7 +2337,7 @@ function openDB() {
2333
2337
  const request = indexedDB.open(DB_NAME, DB_VERSION);
2334
2338
  request.onerror = () => reject(request.error);
2335
2339
  request.onsuccess = () => resolve(request.result);
2336
- request.onupgradeneeded = (event) => {
2340
+ request.onupgradeneeded = (_event) => {
2337
2341
  const db = request.result;
2338
2342
  if (!db.objectStoreNames.contains(FILES_STORE)) {
2339
2343
  db.createObjectStore(FILES_STORE);
@@ -2359,6 +2363,7 @@ var IndexedDBBackend = class {
2359
2363
  constructor(prefix = "vfs") {
2360
2364
  this.prefix = prefix;
2361
2365
  }
2366
+ prefix;
2362
2367
  key(path) {
2363
2368
  return `${this.prefix}:${normalizePath2(path)}`;
2364
2369
  }
@@ -2529,6 +2534,7 @@ var HttpBackend = class {
2529
2534
  constructor(config) {
2530
2535
  this.config = config;
2531
2536
  }
2537
+ config;
2532
2538
  async readFile(path) {
2533
2539
  const res = await fetch(this.url(path));
2534
2540
  if (!res.ok) throw new Error(`ENOENT: ${path}`);
@@ -2632,6 +2638,7 @@ var VFSStore = class {
2632
2638
  }
2633
2639
  }
2634
2640
  }
2641
+ provider;
2635
2642
  local;
2636
2643
  syncEngine;
2637
2644
  root;
@@ -2803,8 +2810,8 @@ var VFSStore = class {
2803
2810
  cdnTransformPlugin,
2804
2811
  createCompiler,
2805
2812
  createFieldAccessProxy,
2806
- createHttpServiceProxy,
2807
- createIframeServiceProxy,
2813
+ createHttpProxy,
2814
+ createIframeProxy,
2808
2815
  createImageRegistry,
2809
2816
  createProjectFromFiles,
2810
2817
  createSingleFileProject,