@powerhousedao/builder-tools 0.3.2 → 0.3.4

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.
@@ -1,4 +1,5 @@
1
1
  import { PowerhouseConfig } from "@powerhousedao/config/powerhouse";
2
+ export declare function copyConnect(sourcePath: string, targetPath: string): void;
2
3
  export declare function backupIndexHtml(appPath: string, restore?: boolean): void;
3
4
  export declare function removeBase64EnvValues(appPath: string): void;
4
5
  export declare function readJsonFile(filePath: string): PowerhouseConfig | null;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../connect-studio/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAIpE,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,UAAQ,QAS/D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,QA+BpD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAStE"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../connect-studio/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAIpE,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAUjE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,UAAQ,QAS/D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,QAgCpD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAStE"}
@@ -1,5 +1,16 @@
1
1
  import fs from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
+ export function copyConnect(sourcePath, targetPath) {
4
+ try {
5
+ // Ensure targetPath is removed before copying
6
+ fs.rmSync(targetPath, { recursive: true, force: true });
7
+ // Copy everything from sourcePath to targetPath
8
+ fs.cpSync(sourcePath, targetPath, { recursive: true });
9
+ }
10
+ catch (error) {
11
+ console.error(`❌ Error copying ${sourcePath} to ${targetPath}:`, error);
12
+ }
13
+ }
3
14
  export function backupIndexHtml(appPath, restore = false) {
4
15
  const filePath = join(appPath, "index.html");
5
16
  const backupPath = join(appPath, "index.html.bak");
@@ -21,6 +32,7 @@ export function removeBase64EnvValues(appPath) {
21
32
  const modifiedData = data
22
33
  .replace(/"LOCAL_DOCUMENT_MODELS":\s*".*?",/, `"LOCAL_DOCUMENT_MODELS": "",`)
23
34
  .replace(/"LOCAL_DOCUMENT_EDITORS":\s*".*?"/, `"LOCAL_DOCUMENT_EDITORS": ""`);
35
+ console.log("Modified data:", modifiedData);
24
36
  // Write the modified content back to the file
25
37
  fs.writeFile(filePath, modifiedData, "utf-8", (err) => {
26
38
  if (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../connect-studio/server.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAkEhD,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAER,iBA8HF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../connect-studio/server.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAkEhD,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAER,iBAmFF"}
@@ -5,7 +5,7 @@ import { createRequire } from "node:module";
5
5
  import { join, resolve } from "node:path";
6
6
  import { createLogger, createServer } from "vite";
7
7
  import { viteEnvs } from "vite-envs";
8
- import { backupIndexHtml, removeBase64EnvValues } from "./helpers.js";
8
+ import { backupIndexHtml, copyConnect, removeBase64EnvValues, } from "./helpers.js";
9
9
  import { getStudioConfig } from "./vite-plugins/base.js";
10
10
  import { viteLoadExternalPackages } from "./vite-plugins/external-packages.js";
11
11
  import { generateImportMapPlugin } from "./vite-plugins/importmap.js";
@@ -72,8 +72,10 @@ export async function startServer(options = {
72
72
  ensureNodeVersion();
73
73
  const connectPath = options.connectPath ?? resolveConnect();
74
74
  const projectRoot = process.cwd();
75
+ const studioPath = join(projectRoot, ".ph", "connect-studio");
76
+ copyConnect(connectPath, studioPath);
75
77
  // backups index html if running on windows
76
- backupIndexHtml(connectPath, true);
78
+ backupIndexHtml(studioPath, true);
77
79
  const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3000;
78
80
  const HOST = process.env.HOST ? process.env.HOST : "0.0.0.0";
79
81
  const OPEN_BROWSER = typeof process.env.OPEN_BROWSER === "string"
@@ -81,8 +83,8 @@ export async function startServer(options = {
81
83
  : false;
82
84
  const studioConfig = getStudioConfig();
83
85
  // needed for viteEnvs
84
- if (!fs.existsSync(join(connectPath, "src"))) {
85
- fs.mkdirSync(join(connectPath, "src"));
86
+ if (!fs.existsSync(join(studioPath, "src"))) {
87
+ fs.mkdirSync(join(studioPath, "src"));
86
88
  }
87
89
  process.env.PH_CONNECT_STUDIO_MODE = "true";
88
90
  process.env.PH_CONNECT_CLI_VERSION = options.phCliVersion;
@@ -90,7 +92,7 @@ export async function startServer(options = {
90
92
  const config = {
91
93
  customLogger: logger,
92
94
  configFile: false,
93
- root: connectPath,
95
+ root: studioPath,
94
96
  server: {
95
97
  port: PORT,
96
98
  open: options.open ?? OPEN_BROWSER,
@@ -107,66 +109,26 @@ export async function startServer(options = {
107
109
  find: "react-dom",
108
110
  replacement: join(projectRoot, "node_modules", "react-dom"),
109
111
  },
110
- {
111
- find: "@powerhousedao/reactor-browser",
112
- replacement: join(projectRoot, "node_modules", "@powerhousedao", "reactor-browser", "dist/src"),
113
- },
114
112
  ],
115
- // Resolve to the node_modules in the project root
116
- // "@powerhousedao/design-system/scalars": join(
117
- // projectRoot,
118
- // "node_modules",
119
- // "@powerhousedao",
120
- // "design-system",
121
- // "dist",
122
- // "scalars",
123
- // ),
124
- // "@powerhousedao/design-system": join(
125
- // projectRoot,
126
- // "node_modules",
127
- // "@powerhousedao",
128
- // "design-system",
129
- // ),
130
- // "@powerhousedao/scalars": join(
131
- // projectRoot,
132
- // "node_modules",
133
- // "@powerhousedao",
134
- // "scalars",
135
- // ),
136
- // "@powerhousedao/reactor-browser/hooks/useUiNodesContext": join(
137
- // projectRoot,
138
- // "node_modules",
139
- // "@powerhousedao",
140
- // "reactor-browser",
141
- // "dist/src/hooks",
142
- // ),
143
- // react: join(projectRoot, "node_modules", "react"),
144
- // "react-dom": join(projectRoot, "node_modules", "react-dom"),
145
- // },
146
113
  },
147
114
  plugins: [
148
- viteConnectDevStudioPlugin(true, connectPath),
149
- viteLoadExternalPackages(options.packages, true),
115
+ viteConnectDevStudioPlugin(true, studioPath),
116
+ viteLoadExternalPackages(options.packages, studioPath, true),
150
117
  viteEnvs({
151
- declarationFile: join(connectPath, ".env"),
118
+ declarationFile: join(studioPath, ".env"),
152
119
  computedEnv,
153
120
  }),
154
- runShellScriptPlugin("vite-envs.sh", connectPath),
121
+ runShellScriptPlugin("vite-envs.sh", studioPath),
155
122
  options.https &&
156
123
  basicSsl({
157
124
  name: "Powerhouse Connect Studio",
158
125
  }),
159
- generateImportMapPlugin(connectPath, [
126
+ generateImportMapPlugin(studioPath, [
160
127
  { name: "react", provider: "esm.sh" },
161
128
  { name: "react-dom", provider: "esm.sh" },
162
129
  "@powerhousedao/reactor-browser",
163
130
  ]),
164
131
  ],
165
- build: {
166
- rollupOptions: {
167
- input: "index.html",
168
- },
169
- },
170
132
  };
171
133
  const server = await createServer(config);
172
134
  await server.listen();
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/base.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,MAAM,EAAE,YAAY,EAAiB,MAAM,MAAM,CAAC;AAGhF,eAAO,MAAM,WAAW,UAGvB,CAAC;AAEF,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AACpE,eAAO,MAAM,6BAA6B,2BAA2B,CAAC;AACtE,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD,eAAO,MAAM,cAAc,+EAIjB,CAAC;AAEX,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;IAC7D,CAAC,4BAA4B,CAAC,CAAC,EAAE,MAAM,CAAC;IACxC,CAAC,6BAA6B,CAAC,CAAC,EAAE,MAAM,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CA8BA;AAKD,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,EAAE,GACnD,MAAM,CAgER;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,YAAY,CAgDd;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM;iBAsBT,OAAO;;GAOtD"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/base.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,MAAM,EAAE,YAAY,EAAiB,MAAM,MAAM,CAAC;AAGhF,eAAO,MAAM,WAAW,UAIvB,CAAC;AAEF,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AACpE,eAAO,MAAM,6BAA6B,2BAA2B,CAAC;AACtE,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD,eAAO,MAAM,cAAc,+EAIjB,CAAC;AAEX,wBAAgB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;IAC7D,CAAC,4BAA4B,CAAC,CAAC,EAAE,MAAM,CAAC;IACxC,CAAC,6BAA6B,CAAC,CAAC,EAAE,MAAM,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CA8BA;AAKD,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,EAAE,GACnD,MAAM,CAgER;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,YAAY,CAgDd;AAED,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM;iBAsBT,OAAO;;GAOtD"}
@@ -7,6 +7,7 @@ import { normalizePath } from "vite";
7
7
  export const externalIds = [
8
8
  /^react(-dom)?(\/.*)?$/,
9
9
  /^@powerhousedao\/reactor-browser(\/.*)?$/,
10
+ /^node:.*$/,
10
11
  ];
11
12
  export const LOCAL_DOCUMENT_MODELS_IMPORT = "LOCAL_DOCUMENT_MODELS";
12
13
  export const LOCAL_DOCUMENT_EDITORS_IMPORT = "LOCAL_DOCUMENT_EDITORS";
@@ -1,6 +1,5 @@
1
1
  import { PluginOption } from "vite";
2
2
  export declare const EXTERNAL_PACKAGES_IMPORT = "PH:EXTERNAL_PACKAGES";
3
- export declare const IMPORT_SCRIPT_FILE: string;
4
- export declare function generateImportScript(packages: string[]): string;
5
- export declare const viteLoadExternalPackages: (packages: string[] | undefined, hmr?: boolean) => PluginOption;
3
+ export declare const IMPORT_SCRIPT_FILE = "external-packages.js";
4
+ export declare const viteLoadExternalPackages: (packages: string[] | undefined, targetDir: string, hmr?: boolean) => PluginOption;
6
5
  //# sourceMappingURL=external-packages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-packages.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/external-packages.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,YAAY,EAAE,MAAM,MAAM,CAAC;AAOnD,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,kBAAkB,QAE9B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAiCtD;AAED,eAAO,MAAM,wBAAwB,GACnC,UAAU,MAAM,EAAE,GAAG,SAAS,EAC9B,aAAW,KACV,YA4CF,CAAC"}
1
+ {"version":3,"file":"external-packages.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/external-packages.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAOpC,eAAO,MAAM,wBAAwB,yBAAyB,CAAC;AAC/D,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AAoCzD,eAAO,MAAM,wBAAwB,GACnC,UAAU,MAAM,EAAE,GAAG,SAAS,EAC9B,WAAW,MAAM,EACjB,aAAW,KACV,YA8CF,CAAC"}
@@ -1,19 +1,18 @@
1
1
  import { getConfig } from "@powerhousedao/config/powerhouse";
2
2
  import fs from "node:fs";
3
- import { dirname, join } from "node:path";
4
- import { normalizePath } from "vite";
3
+ import { join } from "node:path";
5
4
  import { viteIgnoreStaticImport, viteReplaceImports } from "./base.js";
6
5
  // TODO use config path?
7
6
  const __dirname = join(process.cwd(), ".ph/");
8
7
  // import.meta.dirname || dirname(fileURLToPath(import.meta.url));
9
8
  export const EXTERNAL_PACKAGES_IMPORT = "PH:EXTERNAL_PACKAGES";
10
- export const IMPORT_SCRIPT_FILE = normalizePath(join(__dirname, "external-packages.js"));
11
- export function generateImportScript(packages) {
12
- const targetDir = dirname(IMPORT_SCRIPT_FILE);
9
+ export const IMPORT_SCRIPT_FILE = "external-packages.js";
10
+ function generateImportScript(packages, targetDir) {
13
11
  // create file if it doesn't exist, also create path if it doesn't exist (recursive)
14
12
  if (!fs.existsSync(targetDir)) {
15
13
  fs.mkdirSync(targetDir, { recursive: true });
16
14
  }
15
+ const scriptPath = join(targetDir, IMPORT_SCRIPT_FILE);
17
16
  const imports = [];
18
17
  const moduleNames = [];
19
18
  let counter = 0;
@@ -32,23 +31,23 @@ export function generateImportScript(packages) {
32
31
  .join(",\n")}
33
32
  ];`;
34
33
  const fileContent = `${imports.join("\n")}\n\n${exportStatement}`;
35
- fs.writeFileSync(IMPORT_SCRIPT_FILE, fileContent);
36
- return IMPORT_SCRIPT_FILE;
34
+ fs.writeFileSync(scriptPath, fileContent);
35
+ return scriptPath;
37
36
  }
38
- export const viteLoadExternalPackages = (packages, hmr = false) => {
37
+ export const viteLoadExternalPackages = (packages, targetDir, hmr = false) => {
39
38
  if (!packages?.length && !hmr) {
40
39
  return viteIgnoreStaticImport([EXTERNAL_PACKAGES_IMPORT]);
41
40
  }
42
- generateImportScript(packages ?? []);
41
+ const importScriptPath = generateImportScript(packages ?? [], targetDir);
43
42
  process.env.LOAD_EXTERNAL_PACKAGES = "true";
44
43
  return [
45
- viteReplaceImports({ [EXTERNAL_PACKAGES_IMPORT]: IMPORT_SCRIPT_FILE }),
44
+ viteReplaceImports({ [EXTERNAL_PACKAGES_IMPORT]: importScriptPath }),
46
45
  hmr && {
47
46
  name: "vite-plugin-studio-external-packages",
48
47
  handleHotUpdate({ file, server, modules }) {
49
48
  if (file.endsWith("powerhouse.config.json")) {
50
49
  const config = getConfig(file);
51
- generateImportScript(config.packages?.map((p) => p.packageName) ?? []);
50
+ generateImportScript(config.packages?.map((p) => p.packageName) ?? [], targetDir);
52
51
  config.packages?.forEach((pkg) => console.log("-> Loading package:", pkg.packageName));
53
52
  const module = server.moduleGraph.getModuleById(IMPORT_SCRIPT_FILE);
54
53
  if (module) {
@@ -1 +1 @@
1
- {"version":3,"file":"importmap.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/importmap.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAGpC,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,QAAQ,CAAC;AAoOjD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,CAAC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,EAAE,GAC9D,YAAY,CAUd"}
1
+ {"version":3,"file":"importmap.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/importmap.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAGpC,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,QAAQ,CAAC;AAkRjD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,CAAC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,EAAE,GAC9D,YAAY,CA+Bd"}
@@ -101,8 +101,7 @@ function importFromEsmSh(name) {
101
101
  [`${name}/`]: `https://esm.sh/${name}/`,
102
102
  };
103
103
  }
104
- async function importFromNodeModules(name, modulesDir, importMapDeps) {
105
- console.log(`Bundling dependency: ${name}`);
104
+ async function importFromNodeModules(name, modulesDir, importMapDeps, baseUrl) {
106
105
  const importMap = {};
107
106
  const { packageJson, path: srcPath } = await findPackageJson(name);
108
107
  const entries = await getPackageExports(name, packageJson, srcPath);
@@ -113,31 +112,34 @@ async function importFromNodeModules(name, modulesDir, importMapDeps) {
113
112
  const fileName = path.basename(entries.get("")?.export || "index", path.extname(indexFile));
114
113
  const outputPath = path.join(modulesDir, name);
115
114
  // Bundle and tree-shake only dependencies (exclude the actual library code)
116
- await build({
117
- entryPoints: Array.from(entries.values()).map((value) => path.join(srcPath, value.file)),
118
- outdir: outputPath,
119
- bundle: true,
120
- format: "esm",
121
- platform: "browser",
122
- target: "esnext",
123
- splitting: true,
124
- external: nodeModules.concat(Array.from(importMapDeps)), // Exclude dependencies already in import map
125
- sourcemap: true,
126
- minify: false,
127
- });
115
+ const buildModule = () => {
116
+ console.log(`Bundling dependency: ${name}`);
117
+ return build({
118
+ entryPoints: Array.from(entries.values()).map((value) => path.join(srcPath, value.file)),
119
+ outdir: outputPath,
120
+ bundle: true,
121
+ format: "esm",
122
+ platform: "browser",
123
+ target: "esnext",
124
+ splitting: true,
125
+ external: nodeModules.concat(Array.from(importMapDeps)), // Exclude dependencies already in import map
126
+ sourcemap: false,
127
+ minify: false,
128
+ });
129
+ };
128
130
  // Add entry to import map
129
131
  importMap[name] = `./modules/${name}/${fileName}.js`;
130
132
  entries.forEach((entry, key) => {
131
- importMap[path.join(name, key)] =
132
- `./modules/${path.join(name, entry.export)}`;
133
+ importMap[path.join(name, key)] = path.join(baseUrl, `./modules/${path.join(name, entry.export)}`);
133
134
  });
134
- return importMap;
135
+ return { importMap, buildModule };
135
136
  }
136
- async function generateImportMap(outputDir, dependencies) {
137
+ async function generateImportMap(outputDir, dependencies, baseUrl) {
137
138
  const modulesDir = path.join(outputDir, "/modules");
138
139
  await fs.mkdir(modulesDir, { recursive: true });
139
140
  const importMapDeps = new Set(dependencies.map((dep) => (typeof dep === "string" ? dep : dep.name)));
140
141
  let importMap = {};
142
+ const buildModules = [];
141
143
  for (const dependency of dependencies) {
142
144
  const name = typeof dependency === "string" ? dependency : dependency.name;
143
145
  const provider = typeof dependency === "string" ? "node_modules" : dependency.provider;
@@ -146,19 +148,47 @@ async function generateImportMap(outputDir, dependencies) {
146
148
  importMap = { ...importMap, ...imports };
147
149
  }
148
150
  else if (provider.toString() === "node_modules") {
149
- const imports = await importFromNodeModules(name, modulesDir, importMapDeps);
151
+ const { importMap: imports, buildModule } = await importFromNodeModules(name, modulesDir, importMapDeps, baseUrl);
150
152
  importMap = { ...importMap, ...imports };
153
+ buildModules.push(buildModule);
151
154
  }
152
155
  else {
153
156
  throw new Error(`Unsupported provider: ${provider}`);
154
157
  }
155
158
  }
156
- const indexPath = path.join(outputDir, "index.html");
157
- let html = await fs.readFile(indexPath, "utf-8");
158
- const importMapScript = `<script type="importmap">${JSON.stringify({ imports: importMap }, null, 2)}</script>`;
159
- html = html.replace("</head>", `${importMapScript}\n</head>`);
160
- await fs.writeFile(indexPath, html, "utf-8");
161
- console.log("✅ Import map added to index.html");
159
+ return {
160
+ importMap,
161
+ buildModules: async () => {
162
+ await Promise.all(buildModules.map((build) => build()));
163
+ },
164
+ };
165
+ }
166
+ async function addImportMapToHTML(importMap, html) {
167
+ let newHtml = "";
168
+ // Regex to find existing import map
169
+ const importMapRegex = /<script type="importmap">(.*?)<\/script>/s;
170
+ const match = importMapRegex.exec(html);
171
+ // If an import map exists, merge the imports
172
+ if (match) {
173
+ try {
174
+ const existingImportMap = JSON.parse(match[1]);
175
+ existingImportMap.imports = {
176
+ ...existingImportMap.imports,
177
+ ...importMap,
178
+ };
179
+ const mergedImportMapString = JSON.stringify(existingImportMap, null, 2);
180
+ newHtml = html.replace(importMapRegex, `<script type="importmap">${mergedImportMapString}</script>`);
181
+ }
182
+ catch (error) {
183
+ console.error("⚠️ Error parsing existing import map:", error);
184
+ }
185
+ }
186
+ else {
187
+ const importMapString = JSON.stringify({ imports: importMap }, null, 2);
188
+ const importMapScript = `<script type="importmap">${importMapString}</script>`;
189
+ newHtml = html.replace("</head>", `${importMapScript}\n</head>`);
190
+ }
191
+ return newHtml;
162
192
  }
163
193
  /**
164
194
  * Vite plugin to bundle or copy dependencies and inject an import map into `index.html`.
@@ -174,13 +204,30 @@ async function generateImportMap(outputDir, dependencies) {
174
204
  * @returns {Plugin} A Vite plugin that processes dependencies and injects an import map.
175
205
  */
176
206
  export function generateImportMapPlugin(outputDir, dependencies) {
207
+ let buildModules = undefined;
208
+ let importMap = {};
177
209
  return {
178
210
  name: "vite-plugin-importmap",
179
- async closeBundle() {
180
- await generateImportMap(outputDir, dependencies);
211
+ enforce: "post",
212
+ // generates import map according to the base url
213
+ // and collects build method for each dependency
214
+ async configResolved(config) {
215
+ const result = await generateImportMap(outputDir, dependencies, config.base);
216
+ importMap = result.importMap;
217
+ buildModules = result.buildModules;
218
+ },
219
+ // builds modules when building the bundle
220
+ closeBundle() {
221
+ return buildModules?.();
222
+ },
223
+ // builds modules when starting the dev server
224
+ configureServer() {
225
+ return buildModules?.();
181
226
  },
182
- async configureServer() {
183
- await generateImportMap(outputDir, dependencies);
227
+ // adds importmap to the html
228
+ async transformIndexHtml(html) {
229
+ const newHtml = await addImportMapToHTML(importMap, html);
230
+ return newHtml || html;
184
231
  },
185
232
  };
186
233
  }
@@ -1 +1 @@
1
- {"version":3,"file":"studio.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/studio.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAanD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,WAAW,CAAC,EAAE,MAAM,QA8DrB;AAED,wBAAgB,0BAA0B,CACxC,OAAO,qBAAQ,EACf,WAAW,EAAE,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,YAAY,EAAE,CAoEhB"}
1
+ {"version":3,"file":"studio.d.ts","sourceRoot":"","sources":["../../../connect-studio/vite-plugins/studio.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAanD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,WAAW,CAAC,EAAE,MAAM,QA8DrB;AAED,wBAAgB,0BAA0B,CACxC,OAAO,qBAAQ,EACf,WAAW,EAAE,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,YAAY,EAAE,CAqEhB"}
@@ -65,6 +65,7 @@ export function viteConnectDevStudioPlugin(enabled = false, connectPath, env) {
65
65
  "react",
66
66
  "react-dom",
67
67
  "@powerhousedao/reactor-browser",
68
+ ...externalIds,
68
69
  ]),
69
70
  localDocumentModelsPath
70
71
  ? viteReplaceImports({