muon-ui 0.2.0 → 0.4.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.
Files changed (47) hide show
  1. package/README.md +3 -2
  2. package/dist/cli.cjs +271 -11
  3. package/dist/cli.cjs.map +1 -1
  4. package/dist/index.cjs +2 -2
  5. package/dist/index.mjs +2 -2
  6. package/dist/native/linux64/muon-bootstrap +0 -0
  7. package/dist/native/linux64/muon-prepare +0 -0
  8. package/dist/native/linuxarm/muon-bootstrap +0 -0
  9. package/dist/native/linuxarm/muon-prepare +0 -0
  10. package/dist/native/linuxarm64/muon-bootstrap +0 -0
  11. package/dist/native/linuxarm64/muon-prepare +0 -0
  12. package/dist/native/windows32/muon-bootstrap.exe +0 -0
  13. package/dist/native/windows32/muon-prepare.exe +0 -0
  14. package/dist/native/windows64/muon-bootstrap.exe +0 -0
  15. package/dist/native/windows64/muon-prepare.exe +0 -0
  16. package/dist/runtime/linux64/LICENSE_muon +97 -0
  17. package/dist/runtime/linux64/libmuon-ui.so +0 -0
  18. package/dist/runtime/linux64/muon-core +0 -0
  19. package/dist/runtime/linuxarm/LICENSE_muon +97 -0
  20. package/dist/runtime/linuxarm/libmuon-ui.so +0 -0
  21. package/dist/runtime/linuxarm/muon-core +0 -0
  22. package/dist/runtime/linuxarm64/LICENSE_muon +97 -0
  23. package/dist/runtime/linuxarm64/libmuon-ui.so +0 -0
  24. package/dist/runtime/linuxarm64/muon-core +0 -0
  25. package/dist/runtime/windows32/LICENSE_muon +97 -0
  26. package/dist/runtime/windows32/libcardio.dll +0 -0
  27. package/dist/runtime/windows32/libgcc_s_dw2-1.dll +0 -0
  28. package/dist/runtime/windows32/libmuon-ui.dll +0 -0
  29. package/dist/runtime/windows32/libstdc++-6.dll +0 -0
  30. package/dist/runtime/windows32/muon-core.exe +0 -0
  31. package/dist/runtime/windows64/LICENSE_muon +97 -0
  32. package/dist/runtime/windows64/libcardio.dll +0 -0
  33. package/dist/runtime/windows64/libgcc_s_seh-1.dll +0 -0
  34. package/dist/runtime/windows64/libmuon-ui.dll +0 -0
  35. package/dist/runtime/windows64/libstdc++-6.dll +0 -0
  36. package/dist/runtime/windows64/muon-core.exe +0 -0
  37. package/dist/{build-BxDRaTmF.cjs → vite-options-C4evRLpv.cjs} +395 -29
  38. package/dist/vite-options-C4evRLpv.cjs.map +1 -0
  39. package/dist/vite.cjs +9 -230
  40. package/dist/vite.cjs.map +1 -1
  41. package/dist/vite.mjs +111 -36
  42. package/dist/vite.mjs.map +1 -1
  43. package/images/vscode.png +0 -0
  44. package/muon.d.ts +27 -0
  45. package/package.json +9 -8
  46. package/vite.d.ts +18 -2
  47. package/dist/build-BxDRaTmF.cjs.map +0 -1
package/dist/vite.cjs CHANGED
@@ -1,251 +1,30 @@
1
1
  /*!
2
2
  * name: muon-ui
3
- * version: 0.2.0
3
+ * version: 0.4.0
4
4
  * description: A multi-platform GUI application framework that uses CEF as its backend
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/muon-ui.git
8
- * git.commit.hash: 6251ff88aafa8ae873657f39aed1ebba2fa329a4
8
+ * git.commit.hash: 44d549142c8cbfa13cb29d10be2568652a68bf50
9
9
  */
10
- const require_build = require("./build-BxDRaTmF.cjs");
11
- let node_fs = require("node:fs");
12
- let node_fs_promises = require("node:fs/promises");
13
- let node_url = require("node:url");
10
+ const require_vite_options = require("./vite-options-C4evRLpv.cjs");
14
11
  let node_path = require("node:path");
