@vizejs/vite-plugin 0.289.0 → 0.291.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { registerResolvedVizeConfig, unregisterResolvedVizeConfig } from "./internal/config-bridge.mjs";
1
2
  import { createRequire } from "node:module";
2
3
  import { createHash } from "node:crypto";
3
4
  import * as native from "@vizejs/native";
@@ -78,6 +79,7 @@ function styleFingerprint(module) {
78
79
  //#region src/utils/module-output.ts
79
80
  const OUTPUT_PARSE_ID = "vize-output.tsx";
80
81
  const SFC_MAIN_NAME = "_sfc_main";
82
+ const EXPORT_DEFAULT = "export default";
81
83
  function isNode(value) {
82
84
  return value != null && typeof value === "object" && typeof value.type === "string";
83
85
  }
@@ -132,6 +134,21 @@ function getExportedNames(statement) {
132
134
  function findDefaultExport(program) {
133
135
  return getProgramBody(program).find((statement) => statement.type === "ExportDefaultDeclaration") ?? null;
134
136
  }
137
+ function analyzeFastDefaultOutput(code) {
138
+ if (code.includes(SFC_MAIN_NAME) || code.includes("export function render") || code.includes("export function ssrRender") || code.includes("export {")) return null;
139
+ const defaultExportStart = code.indexOf(EXPORT_DEFAULT);
140
+ if (defaultExportStart === -1 || defaultExportStart !== code.lastIndexOf(EXPORT_DEFAULT)) return null;
141
+ const before = defaultExportStart === 0 ? "\n" : code[defaultExportStart - 1];
142
+ if (!before || !/\s|;/.test(before)) return null;
143
+ return {
144
+ hasDefaultExport: true,
145
+ hasSfcMainDefined: false,
146
+ hasNamedRenderExport: false,
147
+ hasNamedSsrRenderExport: false,
148
+ defaultExportStart,
149
+ defaultExportKeywordEnd: defaultExportStart + 14
150
+ };
151
+ }
135
152
  function getExportDefaultKeywordEnd(code, defaultExport) {
136
153
  const exportStart = getNodeStart(defaultExport);
137
154
  if (exportStart == null) return null;
@@ -139,9 +156,13 @@ function getExportDefaultKeywordEnd(code, defaultExport) {
139
156
  return match ? exportStart + match[0].length : null;
140
157
  }
141
158
  function analyzeModuleOutput(code) {
159
+ const fastOutput = analyzeFastDefaultOutput(code);
160
+ if (fastOutput) return fastOutput;
142
161
  const program = parseProgram(code);
143
162
  const body = getProgramBody(program);
144
163
  const defaultExport = findDefaultExport(program);
164
+ const defaultExportStart = getNodeStart(defaultExport);
165
+ const defaultExportKeywordEnd = defaultExport ? getExportDefaultKeywordEnd(code, defaultExport) : null;
145
166
  const exportedNames = body.filter((statement) => statement.type === "ExportNamedDeclaration").flatMap(getExportedNames);
146
167
  return {
147
168
  hasDefaultExport: defaultExport != null,
@@ -149,13 +170,22 @@ function analyzeModuleOutput(code) {
149
170
  return statement.type === "VariableDeclaration" && getVariableDeclarationNames(statement).includes(SFC_MAIN_NAME);
150
171
  }),
151
172
  hasNamedRenderExport: exportedNames.includes("render"),
152
- hasNamedSsrRenderExport: exportedNames.includes("ssrRender")
173
+ hasNamedSsrRenderExport: exportedNames.includes("ssrRender"),
174
+ defaultExportKeywordEnd,
175
+ defaultExportStart
153
176
  };
154
177
  }
155
- function rewriteDefaultExportToSfcMain(code) {
156
- const defaultExport = findDefaultExport(parseProgram(code));
157
- const exportStart = getNodeStart(defaultExport);
158
- const keywordEnd = defaultExport ? getExportDefaultKeywordEnd(code, defaultExport) : null;
178
+ function rewriteDefaultExportToSfcMain(code, moduleInfo = {
179
+ defaultExportKeywordEnd: null,
180
+ defaultExportStart: null
181
+ }) {
182
+ let exportStart = moduleInfo.defaultExportStart;
183
+ let keywordEnd = moduleInfo.defaultExportKeywordEnd;
184
+ if (exportStart == null || keywordEnd == null) {
185
+ const defaultExport = findDefaultExport(parseProgram(code));
186
+ exportStart = getNodeStart(defaultExport);
187
+ keywordEnd = defaultExport ? getExportDefaultKeywordEnd(code, defaultExport) : null;
188
+ }
159
189
  if (exportStart == null || keywordEnd == null) return code;
160
190
  return `${code.slice(0, exportStart)}const ${SFC_MAIN_NAME} =${code.slice(keywordEnd)}`;
161
191
  }
@@ -353,7 +383,7 @@ function generateOutput(compiled, options) {
353
383
  const hasNamedSsrRenderExport = moduleInfo.hasNamedSsrRenderExport;
354
384
  const hasSfcMainDefined = moduleInfo.hasSfcMainDefined;
355
385
  if (hasExportDefault && !hasSfcMainDefined) {
356
- output = rewriteDefaultExportToSfcMain(output);
386
+ output = rewriteDefaultExportToSfcMain(output, moduleInfo);
357
387
  if (compiled.hasScoped && compiled.scopeId) output += `\n_sfc_main.__scopeId = "data-v-${compiled.scopeId}";`;
358
388
  output += "\nexport default _sfc_main;";
359
389
  } else if (hasExportDefault && hasSfcMainDefined) {
@@ -446,9 +476,6 @@ function isPluginVisibleSsrVirtualId(id) {
446
476
  function toBrowserImportPrefix(replacement) {
447
477
  return toViteBrowserImportPrefix(replacement);
448
478
  }
449
- function rewriteDynamicTemplateImports(code, aliasRules) {
450
- return rewriteViteDynamicTemplateImports(code, aliasRules);
451
- }
452
479
  //#endregion
453
480
  //#region src/transform.ts
454
481
  /**
@@ -465,8 +492,13 @@ function rewriteDynamicTemplateImports(code, aliasRules) {
465
492
  * pipeline handles alias expansion and asset hashing in both dev and build.
466
493
  */
467
494
  function rewriteStaticAssetUrls(code, aliasRules) {
495
+ if (aliasRules.length === 0 || !code.includes("src")) return code;
468
496
  return rewriteViteStaticAssetUrls(code, aliasRules);
469
497
  }
498
+ function rewriteDynamicTemplateImports(code, aliasRules) {
499
+ if (!code.includes("import(") || !code.includes("`")) return code;
500
+ return rewriteViteDynamicTemplateImports(code, aliasRules);
501
+ }
470
502
  function rewriteImportMetaGlobBase(code, importer, root) {
471
503
  if (!code.includes("import.meta.glob")) return code;
472
504
  return rewriteViteImportMetaGlobBase(code, importer, root);
@@ -494,40 +526,6 @@ function createLogger(debug) {
494
526
  };
495
527
  }
496
528
  //#endregion
497
- //#region src/config.ts
498
- const require = createRequire(import.meta.url);
499
- const CONFIG_FILE_NAMES = [
500
- "vize.config.pkl",
501
- "vize.config.ts",
502
- "vize.config.js",
503
- "vize.config.mjs",
504
- "vize.config.json"
505
- ];
506
- let vizeConfigModulePromise = null;
507
- function loadVizeConfigModule() {
508
- vizeConfigModulePromise ??= import("vize/config");
509
- return vizeConfigModulePromise;
510
- }
511
- function defineConfig(config) {
512
- return config;
513
- }
514
- async function loadConfig(root, options) {
515
- return (await loadVizeConfigModule()).loadConfig(root, options);
516
- }
517
- async function resolveConfigExport(exported, env) {
518
- return (await loadVizeConfigModule()).resolveConfigExport(exported, env);
519
- }
520
- require.resolve("vize/schemas/vize.config.schema.json");
521
- require.resolve("vize/pkl/vize.pkl");
522
- [...CONFIG_FILE_NAMES];
523
- const VIZE_CONFIG_FILE_ENV = "VIZE_CONFIG_FILE";
524
- /**
525
- * Shared config store for inter-plugin communication.
526
- * Key = project root, Value = resolved VizeConfig.
527
- * Used by musea() and other plugins to access the unified config.
528
- */
529
- const vizeConfigStore = /* @__PURE__ */ new Map();
530
- //#endregion
531
529
  //#region src/compile-options.ts
532
530
  function buildCompileFileOptions(filePath, options) {
533
531
  return {
@@ -1651,7 +1649,110 @@ function createVirtualTypeScriptTransformer(viteApi) {
1651
1649
  throw new Error("Installed Vite does not expose transformWithOxc or transformWithEsbuild");
1652
1650
  };
1653
1651
  }
1652
+ const TYPE_DECLARATION_RE = /\b(?:interface|type|enum|namespace|declare)\s+[A-Za-z_$]/;
1653
+ const TYPE_ASSERTION_RE = /\bas\s+(?:const|unknown|never|any|string|number|boolean|readonly\b|[A-Z][A-Za-z0-9_$]*(?:\s*[<[{&|),;=]|$))/;
1654
+ const TYPED_BINDING_RE = /\b(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*:/;
1655
+ const GENERIC_FUNCTION_RE = /\bfunction\s+[A-Za-z_$][\w$]*\s*<[^>{}]*>\s*\(/;
1656
+ const TYPED_PARAMETER_RE = /[(,]\s*(?:\.\.\.)?[A-Za-z_$][\w$]*\??\s*:\s*[^,)=]+/;
1657
+ const RETURN_TYPE_RE = /\)\s*:\s*[^=<{;]+[{=>]/;
1658
+ const ACCESS_MODIFIER_RE = /\b(?:public|private|protected|readonly|abstract|implements)\b/;
1659
+ const SATISFIES_RE = /\bsatisfies\s+[A-Za-z_$]/;
1660
+ function hasUnbalancedDelimiters(code) {
1661
+ const stack = [];
1662
+ let quote = null;
1663
+ let escaped = false;
1664
+ let lineComment = false;
1665
+ let blockComment = false;
1666
+ for (let index = 0; index < code.length; index += 1) {
1667
+ const char = code[index];
1668
+ const next = code[index + 1];
1669
+ if (lineComment) {
1670
+ if (char === "\n" || char === "\r") lineComment = false;
1671
+ continue;
1672
+ }
1673
+ if (blockComment) {
1674
+ if (char === "*" && next === "/") {
1675
+ blockComment = false;
1676
+ index += 1;
1677
+ }
1678
+ continue;
1679
+ }
1680
+ if (quote) {
1681
+ if (escaped) escaped = false;
1682
+ else if (char === "\\") escaped = true;
1683
+ else if (char === quote) quote = null;
1684
+ continue;
1685
+ }
1686
+ if (char === "/" && next === "/") {
1687
+ lineComment = true;
1688
+ index += 1;
1689
+ continue;
1690
+ }
1691
+ if (char === "/" && next === "*") {
1692
+ blockComment = true;
1693
+ index += 1;
1694
+ continue;
1695
+ }
1696
+ if (char === "'" || char === "\"" || char === "`") {
1697
+ quote = char;
1698
+ continue;
1699
+ }
1700
+ if (char === "{" || char === "(" || char === "[") {
1701
+ stack.push(char);
1702
+ continue;
1703
+ }
1704
+ if (char === "}" || char === ")" || char === "]") {
1705
+ const open = stack.pop();
1706
+ if (char === "}" && open !== "{" || char === ")" && open !== "(" || char === "]" && open !== "[") return true;
1707
+ }
1708
+ }
1709
+ return quote !== null || blockComment || stack.length > 0;
1710
+ }
1711
+ function needsVirtualTypeScriptTransform(code) {
1712
+ return TYPE_DECLARATION_RE.test(code) || TYPE_ASSERTION_RE.test(code) || TYPED_BINDING_RE.test(code) || GENERIC_FUNCTION_RE.test(code) || TYPED_PARAMETER_RE.test(code) || RETURN_TYPE_RE.test(code) || ACCESS_MODIFIER_RE.test(code) || SATISFIES_RE.test(code) || hasUnbalancedDelimiters(code);
1713
+ }
1654
1714
  const transformVirtualTypeScript = createVirtualTypeScriptTransformer(vite);
1715
+ function getOxcDumpPath(root, realPath) {
1716
+ const dumpDir = path.resolve(root || process.cwd(), "node_modules", ".vize", "oxc-dumps");
1717
+ fs.mkdirSync(dumpDir, { recursive: true });
1718
+ return path.join(dumpDir, `vize-oxc-error-${path.basename(realPath)}.ts`);
1719
+ }
1720
+ function getVirtualModuleDefines(state, ssr) {
1721
+ return {
1722
+ "import.meta.client": ssr ? "false" : "true",
1723
+ "import.meta.server": ssr ? "true" : "false",
1724
+ "import.meta.dev": state.isProduction ? "false" : "true",
1725
+ "import.meta.test": "false",
1726
+ "import.meta.prerender": "false",
1727
+ ...ssr ? state.serverViteDefine : state.clientViteDefine
1728
+ };
1729
+ }
1730
+ function formatUnknownError$1(error) {
1731
+ return error instanceof Error ? error.message : String(error);
1732
+ }
1733
+ async function transformVizeVirtualModule(state, code, realPath, ssr, forceTypeScriptTransform = false) {
1734
+ const needsTsTransform = forceTypeScriptTransform || needsVirtualTypeScriptTransform(code);
1735
+ try {
1736
+ let transformed = (needsTsTransform ? await transformVirtualTypeScript(code, realPath) : { code }).code;
1737
+ if (transformed.includes("import.meta.")) transformed = applyDefineReplacements(transformed, getVirtualModuleDefines(state, ssr));
1738
+ return transformed === code ? null : {
1739
+ code: transformed,
1740
+ map: null
1741
+ };
1742
+ } catch (e) {
1743
+ state.logger.error(`transformWithOxc failed for ${realPath}:`, e);
1744
+ let dumpPath = null;
1745
+ try {
1746
+ dumpPath = getOxcDumpPath(state.root, realPath);
1747
+ fs.writeFileSync(dumpPath, code, "utf-8");
1748
+ state.logger.error(`Dumped failing code to ${dumpPath}`);
1749
+ } catch (dumpError) {
1750
+ state.logger.error(`Failed to dump failing virtual module for ${realPath}:`, dumpError);
1751
+ }
1752
+ const message = [`[vize] Virtual module transform failed for ${realPath}: ${formatUnknownError$1(e)}`, dumpPath ? `Dumped failing code to ${dumpPath}` : null].filter(Boolean).join("\n");
1753
+ throw new Error(message);
1754
+ }
1755
+ }
1655
1756
  //#endregion
1656
1757
  //#region src/plugin/load.ts
1657
1758
  const SERVER_PLACEHOLDER_CODE = `import { createElementBlock, defineComponent } from "vue";
@@ -1668,21 +1769,6 @@ function getBoundaryPlaceholderCode(realPath, ssr) {
1668
1769
  if (!ssr && boundaryKind === "server") return SERVER_PLACEHOLDER_CODE;
1669
1770
  return null;
1670
1771
  }
1671
- function getOxcDumpPath(root, realPath) {
1672
- const dumpDir = path.resolve(root || process.cwd(), "node_modules", ".vize", "oxc-dumps");
1673
- fs.mkdirSync(dumpDir, { recursive: true });
1674
- return path.join(dumpDir, `vize-oxc-error-${path.basename(realPath)}.ts`);
1675
- }
1676
- function getVirtualModuleDefines(state, ssr) {
1677
- return {
1678
- "import.meta.client": ssr ? "false" : "true",
1679
- "import.meta.server": ssr ? "true" : "false",
1680
- "import.meta.dev": state.isProduction ? "false" : "true",
1681
- "import.meta.test": "false",
1682
- "import.meta.prerender": "false",
1683
- ...ssr ? state.serverViteDefine : state.clientViteDefine
1684
- };
1685
- }
1686
1772
  function normalizeVueServerRendererImport(code) {
1687
1773
  return code.replace(/\bfrom\s+(['"])@vue\/server-renderer\1/g, "from \"vue/server-renderer\"");
1688
1774
  }
@@ -1763,6 +1849,7 @@ function loadDefinePageMetaArtifact(state, realPath, ssr) {
1763
1849
  } : null;
1764
1850
  }
1765
1851
  function loadHook(state, id, loadOptions) {
1852
+ if (id !== "\0vize:all-styles.css" && !id.startsWith("\0") && !id.includes(".vue")) return null;
1766
1853
  const request = classifyVitePluginRequest(id);
1767
1854
  const pluginVisibleVirtualPath = fromPluginVisibleVirtualId(id);
1768
1855
  const loadableVueSfcPath = getLoadableVueSfcPath(request);
@@ -1880,41 +1967,15 @@ function transformJsxRequest(state, code, id, options) {
1880
1967
  };
1881
1968
  }
1882
1969
  async function transformHook(state, code, id, options) {
1970
+ if (!id.startsWith("\0") && !id.includes(".vue.ts") && !isJsxComponentPath(id)) return null;
1883
1971
  const pluginVisibleVirtualPath = fromPluginVisibleVirtualId(id);
1884
1972
  const jsxResult = transformJsxRequest(state, code, id, { ssr: options?.ssr });
1885
1973
  if (jsxResult !== void 0) return jsxResult;
1886
1974
  if (!id.startsWith("\0") && !pluginVisibleVirtualPath) return null;
1887
1975
  const request = classifyVitePluginRequest(id);
1888
- if (request.isVizeVirtual || request.isMacroVirtualId || pluginVisibleVirtualPath) {
1889
- const realPath = request.isMacroVirtualId ? request.strippedVirtualPath ?? "" : request.vizeVirtualPath ?? pluginVisibleVirtualPath ?? "";
1890
- try {
1891
- const result = await transformVirtualTypeScript(code, realPath);
1892
- const defines = getVirtualModuleDefines(state, options?.ssr ?? false);
1893
- let transformed = result.code;
1894
- transformed = applyDefineReplacements(transformed, defines);
1895
- return {
1896
- code: transformed,
1897
- map: null
1898
- };
1899
- } catch (e) {
1900
- state.logger.error(`transformWithOxc failed for ${realPath}:`, e);
1901
- let dumpPath = null;
1902
- try {
1903
- dumpPath = getOxcDumpPath(state.root, realPath);
1904
- fs.writeFileSync(dumpPath, code, "utf-8");
1905
- state.logger.error(`Dumped failing code to ${dumpPath}`);
1906
- } catch (dumpError) {
1907
- state.logger.error(`Failed to dump failing virtual module for ${realPath}:`, dumpError);
1908
- }
1909
- const message = [`[vize] Virtual module transform failed for ${realPath}: ${formatUnknownError$1(e)}`, dumpPath ? `Dumped failing code to ${dumpPath}` : null].filter(Boolean).join("\n");
1910
- throw new Error(message);
1911
- }
1912
- }
1976
+ if (request.isVizeVirtual || request.isMacroVirtualId || pluginVisibleVirtualPath) return transformVizeVirtualModule(state, code, request.isMacroVirtualId ? request.strippedVirtualPath ?? "" : request.vizeVirtualPath ?? pluginVisibleVirtualPath ?? "", options?.ssr ?? false, request.isMacroVirtualId);
1913
1977
  return null;
1914
1978
  }
1915
- function formatUnknownError$1(error) {
1916
- return error instanceof Error ? error.message : String(error);
1917
- }
1918
1979
  //#endregion
1919
1980
  //#region src/plugin/hmr.ts
1920
1981
  const VIZE_COMPONENTS_CSS_BASENAME = "vize-components.css";
@@ -2423,6 +2484,43 @@ function createLegacyVueCompatibilityPlugin(options) {
2423
2484
  };
2424
2485
  }
2425
2486
  //#endregion
2487
+ //#region src/config.ts
2488
+ const require = createRequire(import.meta.url);
2489
+ const CONFIG_FILE_NAMES = [
2490
+ "vize.config.pkl",
2491
+ "vize.config.ts",
2492
+ "vize.config.js",
2493
+ "vize.config.mjs",
2494
+ "vize.config.json"
2495
+ ];
2496
+ let vizeConfigModulePromise = null;
2497
+ function loadVizeConfigModule() {
2498
+ vizeConfigModulePromise ??= import("vize/config");
2499
+ return vizeConfigModulePromise;
2500
+ }
2501
+ function defineConfig(config) {
2502
+ return config;
2503
+ }
2504
+ async function loadConfig(root, options) {
2505
+ return (await loadVizeConfigModule()).loadConfig(root, options);
2506
+ }
2507
+ async function resolveConfigExport(exported, env) {
2508
+ return (await loadVizeConfigModule()).resolveConfigExport(exported, env);
2509
+ }
2510
+ require.resolve("vize/schemas/vize.config.schema.json");
2511
+ require.resolve("vize/pkl/vize.pkl");
2512
+ [...CONFIG_FILE_NAMES];
2513
+ const VIZE_CONFIG_FILE_ENV = "VIZE_CONFIG_FILE";
2514
+ /**
2515
+ * Shared config store for inter-plugin communication.
2516
+ * Key = project root, Value = resolved VizeConfig.
2517
+ *
2518
+ * @deprecated Root identity cannot isolate parallel Vite client/SSR instances
2519
+ * or servers. This export remains temporarily for compatibility; internal Vize
2520
+ * integrations use an exact `ResolvedConfig`-scoped bridge instead.
2521
+ */
2522
+ const vizeConfigStore = /* @__PURE__ */ new Map();
2523
+ //#endregion
2426
2524
  //#region src/plugin/shared-config.ts
2427
2525
  function mergeSharedConfig(baseConfig, overrideConfig) {
2428
2526
  if (!baseConfig) return overrideConfig;
@@ -2465,6 +2563,93 @@ function mergeSharedConfig(baseConfig, overrideConfig) {
2465
2563
  entries: [...baseConfig.entries, ...overrideConfig.entries]
2466
2564
  };
2467
2565
  }
2566
+ async function resolveSharedConfig(options, root, env, logger) {
2567
+ let fileConfig = null;
2568
+ if (options.configMode !== false) {
2569
+ const configFile = options.configFile ?? process.env["VIZE_CONFIG_FILE"];
2570
+ try {
2571
+ fileConfig = await loadConfig(root, {
2572
+ mode: options.configMode ?? "root",
2573
+ configFile,
2574
+ env
2575
+ });
2576
+ if (fileConfig) logger.log("Loaded config from vize.config file");
2577
+ } catch (error) {
2578
+ logger.warn(`Failed to load vize config from ${configFile ?? root}:`, error);
2579
+ }
2580
+ }
2581
+ let inlineConfig = null;
2582
+ if (options.config) try {
2583
+ inlineConfig = await resolveConfigExport(options.config, env);
2584
+ logger.log("Loaded inline vize config from plugin options");
2585
+ } catch (error) {
2586
+ logger.warn("Failed to resolve inline vize config:", error);
2587
+ }
2588
+ return mergeSharedConfig(fileConfig, inlineConfig);
2589
+ }
2590
+ //#endregion
2591
+ //#region src/plugin/config-lifecycle.ts
2592
+ const compatibilityOwners = /* @__PURE__ */ new Map();
2593
+ const compatibilityRegistrations = /* @__PURE__ */ new WeakMap();
2594
+ function releaseCompatibilityRegistration(resolvedConfig) {
2595
+ const registration = compatibilityRegistrations.get(resolvedConfig);
2596
+ compatibilityRegistrations.delete(resolvedConfig);
2597
+ if (!registration || compatibilityOwners.get(registration.root) !== registration.token) return;
2598
+ compatibilityOwners.delete(registration.root);
2599
+ if (vizeConfigStore.get(registration.root) === registration.config) vizeConfigStore.delete(registration.root);
2600
+ }
2601
+ function unregisterConfig(resolvedConfig) {
2602
+ unregisterResolvedVizeConfig(resolvedConfig);
2603
+ releaseCompatibilityRegistration(resolvedConfig);
2604
+ }
2605
+ async function register(resolvedConfig, root, sharedConfigPromise) {
2606
+ releaseCompatibilityRegistration(resolvedConfig);
2607
+ const token = Symbol(root);
2608
+ compatibilityOwners.set(root, token);
2609
+ vizeConfigStore.delete(root);
2610
+ registerResolvedVizeConfig(resolvedConfig, sharedConfigPromise);
2611
+ let sharedConfig;
2612
+ try {
2613
+ sharedConfig = await sharedConfigPromise;
2614
+ } catch (error) {
2615
+ unregisterResolvedVizeConfig(resolvedConfig);
2616
+ if (compatibilityOwners.get(root) === token) {
2617
+ compatibilityOwners.delete(root);
2618
+ vizeConfigStore.delete(root);
2619
+ }
2620
+ throw error;
2621
+ }
2622
+ if (compatibilityOwners.get(root) !== token) return sharedConfig;
2623
+ if (sharedConfig) {
2624
+ compatibilityRegistrations.set(resolvedConfig, {
2625
+ config: sharedConfig,
2626
+ root,
2627
+ token
2628
+ });
2629
+ vizeConfigStore.set(root, sharedConfig);
2630
+ } else {
2631
+ compatibilityOwners.delete(root);
2632
+ vizeConfigStore.delete(root);
2633
+ }
2634
+ return sharedConfig;
2635
+ }
2636
+ function configureServerCleanup(devServer) {
2637
+ const resolvedConfig = devServer.config;
2638
+ let unregistered = false;
2639
+ const unregister = () => {
2640
+ if (unregistered) return;
2641
+ unregistered = true;
2642
+ devServer.httpServer?.off("close", unregister);
2643
+ devServer.watcher.off("close", unregister);
2644
+ unregisterConfig(resolvedConfig);
2645
+ };
2646
+ devServer.httpServer?.once("close", unregister);
2647
+ devServer.watcher.once("close", unregister);
2648
+ }
2649
+ function unregisterBuild(context) {
2650
+ const resolvedConfig = context.environment?.getTopLevelConfig?.();
2651
+ if (resolvedConfig) unregisterConfig(resolvedConfig);
2652
+ }
2468
2653
  //#endregion
2469
2654
  //#region src/plugin/index.ts
2470
2655
  function aliasSortKey(find) {
@@ -2554,29 +2739,8 @@ function vize(options = {}) {
2554
2739
  command: resolvedConfig.command === "build" ? "build" : "serve",
2555
2740
  isSsrBuild: !!resolvedConfig.build?.ssr
2556
2741
  };
2557
- let fileConfig = null;
2558
- if (options.configMode !== false) {
2559
- const configFile = options.configFile ?? process.env["VIZE_CONFIG_FILE"];
2560
- try {
2561
- fileConfig = await loadConfig(state.root, {
2562
- mode: options.configMode ?? "root",
2563
- configFile,
2564
- env: configEnv
2565
- });
2566
- if (fileConfig) state.logger.log("Loaded config from vize.config file");
2567
- } catch (error) {
2568
- state.logger.warn(`Failed to load vize config from ${configFile ?? state.root}:`, error);
2569
- }
2570
- }
2571
- let inlineConfig = null;
2572
- if (options.config) try {
2573
- inlineConfig = await resolveConfigExport(options.config, configEnv);
2574
- state.logger.log("Loaded inline vize config from plugin options");
2575
- } catch (error) {
2576
- state.logger.warn("Failed to resolve inline vize config:", error);
2577
- }
2578
- const sharedConfig = mergeSharedConfig(fileConfig, inlineConfig);
2579
- if (sharedConfig) vizeConfigStore.set(state.root, sharedConfig);
2742
+ const sharedConfigPromise = resolveSharedConfig(options, state.root, configEnv, state.logger);
2743
+ const sharedConfig = await register(resolvedConfig, state.root, sharedConfigPromise);
2580
2744
  const viteConfig = sharedConfig?.vite ?? {};
2581
2745
  const compilerConfig = sharedConfig?.compiler ?? {};
2582
2746
  const compatibility = resolveCompatibilityOptions(options, compilerConfig);
@@ -2637,6 +2801,7 @@ function vize(options = {}) {
2637
2801
  },
2638
2802
  configureServer(devServer) {
2639
2803
  state.server = devServer;
2804
+ configureServerCleanup(devServer);
2640
2805
  installDevMiddleware(devServer, state);
2641
2806
  },
2642
2807
  async buildStart() {
@@ -2670,7 +2835,10 @@ function vize(options = {}) {
2670
2835
  }, this.emitFile.bind(this), bundle);
2671
2836
  },
2672
2837
  closeBundle() {
2673
- if (state.server === null) clearBuildCaches(state);
2838
+ if (state.server === null) {
2839
+ unregisterBuild(this);
2840
+ clearBuildCaches(state);
2841
+ }
2674
2842
  }
2675
2843
  },
2676
2844
  createStylePostTransformPlugin(),
@@ -0,0 +1,26 @@
1
+ import { c as ResolvedVizeConfig } from "../types-x-lq08Y8.mjs";
2
+ import { ResolvedConfig } from "vite";
3
+
4
+ //#region src/internal/config-bridge.d.ts
5
+ /**
6
+ * Exact Vite-instance registration returned to internal companion plugins.
7
+ *
8
+ * A registered promise resolving to null is intentionally distinct from a
9
+ * missing registration: it means the Vize plugin ran and found no config.
10
+ *
11
+ * @internal
12
+ */
13
+ type ResolvedVizeConfigRegistration = {
14
+ readonly registered: false;
15
+ } | {
16
+ readonly registered: true;
17
+ readonly config: Promise<ResolvedVizeConfig | null>;
18
+ };
19
+ /** @internal */
20
+ declare function registerResolvedVizeConfig(resolvedConfig: ResolvedConfig, config: ResolvedVizeConfig | null | Promise<ResolvedVizeConfig | null>): void;
21
+ /** @internal */
22
+ declare function getResolvedVizeConfigRegistration(resolvedConfig: ResolvedConfig): ResolvedVizeConfigRegistration;
23
+ /** @internal */
24
+ declare function unregisterResolvedVizeConfig(resolvedConfig: ResolvedConfig): boolean;
25
+ //#endregion
26
+ export { ResolvedVizeConfigRegistration, getResolvedVizeConfigRegistration, registerResolvedVizeConfig, unregisterResolvedVizeConfig };
@@ -0,0 +1,21 @@
1
+ //#region src/internal/config-bridge.ts
2
+ const registrations = /* @__PURE__ */ new WeakMap();
3
+ const missingRegistration = Object.freeze({ registered: false });
4
+ /** @internal */
5
+ function registerResolvedVizeConfig(resolvedConfig, config) {
6
+ registrations.set(resolvedConfig, Promise.resolve(config));
7
+ }
8
+ /** @internal */
9
+ function getResolvedVizeConfigRegistration(resolvedConfig) {
10
+ if (!registrations.has(resolvedConfig)) return missingRegistration;
11
+ return {
12
+ registered: true,
13
+ config: registrations.get(resolvedConfig)
14
+ };
15
+ }
16
+ /** @internal */
17
+ function unregisterResolvedVizeConfig(resolvedConfig) {
18
+ return registrations.delete(resolvedConfig);
19
+ }
20
+ //#endregion
21
+ export { getResolvedVizeConfigRegistration, registerResolvedVizeConfig, unregisterResolvedVizeConfig };