@rozenite/vite-plugin 1.8.1 → 1.10.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.
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Rozenite Dev Host</title>
7
+ <script type="module" crossorigin src="./assets/index-kRQeUY6W.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-PNYu6V-J.css">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,11 @@
1
+ {
2
+ "index.html": {
3
+ "file": "assets/index-kRQeUY6W.js",
4
+ "name": "index",
5
+ "src": "index.html",
6
+ "isEntry": true,
7
+ "css": [
8
+ "assets/index-PNYu6V-J.css"
9
+ ]
10
+ }
11
+ }
package/dist/index.cjs CHANGED
@@ -87,14 +87,75 @@ const getPackageJSON = async (projectRoot) => {
87
87
  const packageJSON = await fs$1.readFile(packageJSONPath, "utf8");
88
88
  return JSON.parse(packageJSON);
89
89
  };
90
+ const DEV_HOST_STATE_ELEMENT_ID = "__rozenite-dev-host__";
91
+ const DEV_HOST_CONFIG_GLOBAL_KEY = "__rozenite-dev-config__";
92
+ const DEV_HOST_BUILD_ENTRY_KEY = "index.html";
93
+ const getDevHostHtmlTemplate = () => {
94
+ return `<!DOCTYPE html>
95
+ <html lang="en">
96
+ <head>
97
+ <meta charset="UTF-8" />
98
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
99
+ <title>Rozenite Dev Host</title>
100
+ </head>
101
+ <body>
102
+ <div id="root"></div>
103
+ </body>
104
+ </html>`;
105
+ };
106
+ const getDevHostSourceEntryFile = (packageDir) => {
107
+ return path.join(packageDir, "src", "dev-host", "main.tsx");
108
+ };
109
+ const getBuiltDevHostAssets = (packageDir) => {
110
+ const devHostDistDir = path.join(packageDir, "dist", "dev-host");
111
+ const manifestPath = path.join(devHostDistDir, "manifest.json");
112
+ if (!fs.existsSync(manifestPath)) {
113
+ return null;
114
+ }
115
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
116
+ const entry = manifest[DEV_HOST_BUILD_ENTRY_KEY];
117
+ if (!entry?.file) {
118
+ throw new Error(`Missing ${DEV_HOST_BUILD_ENTRY_KEY} entry in dev host manifest.`);
119
+ }
120
+ return {
121
+ script: path.join(devHostDistDir, entry.file),
122
+ styles: (entry.css ?? []).map((file) => path.join(devHostDistDir, file))
123
+ };
124
+ };
125
+ const ROZENITE_CONFIG_FILE_NAME = "rozenite.config.ts";
126
+ const ROZENITE_DEV_CONFIG_MODULE_ID = "virtual:rozenite-dev-config";
127
+ const RESOLVED_ROZENITE_DEV_CONFIG_MODULE_ID = `\0${ROZENITE_DEV_CONFIG_MODULE_ID}`;
128
+ const getRozeniteConfigPath = (projectRoot) => {
129
+ return path.resolve(projectRoot, ROZENITE_CONFIG_FILE_NAME);
130
+ };
131
+ const resolveRozeniteDevConfigModuleId = (id) => {
132
+ if (id === ROZENITE_DEV_CONFIG_MODULE_ID) {
133
+ return RESOLVED_ROZENITE_DEV_CONFIG_MODULE_ID;
134
+ }
135
+ return null;
136
+ };
137
+ const loadRozeniteDevConfigModule = (id, projectRoot) => {
138
+ if (id !== RESOLVED_ROZENITE_DEV_CONFIG_MODULE_ID) {
139
+ return null;
140
+ }
141
+ const configPath = vite.normalizePath(getRozeniteConfigPath(projectRoot));
142
+ return `export { default } from ${JSON.stringify(`/@fs${configPath}`)};`;
143
+ };
90
144
  const TEMPLATES_DIR = path.resolve(
91
145
  node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href),
92
146
  "..",
93
147
  "..",
94
148
  "templates"
95
149
  );
150
+ const PACKAGE_DIR = path.resolve(
151
+ node_url.fileURLToPath(typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href),
152
+ "..",
153
+ ".."
154
+ );
155
+ const DEV_HOST_SOURCE_ENTRY_FILE = getDevHostSourceEntryFile(PACKAGE_DIR);
96
156
  const PANELS_DIR = "./panels";
97
157
  const DEVTOOLS_DIR = "devtools";