15
- let node_os = require("node:os");
16
- //#region src/vite-internals.ts
17
- var import_dist = require_build.require_dist();
18
- var getServerOpenValue = (server) => {
19
- const open = server.config.server.open;
20
- return open === true || typeof open === "string" ? open : false;
21
- };
22
- var resolveFromRoot = (root, path) => (0, node_path.isAbsolute)(path) ? path : (0, node_path.resolve)(root, path);
23
- var moduleDirectory = typeof __dirname === "string" ? __dirname : (0, node_path.dirname)((0, node_url.fileURLToPath)({}.url));
24
- var defaultProjectConfigFileNames = [
25
- "muon.json5",
26
- "muon.jsonc",
27
- "muon.json"
28
- ];
29
- /**
30
- * Resolves the muon-core runtime directory used by the Vite plugin.
31
- *
32
- * @param options Runtime path resolution inputs.
33
- * @returns Absolute or package-relative runtime directory path.
34
- */
35
- var resolveMuonRuntimePath = ({ root, target, muonPath, packageDirectory = moduleDirectory }) => muonPath === void 0 ? (0, node_path.join)(packageDirectory, "runtime", target) : resolveFromRoot(root, muonPath);
36
- var getMuonExecutablePath = (runtimePath, platform) => (0, node_path.join)(runtimePath, platform === "win32" ? "muon-core.exe" : "muon-core");
37
- var getLaunchScriptFileName = (platform) => platform === "win32" ? "open-muon.cmd" : "open-muon.sh";
38
- var quotePosix = (value) => `'${value.replaceAll("'", "'\\''")}'`;
39
- var getPlatformDirectoryName = (path, platform) => platform === "win32" ? node_path.win32.dirname(path) : (0, node_path.dirname)(path);
40
- var getOptionalPosixValue = (value) => value === void 0 ? "''" : quotePosix(value);
41
- var createPosixMuonLaunchScript = ({ muonExecutablePath, projectConfigPath, overrideConfigPath }) => `#!/usr/bin/env bash
42
- set -euo pipefail
43
- MUON_EXECUTABLE=${quotePosix(muonExecutablePath)}
44
- MUON_EXECUTABLE_DIRECTORY=${quotePosix(getPlatformDirectoryName(muonExecutablePath, "linux"))}
45
- MUON_PROJECT_CONFIG=${getOptionalPosixValue(projectConfigPath)}
46
- MUON_OVERRIDE_CONFIG=${quotePosix(overrideConfigPath)}
47
-
48
- MUON_CONFIG_ARGS=()
49
- if [[ -n "$MUON_PROJECT_CONFIG" ]]; then
50
- if [[ ! -f "$MUON_PROJECT_CONFIG" ]]; then
51
- echo "Muon startup failed: project config does not exist: $MUON_PROJECT_CONFIG" >&2
52
- exit 1
53
- fi
54
- MUON_CONFIG_ARGS+=("-c" "$MUON_PROJECT_CONFIG")
55
- fi
56
-
57
- if [[ ! -x "$MUON_EXECUTABLE" ]]; then
58
- echo "Muon startup failed: executable does not exist or is not executable: $MUON_EXECUTABLE" >&2
59
- exit 1
60
- fi
61
-
62
- if [[ ! -f "$MUON_OVERRIDE_CONFIG" ]]; then
63
- echo "Muon startup failed: generated override config does not exist: $MUON_OVERRIDE_CONFIG" >&2
64
- exit 1
65
- fi
66
- MUON_CONFIG_ARGS+=("-c" "$MUON_OVERRIDE_CONFIG")
67
-
68
- cd "$MUON_EXECUTABLE_DIRECTORY"
69
- exec "$MUON_EXECUTABLE" "\${MUON_CONFIG_ARGS[@]}"
70
- `;
71
- var escapeWindowsCmdValue = (value) => value.replaceAll("%", "%%").replaceAll("\r", "").replaceAll("\n", "");
72
- var getOptionalWindowsCmdValue = (value) => value === void 0 ? "" : escapeWindowsCmdValue(value);
73
- var createWindowsMuonLaunchScript = ({ muonExecutablePath, projectConfigPath, overrideConfigPath }) => `@echo off
74
- setlocal
75
- set "MUON_EXECUTABLE=${escapeWindowsCmdValue(muonExecutablePath)}"
76
- set "MUON_EXECUTABLE_DIRECTORY=${escapeWindowsCmdValue(getPlatformDirectoryName(muonExecutablePath, "win32"))}"
77
- set "MUON_PROJECT_CONFIG=${getOptionalWindowsCmdValue(projectConfigPath)}"
78
- set "MUON_OVERRIDE_CONFIG=${escapeWindowsCmdValue(overrideConfigPath)}"
79
-
80
- if not exist "%MUON_EXECUTABLE%" (
81
- echo Muon startup failed: executable does not exist: %MUON_EXECUTABLE% 1>&2
82
- exit /b 1
83
- )
84
-
85
- if not exist "%MUON_OVERRIDE_CONFIG%" (
86
- echo Muon startup failed: generated override config does not exist: %MUON_OVERRIDE_CONFIG% 1>&2
87
- exit /b 1
88
- )
89
-
90
- pushd "%MUON_EXECUTABLE_DIRECTORY%"
91
- if defined MUON_PROJECT_CONFIG (
92
- if not exist "%MUON_PROJECT_CONFIG%" (
93
- echo Muon startup failed: project config does not exist: %MUON_PROJECT_CONFIG% 1>&2
94
- popd
95
- exit /b 1
96
- )
97
- "%MUON_EXECUTABLE%" -c "%MUON_PROJECT_CONFIG%" -c "%MUON_OVERRIDE_CONFIG%"
98
- ) else (
99
- "%MUON_EXECUTABLE%" -c "%MUON_OVERRIDE_CONFIG%"
100
- )
101
- set "MUON_EXIT_CODE=%ERRORLEVEL%"
102
- popd
103
- exit /b %MUON_EXIT_CODE%
104
- `;
105
- var createMuonLaunchScript = (options) => options.platform === "win32" ? createWindowsMuonLaunchScript(options) : createPosixMuonLaunchScript(options);
106
- var getBaseUrl = (server) => server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];
107
- var getStartUrl = (server, openValue) => {
108
- const baseUrl = getBaseUrl(server);
109
- if (baseUrl === void 0) return;
110
- return typeof openValue === "string" ? new URL(openValue, baseUrl).href : baseUrl;
111
- };
112
- var getWebSocketOrigin = (startUrl) => {
113
- const url = new URL(startUrl);
114
- if (url.protocol === "https:") url.protocol = "wss:";
115
- else if (url.protocol === "http:") url.protocol = "ws:";
116
- return url.origin;
117
- };
118
- var createMuonOverrideConfig = (startUrl) => {
119
- const origin = new URL(startUrl).origin;
120
- return {
121
- browser: {
122
- startPage: startUrl,
123
- plugin: { allow: [`${origin}/**`] }
124
- },
125
- network: { allow: [`${origin}/**`, `${getWebSocketOrigin(startUrl)}/**`] }
126
- };
127
- };
128
- var writeMuonOverrideConfig = (server, openValue, overrideConfigPath) => {
129
- const startUrl = getStartUrl(server, openValue);
130
- if (startUrl === void 0) {
131
- server.config.logger.warn("Muon Vite plugin could not resolve a Vite URL.");
132
- return;
133
- }
134
- (0, node_fs.writeFileSync)(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl), null, 2)}\n`);
135
- };
136
- var createRuntimePaths = async (server, stagePath, platform, projectConfigPath) => {
137
- const temporaryDirectory = await (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "muon-vite-"));
138
- return {
139
- temporaryDirectory,
140
- launchScriptPath: (0, node_path.join)(temporaryDirectory, getLaunchScriptFileName(platform)),
141
- overrideConfigPath: (0, node_path.join)(temporaryDirectory, "muon.vite.json"),
142
- projectConfigPath,
143
- muonExecutablePath: getMuonExecutablePath(stagePath, platform)
144
- };
145
- };
146
- var fileExists = async (path) => {
147
- try {
148
- await (0, node_fs_promises.access)(path, node_fs.constants.F_OK);
149
- return true;
150
- } catch {
151
- return false;
152
- }
153
- };
154
- var isJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
155
- var getErrorMessage = (error) => error instanceof Error ? error.message : String(error);
156
- var resolveProjectConfigPath = async (server) => {
157
- for (const fileName of defaultProjectConfigFileNames) {
158
- const candidatePath = (0, node_path.join)(server.config.root, fileName);
159
- if (!await fileExists(candidatePath)) continue;
160
- try {
161
- if (!isJsonObject((0, import_dist.parse)(await (0, node_fs_promises.readFile)(candidatePath, "utf8")))) throw new Error("muon config root must be an object");
162
- return candidatePath;
163
- } catch (error) {
164
- server.config.logger.warn(`Muon project config will be ignored because it could not be read or parsed: ${candidatePath}: ${getErrorMessage(error)}`);
165
- return;
166
- }
167
- }
168
- server.config.logger.warn(`Muon project config was not found in ${server.config.root}; launching with generated Vite config only.`);
169
- };
170
- var writeLaunchScript = async (paths, platform) => {
171
- await (0, node_fs_promises.writeFile)(paths.launchScriptPath, createMuonLaunchScript({
172
- muonExecutablePath: paths.muonExecutablePath,
173
- projectConfigPath: paths.projectConfigPath,
174
- overrideConfigPath: paths.overrideConfigPath,
175
- platform
176
- }));
177
- if (platform !== "win32") await (0, node_fs_promises.chmod)(paths.launchScriptPath, 448);
178
- };
179
- var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, architecture, environment }) => {
180
- const openValue = getServerOpenValue(server);
181
- if (openValue === false || server.httpServer === null) return;
182
- const target = require_build.getDefaultMuonPrepareTarget(platform, architecture);
183
- const preparedRuntime = await require_build.runMuonPrepare({
184
- muonPath: resolveMuonRuntimePath({
185
- root: server.config.root,
186
- target,
187
- muonPath: pluginOptions.muonPath
188
- }),
189
- cefPath: pluginOptions.cefPath === void 0 ? void 0 : resolveFromRoot(server.config.root, pluginOptions.cefPath),
190
- stageDir: pluginOptions.stagePath === void 0 ? (0, node_path.resolve)(server.config.root, ".muon", target) : resolveFromRoot(server.config.root, pluginOptions.stagePath),
191
- target,
192
- cacheDir: environment.MUON_CACHE_DIR,
193
- force: false,
194
- quiet: false,
195
- prepareExecutablePath: void 0,
196
- environment,
197
- cwd: server.config.root
198
- });
199
- if (preparedRuntime.stagePath === void 0) throw new Error("muon-prepare did not return a staged runtime path.");
200
- const paths = await createRuntimePaths(server, preparedRuntime.stagePath, platform, await resolveProjectConfigPath(server));
201
- await writeLaunchScript(paths, platform);
202
- const previousBrowser = environment.BROWSER;
203
- environment.BROWSER = paths.launchScriptPath;
204
- let cleanupPromise = void 0;
205
- const cleanup = async () => {
206
- if (cleanupPromise !== void 0) return cleanupPromise;
207
- cleanupPromise = (async () => {
208
- if (previousBrowser === void 0) delete environment.BROWSER;
209
- else environment.BROWSER = previousBrowser;
210
- await (0, node_fs_promises.rm)(paths.temporaryDirectory, {
211
- recursive: true,
212
- force: true
213
- });
214
- })();
215
- return cleanupPromise;
216
- };
217
- const originalClose = server.close.bind(server);
218
- server.close = async () => {
219
- try {
220
- await originalClose();
221
- } finally {
222
- await cleanup();
223
- }
224
- };
225
- server.httpServer.once("close", () => {
226
- cleanup();
227
- });
228
- server.httpServer.once("listening", () => {
229
- writeMuonOverrideConfig(server, openValue, paths.overrideConfigPath);
230
- });
231
- };
232
- //#endregion
233
12
  //#region src/vite.ts
234
13
  /**
235
- * Creates a Vite plugin that launches Muon through Vite's server.open flow.
14
+ * Creates a Vite plugin that launches Muon during Vite dev startup.
236
15
  *
237
- * @param options Muon runtime location used for development startup.
16
+ * @param options Muon plugin options used for development startup and build.
238
17
  * @returns Vite plugin instance.
239
18
  */
240
19
  var muon = (options = {}) => {
241
20
  let resolvedConfig = void 0;
242
- return {
21
+ return require_vite_options.attachMuonVitePluginOptions({
243
22
  name: "muon",
244
23
  configResolved: (config) => {
245
24
  resolvedConfig = config;
246
25
  },
247
26
  configureServer: async (server) => {
248
- await startMuonViteBrowserBridge({
27
+ await require_vite_options.startMuonViteBrowserBridge({
249
28
  server,
250
29
  pluginOptions: options,
251
30
  platform: process.platform,
@@ -257,9 +36,9 @@ var muon = (options = {}) => {
257
36
  if (resolvedConfig === void 0 || resolvedConfig.command !== "build") return;
258
37
  if (options.build === false) return;
259
38
  const buildOptions = typeof options.build === "object" ? options.build : {};
260
- await require_build.buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions));
39
+ await require_vite_options.buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions));
261
40
  }
262
- };
41
+ }, options);
263
42
  };
264
43
  var createMuonBuildOptions = (config, buildOptions) => {
265
44
  const outDir = (0, node_path.isAbsolute)(config.build.outDir) ? config.build.outDir : (0, node_path.resolve)(config.root, config.build.outDir);
package/dist/vite.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.cjs","names":[],"sources":["../src/vite-internals.ts","../src/vite.ts"],"sourcesContent":["// muon - Multi-platform GUI application framework that uses CEF as its backend\n// Copyright (c) Kouji Matsui. (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/muon\n\nimport { constants, writeFileSync } from \"node:fs\";\nimport {\n access,\n chmod,\n mkdtemp,\n readFile,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, isAbsolute, join, resolve, win32 } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { parse } from \"json5\";\nimport type { ViteDevServer } from \"vite\";\n\nimport { getDefaultMuonPrepareTarget, runMuonPrepare } from \"./prepare.js\";\nimport type { MuonVitePluginOptions } from \"./vite.js\";\n\nexport interface MuonLaunchScriptOptions {\n muonExecutablePath: string;\n projectConfigPath: string | undefined;\n overrideConfigPath: string;\n platform: NodeJS.Platform;\n}\n\ninterface MuonViteSessionOptions {\n server: ViteDevServer;\n pluginOptions: MuonVitePluginOptions;\n platform: NodeJS.Platform;\n architecture: NodeJS.Architecture;\n environment: NodeJS.ProcessEnv;\n}\n\ninterface MuonRuntimePaths {\n temporaryDirectory: string;\n launchScriptPath: string;\n overrideConfigPath: string;\n projectConfigPath: string | undefined;\n muonExecutablePath: string;\n}\n\ninterface MuonOverrideConfig {\n browser: {\n startPage: string;\n plugin: {\n allow: string[];\n };\n };\n network: {\n allow: string[];\n };\n}\n\n/**\n * Options for resolving a Muon runtime directory used by the Vite plugin.\n */\nexport interface MuonRuntimePathOptions {\n /**\n * Vite project root used to resolve explicit relative paths.\n */\n root: string;\n\n /**\n * Muon runtime target such as linux64, linuxarm, linuxarm64, windows32, or windows64.\n */\n target: string;\n\n /**\n * Explicit custom muon-core runtime path.\n */\n muonPath: string | undefined;\n\n /**\n * Directory containing the packaged Muon JavaScript files.\n *\n * @remarks This is injectable for tests. Production code uses the module directory.\n */\n packageDirectory?: string;\n}\n\nconst getServerOpenValue = (\n server: ViteDevServer,\n): boolean | string | false => {\n const open = server.config.server.open;\n return open === true || typeof open === \"string\" ? open : false;\n};\n\nconst resolveFromRoot = (root: string, path: string): string =>\n isAbsolute(path) ? path : resolve(root, path);\n\nconst moduleDirectory =\n typeof __dirname === \"string\"\n ? __dirname\n : dirname(fileURLToPath(import.meta.url));\nconst defaultProjectConfigFileNames = [\"muon.json5\", \"muon.jsonc\", \"muon.json\"];\n\n/**\n * Resolves the muon-core runtime directory used by the Vite plugin.\n *\n * @param options Runtime path resolution inputs.\n * @returns Absolute or package-relative runtime directory path.\n */\nexport const resolveMuonRuntimePath = ({\n root,\n target,\n muonPath,\n packageDirectory = moduleDirectory,\n}: MuonRuntimePathOptions): string =>\n muonPath === undefined\n ? join(packageDirectory, \"runtime\", target)\n : resolveFromRoot(root, muonPath);\n\nexport const getMuonExecutablePath = (\n runtimePath: string,\n platform: NodeJS.Platform,\n): string =>\n join(runtimePath, platform === \"win32\" ? \"muon-core.exe\" : \"muon-core\");\n\nconst getLaunchScriptFileName = (platform: NodeJS.Platform): string =>\n platform === \"win32\" ? \"open-muon.cmd\" : \"open-muon.sh\";\n\nconst quotePosix = (value: string): string =>\n `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nconst getPlatformDirectoryName = (\n path: string,\n platform: NodeJS.Platform,\n): string => (platform === \"win32\" ? win32.dirname(path) : dirname(path));\n\nconst getOptionalPosixValue = (value: string | undefined): string =>\n value === undefined ? \"''\" : quotePosix(value);\n\nconst createPosixMuonLaunchScript = ({\n muonExecutablePath,\n projectConfigPath,\n overrideConfigPath,\n}: MuonLaunchScriptOptions): string => `#!/usr/bin/env bash\nset -euo pipefail\nMUON_EXECUTABLE=${quotePosix(muonExecutablePath)}\nMUON_EXECUTABLE_DIRECTORY=${quotePosix(getPlatformDirectoryName(muonExecutablePath, \"linux\"))}\nMUON_PROJECT_CONFIG=${getOptionalPosixValue(projectConfigPath)}\nMUON_OVERRIDE_CONFIG=${quotePosix(overrideConfigPath)}\n\nMUON_CONFIG_ARGS=()\nif [[ -n \"$MUON_PROJECT_CONFIG\" ]]; then\n if [[ ! -f \"$MUON_PROJECT_CONFIG\" ]]; then\n echo \"Muon startup failed: project config does not exist: $MUON_PROJECT_CONFIG\" >&2\n exit 1\n fi\n MUON_CONFIG_ARGS+=(\"-c\" \"$MUON_PROJECT_CONFIG\")\nfi\n\nif [[ ! -x \"$MUON_EXECUTABLE\" ]]; then\n echo \"Muon startup failed: executable does not exist or is not executable: $MUON_EXECUTABLE\" >&2\n exit 1\nfi\n\nif [[ ! -f \"$MUON_OVERRIDE_CONFIG\" ]]; then\n echo \"Muon startup failed: generated override config does not exist: $MUON_OVERRIDE_CONFIG\" >&2\n exit 1\nfi\nMUON_CONFIG_ARGS+=(\"-c\" \"$MUON_OVERRIDE_CONFIG\")\n\ncd \"$MUON_EXECUTABLE_DIRECTORY\"\nexec \"$MUON_EXECUTABLE\" \"\\${MUON_CONFIG_ARGS[@]}\"\n`;\n\nconst escapeWindowsCmdValue = (value: string): string =>\n value.replaceAll(\"%\", \"%%\").replaceAll(\"\\r\", \"\").replaceAll(\"\\n\", \"\");\n\nconst getOptionalWindowsCmdValue = (value: string | undefined): string =>\n value === undefined ? \"\" : escapeWindowsCmdValue(value);\n\nconst createWindowsMuonLaunchScript = ({\n muonExecutablePath,\n projectConfigPath,\n overrideConfigPath,\n}: MuonLaunchScriptOptions): string => `@echo off\nsetlocal\nset \"MUON_EXECUTABLE=${escapeWindowsCmdValue(muonExecutablePath)}\"\nset \"MUON_EXECUTABLE_DIRECTORY=${escapeWindowsCmdValue(getPlatformDirectoryName(muonExecutablePath, \"win32\"))}\"\nset \"MUON_PROJECT_CONFIG=${getOptionalWindowsCmdValue(projectConfigPath)}\"\nset \"MUON_OVERRIDE_CONFIG=${escapeWindowsCmdValue(overrideConfigPath)}\"\n\nif not exist \"%MUON_EXECUTABLE%\" (\n echo Muon startup failed: executable does not exist: %MUON_EXECUTABLE% 1>&2\n exit /b 1\n)\n\nif not exist \"%MUON_OVERRIDE_CONFIG%\" (\n echo Muon startup failed: generated override config does not exist: %MUON_OVERRIDE_CONFIG% 1>&2\n exit /b 1\n)\n\npushd \"%MUON_EXECUTABLE_DIRECTORY%\"\nif defined MUON_PROJECT_CONFIG (\n if not exist \"%MUON_PROJECT_CONFIG%\" (\n echo Muon startup failed: project config does not exist: %MUON_PROJECT_CONFIG% 1>&2\n popd\n exit /b 1\n )\n \"%MUON_EXECUTABLE%\" -c \"%MUON_PROJECT_CONFIG%\" -c \"%MUON_OVERRIDE_CONFIG%\"\n) else (\n \"%MUON_EXECUTABLE%\" -c \"%MUON_OVERRIDE_CONFIG%\"\n)\nset \"MUON_EXIT_CODE=%ERRORLEVEL%\"\npopd\nexit /b %MUON_EXIT_CODE%\n`;\n\nexport const createMuonLaunchScript = (\n options: MuonLaunchScriptOptions,\n): string =>\n options.platform === \"win32\"\n ? createWindowsMuonLaunchScript(options)\n : createPosixMuonLaunchScript(options);\n\nconst getBaseUrl = (server: ViteDevServer): string | undefined =>\n server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];\n\nconst getStartUrl = (\n server: ViteDevServer,\n openValue: boolean | string,\n): string | undefined => {\n const baseUrl = getBaseUrl(server);\n if (baseUrl === undefined) {\n return undefined;\n }\n return typeof openValue === \"string\"\n ? new URL(openValue, baseUrl).href\n : baseUrl;\n};\n\nconst getWebSocketOrigin = (startUrl: string): string => {\n const url = new URL(startUrl);\n if (url.protocol === \"https:\") {\n url.protocol = \"wss:\";\n } else if (url.protocol === \"http:\") {\n url.protocol = \"ws:\";\n }\n return url.origin;\n};\n\nconst createMuonOverrideConfig = (startUrl: string): MuonOverrideConfig => {\n const origin = new URL(startUrl).origin;\n return {\n browser: {\n startPage: startUrl,\n plugin: {\n allow: [`${origin}/**`],\n },\n },\n network: {\n allow: [`${origin}/**`, `${getWebSocketOrigin(startUrl)}/**`],\n },\n };\n};\n\nconst writeMuonOverrideConfig = (\n server: ViteDevServer,\n openValue: boolean | string,\n overrideConfigPath: string,\n): void => {\n const startUrl = getStartUrl(server, openValue);\n if (startUrl === undefined) {\n server.config.logger.warn(\"Muon Vite plugin could not resolve a Vite URL.\");\n return;\n }\n writeFileSync(\n overrideConfigPath,\n `${JSON.stringify(createMuonOverrideConfig(startUrl), null, 2)}\\n`,\n );\n};\n\nconst createRuntimePaths = async (\n server: ViteDevServer,\n stagePath: string,\n platform: NodeJS.Platform,\n projectConfigPath: string | undefined,\n): Promise<MuonRuntimePaths> => {\n const temporaryDirectory = await mkdtemp(join(tmpdir(), \"muon-vite-\"));\n return {\n temporaryDirectory,\n launchScriptPath: join(\n temporaryDirectory,\n getLaunchScriptFileName(platform),\n ),\n overrideConfigPath: join(temporaryDirectory, \"muon.vite.json\"),\n projectConfigPath,\n muonExecutablePath: getMuonExecutablePath(stagePath, platform),\n };\n};\n\nconst fileExists = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nconst isJsonObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst getErrorMessage = (error: unknown): string =>\n error instanceof Error ? error.message : String(error);\n\nconst resolveProjectConfigPath = async (\n server: ViteDevServer,\n): Promise<string | undefined> => {\n for (const fileName of defaultProjectConfigFileNames) {\n const candidatePath = join(server.config.root, fileName);\n if (!(await fileExists(candidatePath))) {\n continue;\n }\n\n try {\n const parsed = parse(await readFile(candidatePath, \"utf8\"));\n if (!isJsonObject(parsed)) {\n throw new Error(\"muon config root must be an object\");\n }\n return candidatePath;\n } catch (error) {\n server.config.logger.warn(\n `Muon project config will be ignored because it could not be read or parsed: ${candidatePath}: ${getErrorMessage(error)}`,\n );\n return undefined;\n }\n }\n\n server.config.logger.warn(\n `Muon project config was not found in ${server.config.root}; launching with generated Vite config only.`,\n );\n return undefined;\n};\n\nconst writeLaunchScript = async (\n paths: MuonRuntimePaths,\n platform: NodeJS.Platform,\n): Promise<void> => {\n await writeFile(\n paths.launchScriptPath,\n createMuonLaunchScript({\n muonExecutablePath: paths.muonExecutablePath,\n projectConfigPath: paths.projectConfigPath,\n overrideConfigPath: paths.overrideConfigPath,\n platform,\n }),\n );\n if (platform !== \"win32\") {\n await chmod(paths.launchScriptPath, 0o700);\n }\n};\n\nexport const startMuonViteBrowserBridge = async ({\n server,\n pluginOptions,\n platform,\n architecture,\n environment,\n}: MuonViteSessionOptions): Promise<void> => {\n const openValue = getServerOpenValue(server);\n if (openValue === false || server.httpServer === null) {\n return;\n }\n\n const target = getDefaultMuonPrepareTarget(platform, architecture);\n const muonPath = resolveMuonRuntimePath({\n root: server.config.root,\n target,\n muonPath: pluginOptions.muonPath,\n });\n const cefPath =\n pluginOptions.cefPath === undefined\n ? undefined\n : resolveFromRoot(server.config.root, pluginOptions.cefPath);\n const stagePath =\n pluginOptions.stagePath === undefined\n ? resolve(server.config.root, \".muon\", target)\n : resolveFromRoot(server.config.root, pluginOptions.stagePath);\n const preparedRuntime = await runMuonPrepare({\n muonPath,\n cefPath,\n stageDir: stagePath,\n target,\n cacheDir: environment.MUON_CACHE_DIR,\n force: false,\n quiet: false,\n prepareExecutablePath: undefined,\n environment,\n cwd: server.config.root,\n });\n if (preparedRuntime.stagePath === undefined) {\n throw new Error(\"muon-prepare did not return a staged runtime path.\");\n }\n const paths = await createRuntimePaths(\n server,\n preparedRuntime.stagePath,\n platform,\n await resolveProjectConfigPath(server),\n );\n await writeLaunchScript(paths, platform);\n const previousBrowser = environment.BROWSER;\n environment.BROWSER = paths.launchScriptPath;\n\n let cleanupPromise: Promise<void> | undefined = undefined;\n const cleanup = async (): Promise<void> => {\n if (cleanupPromise !== undefined) {\n return cleanupPromise;\n }\n cleanupPromise = (async () => {\n if (previousBrowser === undefined) {\n delete environment.BROWSER;\n } else {\n environment.BROWSER = previousBrowser;\n }\n await rm(paths.temporaryDirectory, { recursive: true, force: true });\n })();\n return cleanupPromise;\n };\n\n const originalClose = server.close.bind(server);\n server.close = async (): Promise<void> => {\n try {\n await originalClose();\n } finally {\n await cleanup();\n }\n };\n server.httpServer.once(\"close\", () => {\n void cleanup();\n });\n server.httpServer.once(\"listening\", () => {\n writeMuonOverrideConfig(server, openValue, paths.overrideConfigPath);\n });\n};\n","// muon - Multi-platform GUI application framework that uses CEF as its backend\n// Copyright (c) Kouji Matsui. (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/muon\n\nimport type { Plugin } from \"vite\";\nimport type { ResolvedConfig } from \"vite\";\nimport { isAbsolute, resolve } from \"node:path\";\n\nimport { buildMuonApp, type MuonBuildOptions } from \"./build.js\";\nimport { startMuonViteBrowserBridge } from \"./vite-internals.js\";\n\n/**\n * Options for generating Muon app distributions after Vite build.\n */\nexport interface MuonViteBuildOptions {\n /**\n * Target aliases or internal target names to build.\n */\n targets?: readonly string[];\n\n /**\n * Build every supported target from the installed package.\n */\n allTargets?: boolean;\n\n /**\n * File name used for the app launcher.\n *\n * @remarks The .exe suffix is added automatically for Windows targets.\n */\n appName?: string;\n\n /**\n * Parent directory that receives dist-linux-amd64/ style outputs.\n */\n outputRoot?: string;\n\n /**\n * Muon config path to embed.\n */\n configPath?: string;\n\n /**\n * Directory containing package runtime/ and native/ folders.\n *\n * @remarks This defaults to the installed muon package dist directory.\n */\n packageDirectory?: string;\n\n /**\n * Asset salt override for deterministic tests.\n *\n * @remarks Production builds should omit this option.\n */\n assetSalt?: Uint8Array;\n}\n\n/**\n * Options for the Muon Vite development plugin.\n */\nexport interface MuonVitePluginOptions {\n /**\n * Directory containing muon-core runtime files such as muon-core and plugins.\n *\n * @remarks Relative paths are resolved from the Vite project root. When omitted,\n * the packaged runtime at dist/runtime/<target> is used.\n */\n muonPath?: string;\n\n /**\n * Directory containing CEF files, or a CEF archive root with Release/Resources.\n *\n * @remarks Relative paths are resolved from the Vite project root. When omitted,\n * muon-prepare downloads and caches the tested CEF artifact from muonPath.\n */\n cefPath?: string;\n\n /**\n * Runtime staging directory used for development startup.\n *\n * @remarks Relative paths are resolved from the Vite project root. Defaults to\n * .muon/<target>.\n */\n stagePath?: string;\n\n /**\n * Build app distributions from Vite output.\n *\n * @remarks Defaults to true during Vite build. Set false to disable the build\n * hook while keeping the development bridge enabled.\n */\n build?: boolean | MuonViteBuildOptions;\n}\n\n/**\n * Creates a Vite plugin that launches Muon through Vite's server.open flow.\n *\n * @param options Muon runtime location used for development startup.\n * @returns Vite plugin instance.\n */\nconst muon = (options: MuonVitePluginOptions = {}): Plugin => {\n let resolvedConfig: ResolvedConfig | undefined = undefined;\n\n return {\n name: \"muon\",\n configResolved: (config) => {\n resolvedConfig = config;\n },\n configureServer: async (server) => {\n await startMuonViteBrowserBridge({\n server,\n pluginOptions: options,\n platform: process.platform,\n architecture: process.arch,\n environment: process.env,\n });\n },\n closeBundle: async () => {\n if (resolvedConfig === undefined || resolvedConfig.command !== \"build\") {\n return;\n }\n if (options.build === false) {\n return;\n }\n\n const buildOptions =\n typeof options.build === \"object\" ? options.build : {};\n await buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions));\n },\n };\n};\n\nconst createMuonBuildOptions = (\n config: ResolvedConfig,\n buildOptions: MuonViteBuildOptions,\n): MuonBuildOptions => {\n const outDir = isAbsolute(config.build.outDir)\n ? config.build.outDir\n : resolve(config.root, config.build.outDir);\n const options: MuonBuildOptions = {\n root: config.root,\n assetSourcePath: outDir,\n assetPrefix: \"main\",\n };\n\n if (buildOptions.allTargets !== undefined) {\n options.allTargets = buildOptions.allTargets;\n }\n if (buildOptions.targets !== undefined) {\n options.targets = buildOptions.targets;\n }\n if (buildOptions.appName !== undefined) {\n options.appName = buildOptions.appName;\n }\n if (buildOptions.outputRoot !== undefined) {\n options.outputRoot = buildOptions.outputRoot;\n }\n if (buildOptions.configPath !== undefined) {\n options.configPath = buildOptions.configPath;\n }\n if (buildOptions.packageDirectory !== undefined) {\n options.packageDirectory = buildOptions.packageDirectory;\n }\n if (buildOptions.assetSalt !== undefined) {\n options.assetSalt = buildOptions.assetSalt;\n }\n\n return options;\n};\n\nexport default muon;\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite.cjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["// muon - Multi-platform GUI application framework that uses CEF as its backend\n// Copyright (c) Kouji Matsui. (@kekyo@mi.kekyo.net)\n// Under MIT.\n// https://github.com/kekyo/muon\n\nimport type { Plugin } from \"vite\";\nimport type { ResolvedConfig } from \"vite\";\nimport { isAbsolute, resolve } from \"node:path\";\n\nimport { buildMuonApp, type MuonBuildOptions } from \"./build.js\";\nimport { startMuonViteBrowserBridge } from \"./vite-internals.js\";\nimport { attachMuonVitePluginOptions } from \"./vite-options.js\";\n\n/**\n * Options for generating Muon app distributions after Vite build.\n */\nexport interface MuonViteBuildOptions {\n /**\n * Target aliases or internal target names to build.\n */\n targets?: readonly string[];\n\n /**\n * Build every supported target from the installed package.\n */\n allTargets?: boolean;\n\n /**\n * File name used for the app launcher.\n *\n * @remarks The .exe suffix is added automatically for Windows targets.\n */\n appName?: string;\n\n /**\n * Parent directory that receives dist-linux-amd64/ style outputs.\n */\n outputRoot?: string;\n\n /**\n * Muon config path to embed.\n */\n configPath?: string;\n\n /**\n * Directory containing package runtime/ and native/ folders.\n *\n * @remarks This defaults to the installed muon package dist directory.\n */\n packageDirectory?: string;\n\n /**\n * Asset salt override for deterministic tests.\n *\n * @remarks Production builds should omit this option.\n */\n assetSalt?: Uint8Array;\n}\n\n/**\n * Options for the Muon Vite development plugin.\n */\nexport interface MuonVitePluginOptions {\n /**\n * Directory containing muon-core runtime files such as muon-core and plugins.\n *\n * @remarks Relative paths are resolved from the Vite project root. When omitted,\n * the packaged runtime at dist/runtime/<target> is used.\n */\n muonPath?: string;\n\n /**\n * Directory containing CEF files, or a CEF archive root with Release/Resources.\n *\n * @remarks Relative paths are resolved from the Vite project root. When omitted,\n * muon-prepare downloads and caches the tested CEF artifact from muonPath.\n */\n cefPath?: string;\n\n /**\n * Runtime staging directory used for development startup.\n *\n * @remarks Relative paths are resolved from the Vite project root. Defaults to\n * .muon/<target>.\n */\n stagePath?: string;\n\n /**\n * Launch Muon automatically during Vite dev startup.\n *\n * @remarks Defaults to true. This is independent from Vite's server.open\n * browser startup option. Vite build ignores this option.\n */\n open?: boolean;\n\n /**\n * Enable the Muon debugger defaults during Vite dev startup.\n *\n * @remarks Defaults to true. When enabled, the generated development config\n * enables CDP and binds DevTools to F12. Vite build ignores this option.\n */\n enableDebugger?: boolean;\n\n /**\n * Build app distributions from Vite output.\n *\n * @remarks Defaults to true during Vite build. Set false to disable the build\n * hook while keeping the development bridge enabled.\n */\n build?: boolean | MuonViteBuildOptions;\n}\n\n/**\n * Creates a Vite plugin that launches Muon during Vite dev startup.\n *\n * @param options Muon plugin options used for development startup and build.\n * @returns Vite plugin instance.\n */\nconst muon = (options: MuonVitePluginOptions = {}): Plugin => {\n let resolvedConfig: ResolvedConfig | undefined = undefined;\n\n const plugin: Plugin = {\n name: \"muon\",\n configResolved: (config) => {\n resolvedConfig = config;\n },\n configureServer: async (server) => {\n await startMuonViteBrowserBridge({\n server,\n pluginOptions: options,\n platform: process.platform,\n architecture: process.arch,\n environment: process.env,\n });\n },\n closeBundle: async () => {\n if (resolvedConfig === undefined || resolvedConfig.command !== \"build\") {\n return;\n }\n if (options.build === false) {\n return;\n }\n\n const buildOptions =\n typeof options.build === \"object\" ? options.build : {};\n await buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions));\n },\n };\n\n return attachMuonVitePluginOptions(plugin, options);\n};\n\nconst createMuonBuildOptions = (\n config: ResolvedConfig,\n buildOptions: MuonViteBuildOptions,\n): MuonBuildOptions => {\n const outDir = isAbsolute(config.build.outDir)\n ? config.build.outDir\n : resolve(config.root, config.build.outDir);\n const options: MuonBuildOptions = {\n root: config.root,\n assetSourcePath: outDir,\n assetPrefix: \"main\",\n };\n\n if (buildOptions.allTargets !== undefined) {\n options.allTargets = buildOptions.allTargets;\n }\n if (buildOptions.targets !== undefined) {\n options.targets = buildOptions.targets;\n }\n if (buildOptions.appName !== undefined) {\n options.appName = buildOptions.appName;\n }\n if (buildOptions.outputRoot !== undefined) {\n options.outputRoot = buildOptions.outputRoot;\n }\n if (buildOptions.configPath !== undefined) {\n options.configPath = buildOptions.configPath;\n }\n if (buildOptions.packageDirectory !== undefined) {\n options.packageDirectory = buildOptions.packageDirectory;\n }\n if (buildOptions.assetSalt !== undefined) {\n options.assetSalt = buildOptions.assetSalt;\n }\n\n return options;\n};\n\nexport default muon;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsHA,IAAM,QAAQ,UAAiC,CAAC,MAAc;CAC5D,IAAI,iBAA6C,KAAA;CA8BjD,OAAO,qBAAA,4BAA4B;EA3BjC,MAAM;EACN,iBAAiB,WAAW;GAC1B,iBAAiB;EACnB;EACA,iBAAiB,OAAO,WAAW;GACjC,MAAM,qBAAA,2BAA2B;IAC/B;IACA,eAAe;IACf,UAAU,QAAQ;IAClB,cAAc,QAAQ;IACtB,aAAa,QAAQ;GACvB,CAAC;EACH;EACA,aAAa,YAAY;GACvB,IAAI,mBAAmB,KAAA,KAAa,eAAe,YAAY,SAC7D;GAEF,IAAI,QAAQ,UAAU,OACpB;GAGF,MAAM,eACJ,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,CAAC;GACvD,MAAM,qBAAA,aAAa,uBAAuB,gBAAgB,YAAY,CAAC;EACzE;CAGiC,GAAQ,OAAO;AACpD;AAEA,IAAM,0BACJ,QACA,iBACqB;CACrB,MAAM,UAAA,GAAA,UAAA,YAAoB,OAAO,MAAM,MAAM,IACzC,OAAO,MAAM,UAAA,GAAA,UAAA,SACL,OAAO,MAAM,OAAO,MAAM,MAAM;CAC5C,MAAM,UAA4B;EAChC,MAAM,OAAO;EACb,iBAAiB;EACjB,aAAa;CACf;CAEA,IAAI,aAAa,eAAe,KAAA,GAC9B,QAAQ,aAAa,aAAa;CAEpC,IAAI,aAAa,YAAY,KAAA,GAC3B,QAAQ,UAAU,aAAa;CAEjC,IAAI,aAAa,YAAY,KAAA,GAC3B,QAAQ,UAAU,aAAa;CAEjC,IAAI,aAAa,eAAe,KAAA,GAC9B,QAAQ,aAAa,aAAa;CAEpC,IAAI,aAAa,eAAe,KAAA,GAC9B,QAAQ,aAAa,aAAa;CAEpC,IAAI,aAAa,qBAAqB,KAAA,GACpC,QAAQ,mBAAmB,aAAa;CAE1C,IAAI,aAAa,cAAc,KAAA,GAC7B,QAAQ,YAAY,aAAa;CAGnC,OAAO;AACT"}
package/dist/vite.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  /*!
2
2
  * name: muon-ui
3
- * version: 0.2.0
3
+ * version: 0.4.0
4
4
  * description: A multi-platform GUI application framework that uses CEF as its backend
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/muon-ui.git
8
- * git.commit.hash: 6251ff88aafa8ae873657f39aed1ebba2fa329a4
8
+ * git.commit.hash: 44d549142c8cbfa13cb29d10be2568652a68bf50
9
9
  */
10
10
  import { basename, dirname, isAbsolute, join, relative, resolve, sep, win32 } from "node:path";
11
11
  import { constants, writeFileSync } from "node:fs";
@@ -1769,7 +1769,7 @@ var defaultConfigFileNames = [
1769
1769
  "muon.jsonc",
1770
1770
  "muon.json"
1771
1771
  ];
1772
- var appConfigFromPath = "./assets.zip";
1772
+ var appConfigSourcePath = "./assets.zip";
1773
1773
  var defaultAppName = "muon-app";
1774
1774
  var muonLicenseFileName = "LICENSE_muon";
1775
1775
  var directoryMode = 493;
@@ -1833,7 +1833,7 @@ var resolveBuildTargets = (options) => {
1833
1833
  return [getDefaultMuonBuildTarget()];
1834
1834
  };
1835
1835
  var resolveAssetInput = (root, assetSourcePath, assetPrefix, buildConfig) => {
1836
- const configuredAssetSourcePath = assetSourcePath === void 0 ? readConfigAssetFrom(buildConfig.config) : void 0;
1836
+ const configuredAssetSourcePath = assetSourcePath === void 0 ? readConfigAssetSourcePath(buildConfig.config) : void 0;
1837
1837
  return {
1838
1838
  sourcePath: assetSourcePath !== void 0 ? resolve(root, assetSourcePath) : configuredAssetSourcePath !== void 0 ? resolve(buildConfig.directory, configuredAssetSourcePath) : resolve(root, "assets"),
1839
1839
  prefix: normalizeZipPrefix(assetPrefix ?? "")
@@ -1864,14 +1864,14 @@ var readBuildConfig = async (root, configPath) => {
1864
1864
  directory: dirname(resolvedConfigPath)
1865
1865
  };
1866
1866
  };
1867
- var readConfigAssetFrom = (sourceConfig) => {
1867
+ var readConfigAssetSourcePath = (sourceConfig) => {
1868
1868
  const sourceAsset = sourceConfig.asset;
1869
1869
  if (sourceAsset === void 0) return;
1870
1870
  if (!isJsonObject$1(sourceAsset)) throw new Error("muon.json asset must be an object when present.");
1871
- const sourceAssetFrom = sourceAsset.from;
1872
- if (sourceAssetFrom === void 0) return;
1873
- if (typeof sourceAssetFrom !== "string") throw new Error("muon.json asset.from must be a string when present.");
1874
- return sourceAssetFrom;
1871
+ const sourceAssetPath = sourceAsset.sourcePath;
1872
+ if (sourceAssetPath === void 0) return;
1873
+ if (typeof sourceAssetPath !== "string") throw new Error("muon.json asset.sourcePath must be a string when present.");
1874
+ return sourceAssetPath;
1875
1875
  };
1876
1876
  var resolveConfigPath = async (root, configPath) => {
1877
1877
  if (configPath !== void 0) {
@@ -2023,7 +2023,7 @@ var createEmbeddedConfig = (sourceConfig, asset) => {
2023
2023
  ...sourceConfig,
2024
2024
  asset: {
2025
2025
  ...sourceAsset ?? {},
2026
- from: appConfigFromPath,
2026
+ sourcePath: appConfigSourcePath,
2027
2027
  signature: asset.signature,
2028
2028
  salt: asset.salt
2029
2029
  }
@@ -2070,11 +2070,37 @@ var isJsonObject$1 = (value) => {
2070
2070
  };
2071
2071
  var getErrorMessage$1 = (error) => error instanceof Error ? error.message : String(error);
2072
2072
  //#endregion
2073
- //#region src/vite-internals.ts
2074
- var getServerOpenValue = (server) => {
2075
- const open = server.config.server.open;
2076
- return open === true || typeof open === "string" ? open : false;
2073
+ //#region src/gitignore.ts
2074
+ var muonGitignoreEntry = ".muon/";
2075
+ var isMissingFileError = (error) => error instanceof Error && error.code === "ENOENT";
2076
+ var hasMuonGitignoreEntry = (content) => content.split(/\r?\n/).map((line) => line.trim()).some((line) => line === muonGitignoreEntry || line === `/${muonGitignoreEntry}` || line === ".muon" || line === "/.muon");
2077
+ /**
2078
+ * Adds the Muon staging directory to a project .gitignore file.
2079
+ *
2080
+ * @param root Project root containing the .gitignore file.
2081
+ * @returns Gitignore update result.
2082
+ */
2083
+ var ensureMuonGitignoreEntry = async (root) => {
2084
+ const gitignorePath = join(root, ".gitignore");
2085
+ let content = "";
2086
+ try {
2087
+ content = await readFile(gitignorePath, "utf8");
2088
+ } catch (error) {
2089
+ if (!isMissingFileError(error)) throw error;
2090
+ }
2091
+ if (hasMuonGitignoreEntry(content)) return {
2092
+ gitignorePath,
2093
+ changed: false
2094
+ };
2095
+ const separator = content.length > 0 && !content.endsWith("\n") ? "\n" : "";
2096
+ await writeFile(gitignorePath, `${content}${separator}${muonGitignoreEntry}\n`);
2097
+ return {
2098
+ gitignorePath,
2099
+ changed: true
2100
+ };
2077
2101
  };
2102
+ //#endregion
2103
+ //#region src/vite-internals.ts
2078
2104
  var resolveFromRoot = (root, path) => isAbsolute(path) ? path : resolve(root, path);
2079
2105
  var moduleDirectory = typeof __dirname === "string" ? __dirname : dirname(fileURLToPath(import.meta.url));
2080
2106
  var defaultProjectConfigFileNames = [
@@ -2082,6 +2108,7 @@ var defaultProjectConfigFileNames = [
2082
2108
  "muon.jsonc",
2083
2109
  "muon.json"
2084
2110
  ];
2111
+ var muonRecycleExitCode = 88;
2085
2112
  /**
2086
2113
  * Resolves the muon-core runtime directory used by the Vite plugin.
2087
2114
  *
@@ -2096,6 +2123,7 @@ var getPlatformDirectoryName = (path, platform) => platform === "win32" ? win32.
2096
2123
  var getOptionalPosixValue = (value) => value === void 0 ? "''" : quotePosix(value);
2097
2124
  var createPosixMuonLaunchScript = ({ muonExecutablePath, projectConfigPath, overrideConfigPath }) => `#!/usr/bin/env bash
2098
2125
  set -euo pipefail
2126
+ MUON_RECYCLE_EXIT_CODE=${muonRecycleExitCode}
2099
2127
  MUON_EXECUTABLE=${quotePosix(muonExecutablePath)}
2100
2128
  MUON_EXECUTABLE_DIRECTORY=${quotePosix(getPlatformDirectoryName(muonExecutablePath, "linux"))}
2101
2129
  MUON_PROJECT_CONFIG=${getOptionalPosixValue(projectConfigPath)}
@@ -2122,12 +2150,21 @@ fi
2122
2150
  MUON_CONFIG_ARGS+=("-c" "$MUON_OVERRIDE_CONFIG")
2123
2151
 
2124
2152
  cd "$MUON_EXECUTABLE_DIRECTORY"
2125
- exec "$MUON_EXECUTABLE" "\${MUON_CONFIG_ARGS[@]}"
2153
+ while true; do
2154
+ set +e
2155
+ "$MUON_EXECUTABLE" "\${MUON_CONFIG_ARGS[@]}"
2156
+ MUON_EXIT_CODE=$?
2157
+ set -e
2158
+ if [[ "$MUON_EXIT_CODE" -ne "$MUON_RECYCLE_EXIT_CODE" ]]; then
2159
+ exit "$MUON_EXIT_CODE"
2160
+ fi
2161
+ done
2126
2162
  `;
2127
2163
  var escapeWindowsCmdValue = (value) => value.replaceAll("%", "%%").replaceAll("\r", "").replaceAll("\n", "");
2128
2164
  var getOptionalWindowsCmdValue = (value) => value === void 0 ? "" : escapeWindowsCmdValue(value);
2129
2165
  var createWindowsMuonLaunchScript = ({ muonExecutablePath, projectConfigPath, overrideConfigPath }) => `@echo off
2130
2166
  setlocal
2167
+ set "MUON_RECYCLE_EXIT_CODE=${muonRecycleExitCode}"
2131
2168
  set "MUON_EXECUTABLE=${escapeWindowsCmdValue(muonExecutablePath)}"
2132
2169
  set "MUON_EXECUTABLE_DIRECTORY=${escapeWindowsCmdValue(getPlatformDirectoryName(muonExecutablePath, "win32"))}"
2133
2170
  set "MUON_PROJECT_CONFIG=${getOptionalWindowsCmdValue(projectConfigPath)}"
@@ -2144,6 +2181,7 @@ if not exist "%MUON_OVERRIDE_CONFIG%" (
2144
2181
  )
2145
2182
 
2146
2183
  pushd "%MUON_EXECUTABLE_DIRECTORY%"
2184
+ :muon_recycle_loop
2147
2185
  if defined MUON_PROJECT_CONFIG (
2148
2186
  if not exist "%MUON_PROJECT_CONFIG%" (
2149
2187
  echo Muon startup failed: project config does not exist: %MUON_PROJECT_CONFIG% 1>&2
@@ -2155,39 +2193,41 @@ if defined MUON_PROJECT_CONFIG (
2155
2193
  "%MUON_EXECUTABLE%" -c "%MUON_OVERRIDE_CONFIG%"
2156
2194
  )
2157
2195
  set "MUON_EXIT_CODE=%ERRORLEVEL%"
2196
+ if "%MUON_EXIT_CODE%"=="%MUON_RECYCLE_EXIT_CODE%" goto muon_recycle_loop
2158
2197
  popd
2159
2198
  exit /b %MUON_EXIT_CODE%
2160
2199
  `;
2161
2200
  var createMuonLaunchScript = (options) => options.platform === "win32" ? createWindowsMuonLaunchScript(options) : createPosixMuonLaunchScript(options);
2162
2201
  var getBaseUrl = (server) => server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];
2163
- var getStartUrl = (server, openValue) => {
2164
- const baseUrl = getBaseUrl(server);
2165
- if (baseUrl === void 0) return;
2166
- return typeof openValue === "string" ? new URL(openValue, baseUrl).href : baseUrl;
2167
- };
2168
2202
  var getWebSocketOrigin = (startUrl) => {
2169
2203
  const url = new URL(startUrl);
2170
2204
  if (url.protocol === "https:") url.protocol = "wss:";
2171
2205
  else if (url.protocol === "http:") url.protocol = "ws:";
2172
2206
  return url.origin;
2173
2207
  };
2174
- var createMuonOverrideConfig = (startUrl) => {
2208
+ var createMuonOverrideConfig = (startUrl, enableDebugger) => {
2175
2209
  const origin = new URL(startUrl).origin;
2176
2210
  return {
2211
+ ...enableDebugger ? { cdp: { enable: true } } : {},
2177
2212
  browser: {
2178
2213
  startPage: startUrl,
2214
+ ...enableDebugger ? { keybind: {
2215
+ devtools: "f12",
2216
+ recycle: "ctrl+f12"
2217
+ } } : {},
2179
2218
  plugin: { allow: [`${origin}/**`] }
2180
2219
  },
2181
2220
  network: { allow: [`${origin}/**`, `${getWebSocketOrigin(startUrl)}/**`] }
2182
2221
  };
2183
2222
  };
2184
- var writeMuonOverrideConfig = (server, openValue, overrideConfigPath) => {
2185
- const startUrl = getStartUrl(server, openValue);
2223
+ var writeMuonOverrideConfig = (server, overrideConfigPath, enableDebugger) => {
2224
+ const startUrl = getBaseUrl(server);
2186
2225
  if (startUrl === void 0) {
2187
2226
  server.config.logger.warn("Muon Vite plugin could not resolve a Vite URL.");
2188
- return;
2227
+ return false;
2189
2228
  }
2190
- writeFileSync(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl), null, 2)}\n`);
2229
+ writeFileSync(overrideConfigPath, `${JSON.stringify(createMuonOverrideConfig(startUrl, enableDebugger), null, 2)}\n`);
2230
+ return true;
2191
2231
  };
2192
2232
  var createRuntimePaths = async (server, stagePath, platform, projectConfigPath) => {
2193
2233
  const temporaryDirectory = await mkdtemp(join(tmpdir(), "muon-vite-"));
@@ -2232,9 +2272,26 @@ var writeLaunchScript = async (paths, platform) => {
2232
2272
  }));
2233
2273
  if (platform !== "win32") await chmod(paths.launchScriptPath, 448);
2234
2274
  };
2275
+ var quoteWindowsCommandArgument = (value) => `"${value.replaceAll("\"", "\\\"")}"`;
2276
+ var launchMuon = (paths, platform, server) => {
2277
+ const child = spawn(platform === "win32" ? "cmd.exe" : paths.launchScriptPath, platform === "win32" ? [
2278
+ "/d",
2279
+ "/s",
2280
+ "/c",
2281
+ quoteWindowsCommandArgument(paths.launchScriptPath)
2282
+ ] : [], {
2283
+ detached: true,
2284
+ stdio: "ignore",
2285
+ windowsHide: false
2286
+ });
2287
+ child.once("error", (error) => {
2288
+ server.config.logger.warn(`Muon startup failed: ${getErrorMessage(error)}`);
2289
+ });
2290
+ child.unref();
2291
+ };
2235
2292
  var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, architecture, environment }) => {
2236
- const openValue = getServerOpenValue(server);
2237
- if (openValue === false || server.httpServer === null) return;
2293
+ await ensureMuonGitignoreEntry(server.config.root);
2294
+ if (pluginOptions.open === false || server.httpServer === null) return;
2238
2295
  const target = getDefaultMuonPrepareTarget(platform, architecture);
2239
2296
  const preparedRuntime = await runMuonPrepare({
2240
2297
  muonPath: resolveMuonRuntimePath({
@@ -2255,14 +2312,10 @@ var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, archi
2255
2312
  if (preparedRuntime.stagePath === void 0) throw new Error("muon-prepare did not return a staged runtime path.");
2256
2313
  const paths = await createRuntimePaths(server, preparedRuntime.stagePath, platform, await resolveProjectConfigPath(server));
2257
2314
  await writeLaunchScript(paths, platform);
2258
- const previousBrowser = environment.BROWSER;
2259
- environment.BROWSER = paths.launchScriptPath;
2260
2315
  let cleanupPromise = void 0;
2261
2316
  const cleanup = async () => {
2262
2317
  if (cleanupPromise !== void 0) return cleanupPromise;
2263
2318
  cleanupPromise = (async () => {
2264
- if (previousBrowser === void 0) delete environment.BROWSER;
2265
- else environment.BROWSER = previousBrowser;
2266
2319
  await rm(paths.temporaryDirectory, {
2267
2320
  recursive: true,
2268
2321
  force: true
@@ -2282,20 +2335,42 @@ var startMuonViteBrowserBridge = async ({ server, pluginOptions, platform, archi
2282
2335
  cleanup();
2283
2336
  });
2284
2337
  server.httpServer.once("listening", () => {
2285
- writeMuonOverrideConfig(server, openValue, paths.overrideConfigPath);
2338
+ if (writeMuonOverrideConfig(server, paths.overrideConfigPath, pluginOptions.enableDebugger !== false)) launchMuon(paths, platform, server);
2286
2339
  });
2287
2340
  };
2288
2341
  //#endregion
2342
+ //#region src/vite-options.ts
2343
+ /**
2344
+ * Metadata symbol used to recover `muon()` plugin options from `vite.config.*`.
2345
+ */
2346
+ var muonVitePluginOptionsSymbol = Symbol.for("muon.vite.plugin.options");
2347
+ /**
2348
+ * Attaches raw Muon Vite plugin options to a plugin instance.
2349
+ *
2350
+ * @param plugin Plugin object.
2351
+ * @param options Raw plugin options.
2352
+ * @returns Plugin object with internal Muon metadata.
2353
+ */
2354
+ var attachMuonVitePluginOptions = (plugin, options) => {
2355
+ Object.defineProperty(plugin, muonVitePluginOptionsSymbol, {
2356
+ configurable: false,
2357
+ enumerable: false,
2358
+ value: { ...options },
2359
+ writable: false
2360
+ });
2361
+ return plugin;
2362
+ };
2363
+ //#endregion
2289
2364
  //#region src/vite.ts
2290
2365
  /**
2291
- * Creates a Vite plugin that launches Muon through Vite's server.open flow.
2366
+ * Creates a Vite plugin that launches Muon during Vite dev startup.
2292
2367
  *
2293
- * @param options Muon runtime location used for development startup.
2368
+ * @param options Muon plugin options used for development startup and build.
2294
2369
  * @returns Vite plugin instance.
2295
2370
  */
2296
2371
  var muon = (options = {}) => {
2297
2372
  let resolvedConfig = void 0;
2298
- return {
2373
+ return attachMuonVitePluginOptions({
2299
2374
  name: "muon",
2300
2375
  configResolved: (config) => {
2301
2376
  resolvedConfig = config;
@@ -2315,7 +2390,7 @@ var muon = (options = {}) => {
2315
2390
  const buildOptions = typeof options.build === "object" ? options.build : {};
2316
2391
  await buildMuonApp(createMuonBuildOptions(resolvedConfig, buildOptions));
2317
2392
  }
2318
- };
2393
+ }, options);
2319
2394
  };
2320
2395
  var createMuonBuildOptions = (config, buildOptions) => {
2321
2396
  const outDir = isAbsolute(config.build.outDir) ? config.build.outDir : resolve(config.root, config.build.outDir);