158
+ const DEV_HOST_ROUTE = "/";
98
159
  const rozeniteClientPlugin = () => {
99
160
  let projectRoot = process$1.cwd();
100
161
  let viteServer = null;
@@ -117,6 +178,18 @@ const rozeniteClientPlugin = () => {
117
178
  });
118
179
  };
119
180
  const PANEL_TEMPLATE = path.join(TEMPLATES_DIR, "panel.ejs");
181
+ const getManifestPanels = () => {
182
+ return getPanels().map((panel) => ({
183
+ name: panel.label,
184
+ source: `/${DEVTOOLS_DIR}/` + panel.htmlFile
185
+ }));
186
+ };
187
+ const getDevHostPanels = () => {
188
+ return getPanels().map((panel) => ({
189
+ label: panel.label,
190
+ source: `/${DEVTOOLS_DIR}/` + panel.htmlFile
191
+ }));
192
+ };
120
193
  const generatePanelHtmlContent = (panel) => {
121
194
  const template = fs.readFileSync(PANEL_TEMPLATE, "utf-8");
122
195
  const relativePath = path.relative(projectRoot, panel.sourceFile);
@@ -125,18 +198,63 @@ const rozeniteClientPlugin = () => {
125
198
  panelFile: relativePath
126
199
  });
127
200
  };
201
+ const getDevHostState = async () => {
202
+ const packageJSON = await getPackageJSON(projectRoot);
203
+ return {
204
+ packageName: packageJSON.name,
205
+ packageDescription: packageJSON.description,
206
+ panels: getDevHostPanels()
207
+ };
208
+ };
209
+ const serializeDevHostState = (state) => {
210
+ return JSON.stringify(state).replace(/</g, "\\u003c");
211
+ };
212
+ const toFsUrl = (filePath) => {
213
+ return `/@fs${vite.normalizePath(filePath)}`;
214
+ };
215
+ const getDevHostAssetTags = () => {
216
+ const builtAssets = getBuiltDevHostAssets(PACKAGE_DIR);
217
+ if (!builtAssets) {
218
+ return [
219
+ {
220
+ tag: "script",
221
+ attrs: {
222
+ type: "module",
223
+ src: toFsUrl(DEV_HOST_SOURCE_ENTRY_FILE)
224
+ },
225
+ injectTo: "body"
226
+ }
227
+ ];
228
+ }
229
+ return [
230
+ ...builtAssets.styles.map((stylePath) => ({
231
+ tag: "link",
232
+ attrs: {
233
+ rel: "stylesheet",
234
+ href: toFsUrl(stylePath)
235
+ },
236
+ injectTo: "head"
237
+ })),
238
+ {
239
+ tag: "script",
240
+ attrs: {
241
+ type: "module",
242
+ src: toFsUrl(builtAssets.script)
243
+ },
244
+ injectTo: "body"
245
+ }
246
+ ];
247
+ };
128
248
  return {
129
249
  name: "rozenite-client-plugin",
130
250
  async config(config) {
131
251
  if (config.root) {
132
252
  projectRoot = config.root;
133
253
  }
134
- rozeniteConfig = await loadConfig(
135
- path.resolve(projectRoot, "rozenite.config.ts")
136
- );
254
+ rozeniteConfig = await loadConfig(getRozeniteConfigPath(projectRoot));
137
255
  const panels = getPanels();
138
256
  config.server ??= {};
139
- config.server.open = false;
257
+ config.server.open = config.server.open === true ? DEV_HOST_ROUTE : config.server.open ?? DEV_HOST_ROUTE;
140
258
  config.server.port = 8888;
141
259
  config.build ??= {};
142
260
  config.build.rollupOptions ??= {};
@@ -157,6 +275,10 @@ const rozeniteClientPlugin = () => {
157
275
  };
158
276
  },
159
277
  resolveId(id) {
278
+ const devConfigModuleId = resolveRozeniteDevConfigModuleId(id);
279
+ if (devConfigModuleId) {
280
+ return devConfigModuleId;
281
+ }
160
282
  const isPanel = getPanels().some(
161
283
  (panel) => `${DEVTOOLS_DIR}/${panel.htmlFile}` === id
162
284
  );
@@ -166,6 +288,10 @@ const rozeniteClientPlugin = () => {
166
288
  return null;
167
289
  },
168
290
  load(id) {
291
+ const devConfigModule = loadRozeniteDevConfigModule(id, projectRoot);
292
+ if (devConfigModule) {
293
+ return devConfigModule;
294
+ }
169
295
  const panel = getPanels().find(
170
296
  (panel2) => `${DEVTOOLS_DIR}/${panel2.htmlFile}` === id
171
297
  );
@@ -174,6 +300,41 @@ const rozeniteClientPlugin = () => {
174
300
  }
175
301
  return null;
176
302
  },
303
+ async transformIndexHtml(_html, context) {
304
+ const pathname = context?.path ?? DEV_HOST_ROUTE;
305
+ if (pathname !== DEV_HOST_ROUTE) {
306
+ return;
307
+ }
308
+ const state = await getDevHostState();
309
+ return [
310
+ {
311
+ tag: "script",
312
+ attrs: {
313
+ id: DEV_HOST_STATE_ELEMENT_ID,
314
+ type: "application/json"
315
+ },
316
+ children: serializeDevHostState(state),
317
+ injectTo: "body"
318
+ },
319
+ {
320
+ tag: "script",
321
+ attrs: {
322
+ type: "module"
323
+ },
324
+ children: `import rozeniteConfig from ${JSON.stringify("/@id/" + ROZENITE_DEV_CONFIG_MODULE_ID)}; window[${JSON.stringify(DEV_HOST_CONFIG_GLOBAL_KEY)}] = rozeniteConfig.dev ?? {};`,
325
+ injectTo: "body"
326
+ },
327
+ {
328
+ tag: "meta",
329
+ attrs: {
330
+ name: "rozenite-dev-host",
331
+ content: "true"
332
+ },
333
+ injectTo: "head"
334
+ },
335
+ ...getDevHostAssetTags()
336
+ ];
337
+ },
177
338
  async configureServer(server) {
178
339
  viteServer = server;
179
340
  const packageJSON = await getPackageJSON(projectRoot);
@@ -193,7 +354,17 @@ const rozeniteClientPlugin = () => {
193
354
  return;
194
355
  }
195
356
  const panels = getPanels();
196
- const url = req.url || "/";
357
+ const requestUrl = req.url || "/";
358
+ const url = new URL(requestUrl, "http://localhost").pathname;
359
+ if (url === DEV_HOST_ROUTE) {
360
+ server.transformIndexHtml(requestUrl, getDevHostHtmlTemplate()).then((html) => {
361
+ res.setHeader("Content-Type", "text/html");
362
+ res.end(html);
363
+ }).catch((err) => {
364
+ next(err);
365
+ });
366
+ return;
367
+ }
197
368
  if (url === "/rozenite.json") {
198
369
  res.setHeader("Content-Type", "application/json");
199
370
  res.end(
@@ -202,10 +373,7 @@ const rozeniteClientPlugin = () => {
202
373
  name: packageJSON.name,
203
374
  version: packageJSON.version,
204
375
  description: packageJSON.description,
205
- panels: panels.map((panel2) => ({
206
- name: panel2.label,
207
- source: `/${DEVTOOLS_DIR}/` + panel2.htmlFile
208
- }))
376
+ panels: getManifestPanels()
209
377
  },
210
378
  null,
211
379
  2
@@ -218,7 +386,7 @@ const rozeniteClientPlugin = () => {
218
386
  );
219
387
  if (panel) {
220
388
  const htmlContent = generatePanelHtmlContent(panel);
221
- server.transformIndexHtml(req.url || "/", htmlContent).then((html) => {
389
+ server.transformIndexHtml(requestUrl, htmlContent).then((html) => {
222
390
  res.setHeader("Content-Type", "text/html");
223
391
  res.end(html);
224
392
  }).catch((err) => {
@@ -243,7 +411,6 @@ const rozeniteClientPlugin = () => {
243
411
  });
244
412
  },
245
413
  async generateBundle() {
246
- const panels = getPanels();
247
414
  const packageJSON = await getPackageJSON(projectRoot);
248
415
  this.emitFile({
249
416
  type: "asset",
@@ -252,10 +419,7 @@ const rozeniteClientPlugin = () => {
252
419
  name: packageJSON.name,
253
420
  version: packageJSON.version,
254
421
  description: packageJSON.description,
255
- panels: panels.map((panel) => ({
256
- name: panel.label,
257
- source: `/${DEVTOOLS_DIR}/` + panel.htmlFile
258
- }))
422
+ panels: getManifestPanels()
259
423
  })
260
424
  });
261
425
  }
@@ -499,6 +663,28 @@ function requirePlugin() {
499
663
  }
500
664
  };
501
665
  }
666
+ const normalizeRolledUpDeclarations = (content) => {
667
+ const valueDeclarationNames = /* @__PURE__ */ new Set();
668
+ content.replace(
669
+ /^\s*declare\s+(?:const|let|var|function)\s+([A-Za-z_$][\w$]*)\b/gm,
670
+ (_, name) => {
671
+ valueDeclarationNames.add(name);
672
+ return _;
673
+ }
674
+ );
675
+ const normalizeTypeReference = (name) => valueDeclarationNames.has(name) ? `typeof ${name}` : name;
676
+ return content.replace(
677
+ /^(\s*(?:export\s+)?declare\s+(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*:\s*)([A-Za-z_$][\w$]*)(\s*;)$/gm,
678
+ (_, prefix, name, suffix) => {
679
+ return `${prefix}${normalizeTypeReference(name)}${suffix}`;
680
+ }
681
+ ).replace(
682
+ /^(\s*(?:export\s+)?declare\s+type\s+[A-Za-z_$][\w$]*\s*=\s*)([A-Za-z_$][\w$]*)(\s*;)$/gm,
683
+ (_, prefix, name, suffix) => {
684
+ return `${prefix}${normalizeTypeReference(name)}${suffix}`;
685
+ }
686
+ );
687
+ };
502
688
  const bundleTargetDeclarations = async (projectRoot, target) => {
503
689
  const targetRoot = path.join(projectRoot, "dist", target);
504
690
  const publicEntryPath = path.join(targetRoot, "index.d.ts");
@@ -564,6 +750,11 @@ const bundleTargetDeclarations = async (projectRoot, target) => {
564
750
  }
565
751
  await fs$1.rm(entryPath, { force: true });
566
752
  await fs$1.rename(tempOutputPath, publicEntryPath);
753
+ const bundledContent = await fs$1.readFile(publicEntryPath, "utf8");
754
+ const normalizedContent = normalizeRolledUpDeclarations(bundledContent);
755
+ if (normalizedContent !== bundledContent) {
756
+ await fs$1.writeFile(publicEntryPath, normalizedContent);
757
+ }
567
758
  await fs$1.rm(srcDeclarationsPath, { recursive: true, force: true });
568
759
  };
569
760
  const dtsPlugin = "default" in maybeDtsPlugin ? maybeDtsPlugin.default : maybeDtsPlugin;
package/dist/index.js CHANGED
@@ -84,14 +84,75 @@ const getPackageJSON = async (projectRoot) => {
84
84
  const packageJSON = await fs$1.readFile(packageJSONPath, "utf8");
85
85
  return JSON.parse(packageJSON);
86
86
  };
87
+ const DEV_HOST_STATE_ELEMENT_ID = "__rozenite-dev-host__";
88
+ const DEV_HOST_CONFIG_GLOBAL_KEY = "__rozenite-dev-config__";
89
+ const DEV_HOST_BUILD_ENTRY_KEY = "index.html";
90
+ const getDevHostHtmlTemplate = () => {
91
+ return `<!DOCTYPE html>
92
+ <html lang="en">
93
+ <head>
94
+ <meta charset="UTF-8" />
95
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
96
+ <title>Rozenite Dev Host</title>
97
+ </head>
98
+ <body>
99
+ <div id="root"></div>
100
+ </body>
101
+ </html>`;
102
+ };
103
+ const getDevHostSourceEntryFile = (packageDir) => {
104
+ return path.join(packageDir, "src", "dev-host", "main.tsx");
105
+ };
106
+ const getBuiltDevHostAssets = (packageDir) => {
107
+ const devHostDistDir = path.join(packageDir, "dist", "dev-host");
108
+ const manifestPath = path.join(devHostDistDir, "manifest.json");
109
+ if (!fs.existsSync(manifestPath)) {
110
+ return null;
111
+ }
112
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
113
+ const entry = manifest[DEV_HOST_BUILD_ENTRY_KEY];
114
+ if (!entry?.file) {
115
+ throw new Error(`Missing ${DEV_HOST_BUILD_ENTRY_KEY} entry in dev host manifest.`);
116
+ }
117
+ return {
118
+ script: path.join(devHostDistDir, entry.file),
119
+ styles: (entry.css ?? []).map((file) => path.join(devHostDistDir, file))
120
+ };
121
+ };
122
+ const ROZENITE_CONFIG_FILE_NAME = "rozenite.config.ts";
123
+ const ROZENITE_DEV_CONFIG_MODULE_ID = "virtual:rozenite-dev-config";
124
+ const RESOLVED_ROZENITE_DEV_CONFIG_MODULE_ID = `\0${ROZENITE_DEV_CONFIG_MODULE_ID}`;
125
+ const getRozeniteConfigPath = (projectRoot) => {
126
+ return path.resolve(projectRoot, ROZENITE_CONFIG_FILE_NAME);
127
+ };
128
+ const resolveRozeniteDevConfigModuleId = (id) => {
129
+ if (id === ROZENITE_DEV_CONFIG_MODULE_ID) {
130
+ return RESOLVED_ROZENITE_DEV_CONFIG_MODULE_ID;
131
+ }
132
+ return null;
133
+ };
134
+ const loadRozeniteDevConfigModule = (id, projectRoot) => {
135
+ if (id !== RESOLVED_ROZENITE_DEV_CONFIG_MODULE_ID) {
136
+ return null;
137
+ }
138
+ const configPath = normalizePath(getRozeniteConfigPath(projectRoot));
139
+ return `export { default } from ${JSON.stringify(`/@fs${configPath}`)};`;
140
+ };
87
141
  const TEMPLATES_DIR = path.resolve(
88
142
  fileURLToPath(import.meta.url),
89
143
  "..",
90
144
  "..",
91
145
  "templates"
92
146
  );
147
+ const PACKAGE_DIR = path.resolve(
148
+ fileURLToPath(import.meta.url),
149
+ "..",
150
+ ".."
151
+ );
152
+ const DEV_HOST_SOURCE_ENTRY_FILE = getDevHostSourceEntryFile(PACKAGE_DIR);
93
153
  const PANELS_DIR = "./panels";
94
154
  const DEVTOOLS_DIR = "devtools";
155
+ const DEV_HOST_ROUTE = "/";
95
156
  const rozeniteClientPlugin = () => {
96
157
  let projectRoot = process$1.cwd();
97
158
  let viteServer = null;
@@ -114,6 +175,18 @@ const rozeniteClientPlugin = () => {
114
175
  });
115
176
  };
116
177
  const PANEL_TEMPLATE = path.join(TEMPLATES_DIR, "panel.ejs");
178
+ const getManifestPanels = () => {
179
+ return getPanels().map((panel) => ({
180
+ name: panel.label,
181
+ source: `/${DEVTOOLS_DIR}/` + panel.htmlFile
182
+ }));
183
+ };
184
+ const getDevHostPanels = () => {
185
+ return getPanels().map((panel) => ({
186
+ label: panel.label,
187
+ source: `/${DEVTOOLS_DIR}/` + panel.htmlFile
188
+ }));
189
+ };
117
190
  const generatePanelHtmlContent = (panel) => {
118
191
  const template = fs.readFileSync(PANEL_TEMPLATE, "utf-8");
119
192
  const relativePath = path.relative(projectRoot, panel.sourceFile);
@@ -122,18 +195,63 @@ const rozeniteClientPlugin = () => {
122
195
  panelFile: relativePath
123
196
  });
124
197
  };
198
+ const getDevHostState = async () => {
199
+ const packageJSON = await getPackageJSON(projectRoot);
200
+ return {
201
+ packageName: packageJSON.name,
202
+ packageDescription: packageJSON.description,
203
+ panels: getDevHostPanels()
204
+ };
205
+ };
206
+ const serializeDevHostState = (state) => {
207
+ return JSON.stringify(state).replace(/</g, "\\u003c");
208
+ };
209
+ const toFsUrl = (filePath) => {
210
+ return `/@fs${normalizePath(filePath)}`;
211
+ };
212
+ const getDevHostAssetTags = () => {
213
+ const builtAssets = getBuiltDevHostAssets(PACKAGE_DIR);
214
+ if (!builtAssets) {
215
+ return [
216
+ {
217
+ tag: "script",
218
+ attrs: {
219
+ type: "module",
220
+ src: toFsUrl(DEV_HOST_SOURCE_ENTRY_FILE)
221
+ },
222
+ injectTo: "body"
223
+ }
224
+ ];
225
+ }
226
+ return [
227
+ ...builtAssets.styles.map((stylePath) => ({
228
+ tag: "link",
229
+ attrs: {
230
+ rel: "stylesheet",
231
+ href: toFsUrl(stylePath)
232
+ },
233
+ injectTo: "head"
234
+ })),
235
+ {
236
+ tag: "script",
237
+ attrs: {
238
+ type: "module",
239
+ src: toFsUrl(builtAssets.script)
240
+ },
241
+ injectTo: "body"
242
+ }
243
+ ];
244
+ };
125
245
  return {
126
246
  name: "rozenite-client-plugin",
127
247
  async config(config) {
128
248
  if (config.root) {
129
249
  projectRoot = config.root;
130
250
  }
131
- rozeniteConfig = await loadConfig(
132
- path.resolve(projectRoot, "rozenite.config.ts")
133
- );
251
+ rozeniteConfig = await loadConfig(getRozeniteConfigPath(projectRoot));
134
252
  const panels = getPanels();
135
253
  config.server ??= {};
136
- config.server.open = false;
254
+ config.server.open = config.server.open === true ? DEV_HOST_ROUTE : config.server.open ?? DEV_HOST_ROUTE;
137
255
  config.server.port = 8888;
138
256
  config.build ??= {};
139
257
  config.build.rollupOptions ??= {};
@@ -154,6 +272,10 @@ const rozeniteClientPlugin = () => {
154
272
  };
155
273
  },
156
274
  resolveId(id) {
275
+ const devConfigModuleId = resolveRozeniteDevConfigModuleId(id);
276
+ if (devConfigModuleId) {
277
+ return devConfigModuleId;
278
+ }
157
279
  const isPanel = getPanels().some(
158
280
  (panel) => `${DEVTOOLS_DIR}/${panel.htmlFile}` === id
159
281
  );
@@ -163,6 +285,10 @@ const rozeniteClientPlugin = () => {
163
285
  return null;
164
286
  },
165
287
  load(id) {
288
+ const devConfigModule = loadRozeniteDevConfigModule(id, projectRoot);
289
+ if (devConfigModule) {
290
+ return devConfigModule;
291
+ }
166
292
  const panel = getPanels().find(
167
293
  (panel2) => `${DEVTOOLS_DIR}/${panel2.htmlFile}` === id
168
294
  );
@@ -171,6 +297,41 @@ const rozeniteClientPlugin = () => {
171
297
  }
172
298
  return null;
173
299
  },
300
+ async transformIndexHtml(_html, context) {
301
+ const pathname = context?.path ?? DEV_HOST_ROUTE;
302
+ if (pathname !== DEV_HOST_ROUTE) {
303
+ return;
304
+ }
305
+ const state = await getDevHostState();
306
+ return [
307
+ {
308
+ tag: "script",
309
+ attrs: {
310
+ id: DEV_HOST_STATE_ELEMENT_ID,
311
+ type: "application/json"
312
+ },
313
+ children: serializeDevHostState(state),
314
+ injectTo: "body"
315
+ },
316
+ {
317
+ tag: "script",
318
+ attrs: {
319
+ type: "module"
320
+ },
321
+ children: `import rozeniteConfig from ${JSON.stringify("/@id/" + ROZENITE_DEV_CONFIG_MODULE_ID)}; window[${JSON.stringify(DEV_HOST_CONFIG_GLOBAL_KEY)}] = rozeniteConfig.dev ?? {};`,
322
+ injectTo: "body"
323
+ },
324
+ {
325
+ tag: "meta",
326
+ attrs: {
327
+ name: "rozenite-dev-host",
328
+ content: "true"
329
+ },
330
+ injectTo: "head"
331
+ },
332
+ ...getDevHostAssetTags()
333
+ ];
334
+ },
174
335
  async configureServer(server) {
175
336
  viteServer = server;
176
337
  const packageJSON = await getPackageJSON(projectRoot);
@@ -190,7 +351,17 @@ const rozeniteClientPlugin = () => {
190
351
  return;
191
352
  }
192
353
  const panels = getPanels();
193
- const url = req.url || "/";
354
+ const requestUrl = req.url || "/";
355
+ const url = new URL(requestUrl, "http://localhost").pathname;
356
+ if (url === DEV_HOST_ROUTE) {
357
+ server.transformIndexHtml(requestUrl, getDevHostHtmlTemplate()).then((html) => {
358
+ res.setHeader("Content-Type", "text/html");
359
+ res.end(html);
360
+ }).catch((err) => {
361
+ next(err);
362
+ });
363
+ return;
364
+ }
194
365
  if (url === "/rozenite.json") {
195
366
  res.setHeader("Content-Type", "application/json");
196
367
  res.end(
@@ -199,10 +370,7 @@ const rozeniteClientPlugin = () => {
199
370
  name: packageJSON.name,
200
371
  version: packageJSON.version,
201
372
  description: packageJSON.description,
202
- panels: panels.map((panel2) => ({
203
- name: panel2.label,
204
- source: `/${DEVTOOLS_DIR}/` + panel2.htmlFile
205
- }))
373
+ panels: getManifestPanels()
206
374
  },
207
375
  null,
208
376
  2
@@ -215,7 +383,7 @@ const rozeniteClientPlugin = () => {
215
383
  );
216
384
  if (panel) {
217
385
  const htmlContent = generatePanelHtmlContent(panel);
218
- server.transformIndexHtml(req.url || "/", htmlContent).then((html) => {
386
+ server.transformIndexHtml(requestUrl, htmlContent).then((html) => {
219
387
  res.setHeader("Content-Type", "text/html");
220
388
  res.end(html);
221
389
  }).catch((err) => {
@@ -240,7 +408,6 @@ const rozeniteClientPlugin = () => {
240
408
  });
241
409
  },
242
410
  async generateBundle() {
243
- const panels = getPanels();
244
411
  const packageJSON = await getPackageJSON(projectRoot);
245
412
  this.emitFile({
246
413
  type: "asset",
@@ -249,10 +416,7 @@ const rozeniteClientPlugin = () => {
249
416
  name: packageJSON.name,
250
417
  version: packageJSON.version,
251
418
  description: packageJSON.description,
252
- panels: panels.map((panel) => ({
253
- name: panel.label,
254
- source: `/${DEVTOOLS_DIR}/` + panel.htmlFile
255
- }))
419
+ panels: getManifestPanels()
256
420
  })
257
421
  });
258
422
  }
@@ -496,6 +660,28 @@ function requirePlugin() {
496
660
  }
497
661
  };
498
662
  }
663
+ const normalizeRolledUpDeclarations = (content) => {
664
+ const valueDeclarationNames = /* @__PURE__ */ new Set();
665
+ content.replace(
666
+ /^\s*declare\s+(?:const|let|var|function)\s+([A-Za-z_$][\w$]*)\b/gm,
667
+ (_, name) => {
668
+ valueDeclarationNames.add(name);
669
+ return _;
670
+ }
671
+ );
672
+ const normalizeTypeReference = (name) => valueDeclarationNames.has(name) ? `typeof ${name}` : name;
673
+ return content.replace(
674
+ /^(\s*(?:export\s+)?declare\s+(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*:\s*)([A-Za-z_$][\w$]*)(\s*;)$/gm,
675
+ (_, prefix, name, suffix) => {
676
+ return `${prefix}${normalizeTypeReference(name)}${suffix}`;
677
+ }
678
+ ).replace(
679
+ /^(\s*(?:export\s+)?declare\s+type\s+[A-Za-z_$][\w$]*\s*=\s*)([A-Za-z_$][\w$]*)(\s*;)$/gm,
680
+ (_, prefix, name, suffix) => {
681
+ return `${prefix}${normalizeTypeReference(name)}${suffix}`;
682
+ }
683
+ );
684
+ };
499
685
  const bundleTargetDeclarations = async (projectRoot, target) => {
500
686
  const targetRoot = path.join(projectRoot, "dist", target);
501
687
  const publicEntryPath = path.join(targetRoot, "index.d.ts");
@@ -561,6 +747,11 @@ const bundleTargetDeclarations = async (projectRoot, target) => {
561
747
  }
562
748
  await fs$1.rm(entryPath, { force: true });
563
749
  await fs$1.rename(tempOutputPath, publicEntryPath);
750
+ const bundledContent = await fs$1.readFile(publicEntryPath, "utf8");
751
+ const normalizedContent = normalizeRolledUpDeclarations(bundledContent);
752
+ if (normalizedContent !== bundledContent) {
753
+ await fs$1.writeFile(publicEntryPath, normalizedContent);
754
+ }
564
755
  await fs$1.rm(srcDeclarationsPath, { recursive: true, force: true });
565
756
  };
566
757
  const dtsPlugin = "default" in maybeDtsPlugin ? maybeDtsPlugin.default : maybeDtsPlugin;