@csszyx/unplugin 0.14.4 → 0.15.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 (52) hide show
  1. package/README.md +4 -3
  2. package/dist/index.cjs +8 -7
  3. package/dist/index.d.cts +70 -3
  4. package/dist/index.d.mts +70 -3
  5. package/dist/index.mjs +4 -4
  6. package/dist/next-config.d.cts +1 -2
  7. package/dist/next-config.d.mts +1 -2
  8. package/dist/next-prebuild.cjs +9 -5
  9. package/dist/next-prebuild.d.cts +4 -2
  10. package/dist/next-prebuild.d.mts +4 -2
  11. package/dist/next-prebuild.mjs +8 -4
  12. package/dist/next-turbo-loader.cjs +20 -14
  13. package/dist/next-turbo-loader.d.cts +1 -1
  14. package/dist/next-turbo-loader.d.mts +1 -1
  15. package/dist/next-turbo-loader.mjs +19 -13
  16. package/dist/next-watcher.cjs +2 -2
  17. package/dist/next-watcher.d.cts +2 -2
  18. package/dist/next-watcher.d.mts +2 -2
  19. package/dist/next-watcher.mjs +2 -2
  20. package/dist/postcss.cjs +124 -0
  21. package/dist/postcss.d.cts +42 -0
  22. package/dist/postcss.d.mts +42 -0
  23. package/dist/postcss.mjs +107 -0
  24. package/dist/shared/{unplugin.NlPvn5P4.mjs → unplugin.AGR7mihU.mjs} +2 -6
  25. package/dist/shared/{unplugin.BnRf0Tvd.mjs → unplugin.BGufkSFT.mjs} +297 -173
  26. package/dist/shared/{unplugin.BXYakiXt.d.cts → unplugin.BHfqCocB.d.cts} +53 -55
  27. package/dist/shared/{unplugin.BXYakiXt.d.mts → unplugin.BHfqCocB.d.mts} +53 -55
  28. package/dist/shared/{unplugin.RGzhYt-D.cjs → unplugin.BLbrShMZ.cjs} +344 -221
  29. package/dist/shared/{unplugin.DVbPNK3W.cjs → unplugin.BbBYWFGT.cjs} +6 -6
  30. package/dist/shared/{unplugin.BZPdvVcj.mjs → unplugin.BourSpnZ.mjs} +105 -127
  31. package/dist/shared/{unplugin.CPEWNSA0.d.cts → unplugin.C2ilavL1.d.cts} +2 -0
  32. package/dist/shared/{unplugin.CPEWNSA0.d.mts → unplugin.C2ilavL1.d.mts} +2 -0
  33. package/dist/shared/{unplugin.D8BxOOkA.cjs → unplugin.C7i0agiO.cjs} +121 -142
  34. package/dist/shared/{unplugin.CdZxp0x-.d.mts → unplugin.CXCaQ3-s.d.cts} +1 -1
  35. package/dist/shared/{unplugin.xeED_qwh.d.cts → unplugin.CbNydVwv.d.mts} +1 -1
  36. package/dist/shared/unplugin.CqJS0BbD.mjs +211 -0
  37. package/dist/shared/{unplugin.VtXstzEh.cjs → unplugin.DX3rYT4P.cjs} +6 -11
  38. package/dist/shared/{unplugin.Cji6O5jv.cjs → unplugin.Dai5wlZ3.cjs} +27 -19
  39. package/dist/shared/{unplugin.DN95k991.mjs → unplugin.Dbc26ty6.mjs} +2 -2
  40. package/dist/shared/{unplugin.BU0O4IkX.mjs → unplugin.DmCOQc-b.mjs} +22 -16
  41. package/dist/shared/unplugin.KnDCM-sr.cjs +241 -0
  42. package/dist/vite.cjs +4 -4
  43. package/dist/vite.d.cts +2 -2
  44. package/dist/vite.d.mts +1 -1
  45. package/dist/vite.mjs +4 -4
  46. package/dist/webpack.cjs +4 -4
  47. package/dist/webpack.d.cts +2 -1
  48. package/dist/webpack.d.mts +1 -1
  49. package/dist/webpack.mjs +4 -4
  50. package/package.json +19 -9
  51. package/dist/shared/unplugin.B3XoSRB8.mjs +0 -40
  52. package/dist/shared/unplugin.BkRah5Ot.cjs +0 -48
@@ -1,9 +1,9 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import * as fs from 'node:fs';
3
- import { mkdirSync, writeFileSync } from 'node:fs';
3
+ import fs__default, { mkdirSync, writeFileSync } from 'node:fs';
4
4
  import { createRequire } from 'node:module';
5
5
  import * as path from 'node:path';
6
- import { dirname } from 'node:path';
6
+ import path__default, { dirname } from 'node:path';
7
7
  import { performance } from 'node:perf_hooks';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { scanGlobalVarUsages, sortStrings as sortStrings$1, szFallbackConsequenceOf, isWasmTransformAvailable, isRustTransformAvailable, ensureRustTransformAvailable, transformRust, transformWasm, ASTBudgetExceededError, transformRustBatch, transform } from '@csszyx/compiler';
@@ -13,10 +13,10 @@ import { preprocess as preprocess$1 } from '@csszyx/svelte-adapter';
13
13
  import { isTailwindReservedCustomProperty, CSSZYX_GLOBAL_ALIAS_PREFIX, isCsszyxGlobalAliasCustomProperty, DEFAULT_IMPORTED_STATIC_SZ, DEFAULT_BUILD_CONFIG, validateGlobalVarMangleConfig } from '@csszyx/types';
14
14
  import { preprocess } from '@csszyx/vue-adapter';
15
15
  import { createUnplugin } from 'unplugin';
16
- import { n as normalizePathSeparators, c as collectSpecifierAliases, h as recordSzvRegistryFile, j as recordCrossModuleForwards, k as recordSzObjectRegistryFile, l as resolveCrossModuleStaticsFor, r as resolveTransformCacheDir, e as createTransformCacheKey, w as writeTransformCache, m as evictOldTransformCacheEntries, o as mayExportSzvFactories, i as importedSpecifiersIn, s as specifierBases, a as resolveProviderPathWith, g as readTransformCache, p as evictMemoryCacheToBudget, q as resolveProviderPath, d as isReadableProviderFile } from './unplugin.NlPvn5P4.mjs';
16
+ import { c as collectSpecifierAliases, r as resolveTransformCacheDir, h as evictOldTransformCacheEntries, j as recordSzvRegistryFile, k as recordCrossModuleForwards, l as recordSzObjectRegistryFile, m as mayExportSzvFactories, n as resolveCrossModuleStaticsFor, e as createTransformCacheKey, w as writeTransformCache, o as resolveProviderPath, i as importedSpecifiersIn, s as specifierBases, a as resolveProviderPathWith, g as readTransformCache, p as evictMemoryCacheToBudget, d as isReadableProviderFile } from './unplugin.AGR7mihU.mjs';
17
17
  import { mangleCSSSync } from '../css-mangler.mjs';
18
- import { c as createThemeGroupsModule, e as ensureThemeGroupsFile, R as RESOLVED_VIRTUAL_MODULE_ID, d as createMangleMapModule, f as RESOLVED_VIRTUAL_CHECKSUM_ID, g as createChecksumModule, j as RESOLVED_MANGLE_RUNTIME_VIRTUAL_ID, k as createMangleRuntimeModule, l as RESOLVED_THEME_GROUPS_VIRTUAL_ID, n as isVirtualModule, r as resolveVirtualModule, p as parseThemeBlocks, m as mergeThemes, o as discoverProjectTheme, C as CHECKSUM_PLACEHOLDER, M as MANGLE_MAP_PLACEHOLDER, V as VAR_MANGLE_MAP_PLACEHOLDER, q as importsRuntimeHelper, u as findRuntimeImportClause, T as THEME_GROUPS_VIRTUAL_ID, v as THEME_GROUPS_FILE_MARKER, t as themeGroupsSpecifier, w as MANGLE_RUNTIME_VIRTUAL_ID, a as parseUtilityBlocks, x as runtimeHelperGroupsFromUsage, b as insertAfterUseDirective } from './unplugin.BZPdvVcj.mjs';
19
- import { s as sortStrings, a as replaceEveryLiteral, u as unicodeEscape, b as escapeDoubleQuotedString, c as escapeSingleQuotedString, e as escapeHtmlAttribute, r as renderTailwindScannerCandidates } from './unplugin.B3XoSRB8.mjs';
18
+ import { c as createMangleRuntimeModule, M as MANGLE_RUNTIME_VIRTUAL_ID, d as createThemeGroupsModule, e as ensureThemeGroupsFile, R as RESOLVED_VIRTUAL_MODULE_ID, f as createMangleMapModule, g as RESOLVED_VIRTUAL_CHECKSUM_ID, j as createChecksumModule, k as RESOLVED_MANGLE_RUNTIME_VIRTUAL_ID, l as RESOLVED_THEME_GROUPS_VIRTUAL_ID, n as isVirtualModule, r as resolveVirtualModule, p as parseThemeBlocks, m as mergeThemes, o as discoverProjectTheme, C as CHECKSUM_PLACEHOLDER, q as CENSUS_PLACEHOLDER, u as importsRuntimeHelper, v as findRuntimeImportClause, T as THEME_GROUPS_VIRTUAL_ID, w as THEME_GROUPS_FILE_MARKER, t as themeGroupsSpecifier, a as parseUtilityBlocks, x as runtimeHelperGroupsFromUsage, b as insertAfterUseDirective, y as MANGLE_MAP_PLACEHOLDER, V as VAR_MANGLE_MAP_PLACEHOLDER } from './unplugin.BourSpnZ.mjs';
19
+ import { s as sortStrings, n as normalizePathSeparators, g as stripCssBlockComments, S as SAFELIST_FILE, h as findLegacySourceDirective, l as legacySourceMessage, b as cssImportsTailwind, c as computeSafelistRelPath, a as appendTailwindSourceDirective, r as renderSafelistFile, d as removeLegacySafelists } from './unplugin.CqJS0BbD.mjs';
20
20
  import { gzipSync } from 'node:zlib';
21
21
  import postcss from 'postcss';
22
22
  import valueParser from 'postcss-value-parser';
@@ -1710,6 +1710,24 @@ function expandFilePatterns(rootDir, patterns) {
1710
1710
  return sortStrings(files);
1711
1711
  }
1712
1712
 
1713
+ const BACKSLASH = String.fromCodePoint(92);
1714
+ function unicodeEscape(hexadecimal) {
1715
+ return `${BACKSLASH}u${hexadecimal}`;
1716
+ }
1717
+ function replaceEveryLiteral(value, search, replacement) {
1718
+ return value.replaceAll(search, () => replacement);
1719
+ }
1720
+ function escapeSingleQuotedString(value) {
1721
+ let escaped = replaceEveryLiteral(value, BACKSLASH, BACKSLASH.repeat(2));
1722
+ escaped = replaceEveryLiteral(escaped, "'", `${BACKSLASH}'`);
1723
+ escaped = replaceEveryLiteral(escaped, "\r", `${BACKSLASH}r`);
1724
+ return replaceEveryLiteral(escaped, "\n", `${BACKSLASH}n`);
1725
+ }
1726
+ function escapeDoubleQuotedString(value) {
1727
+ const escaped = replaceEveryLiteral(value, BACKSLASH, BACKSLASH.repeat(2));
1728
+ return replaceEveryLiteral(escaped, '"', `${BACKSLASH}"`);
1729
+ }
1730
+
1713
1731
  const LINE_SEPARATOR$1 = String.fromCodePoint(8232);
1714
1732
  const PARAGRAPH_SEPARATOR$1 = String.fromCodePoint(8233);
1715
1733
  function safeJsonForScriptTag(value, prettyPrint = false) {
@@ -1744,31 +1762,22 @@ function injectChecksum(html, checksum, minify = false) {
1744
1762
  const attrName = minify ? "data-sz-cs" : "data-sz-checksum";
1745
1763
  return injectHtmlOpeningAttr(html, ` ${attrName}="${checksum}"`);
1746
1764
  }
1747
- function injectMangleMapScript(html, mangleMap, options = {}) {
1748
- const {
1749
- prettyPrint = false,
1750
- varMangleMap = {},
1751
- globalVarAliasPrefix = CSSZYX_GLOBAL_ALIAS_PREFIX,
1752
- installRuntimeObject = true
1753
- } = options;
1754
- const checksumMap = createHydrationMangleMap(mangleMap, varMangleMap);
1755
- const jsonContent = safeJsonForScriptTag(checksumMap, prettyPrint);
1756
- const varMapContent = safeJsonForScriptTag(varMangleMap);
1757
- const reuseChecksumPayload = Object.keys(varMangleMap).length === 0;
1758
- const classMapExpr = reuseChecksumPayload ? '(function(){var e=document.getElementById("__CSSZYX_MANGLE_MAP__");return e?JSON.parse(e.textContent):{}})()' : safeJsonForScriptTag(mangleMap);
1759
- const scriptTag = `<script id="__CSSZYX_MANGLE_MAP__" type="application/json">${jsonContent}<\/script>`;
1760
- const prefixContent = safeJsonForScriptTag(globalVarAliasPrefix);
1761
- const debugScript = `<script>(function(){var m=${classMapExpr};var vm=${varMapContent};var gp=${prefixContent};var r={};var vr={};for(var k in m)r[m[k]]=k;for(var vk in vm){var vv=vm[vk];var vs=Array.isArray(vv)?vv:[vv];for(var vi=0;vi<vs.length;vi++)(vr[vs[vi]]||(vr[vs[vi]]=[])).push(vk)}var cs=document.documentElement.getAttribute("data-sz-checksum")||"";window.__csszyx={mangleMap:m,varMangleMap:vm,checksum:cs,decode:function(c){return r[c]},encode:function(c){return m[c]},decodeVar:function(v){return vr[v]||[]},encodeVar:function(v){return vm[v]},decodeGlobalVar:function(v){var a=vr[v]||[];return v.indexOf(gp)===0?a[0]:void 0},decodeAll:function(el){return(el.className||"").split(" ").map(function(c){return r[c]||c})}}})()<\/script>`;
1762
- const combined = installRuntimeObject ? `${scriptTag}
1763
- ${debugScript}` : scriptTag;
1765
+ function withScriptTag(html, scriptTag) {
1764
1766
  if (html.includes("</head>")) {
1765
- return html.replace("</head>", `${combined}
1767
+ return html.replace("</head>", `${scriptTag}
1766
1768
  </head>`);
1767
- } else if (html.includes("</html>")) {
1768
- return html.replace("</html>", `${combined}
1769
+ }
1770
+ if (html.includes("</html>")) {
1771
+ return html.replace("</html>", `${scriptTag}
1769
1772
  </html>`);
1770
1773
  }
1771
- return html + combined;
1774
+ return html + scriptTag;
1775
+ }
1776
+ function injectMangleMapScript(html, mangleMap, options = {}) {
1777
+ const { prettyPrint = false, varMangleMap = {} } = options;
1778
+ const checksumMap = createHydrationMangleMap(mangleMap, varMangleMap);
1779
+ const scriptTag = `<script id="__CSSZYX_MANGLE_MAP__" type="application/json">${safeJsonForScriptTag(checksumMap, prettyPrint)}<\/script>`;
1780
+ return withScriptTag(html, scriptTag);
1772
1781
  }
1773
1782
  function injectMangleMapAttribute(html, mangleMap, minify = false, varMangleMap = {}) {
1774
1783
  const attrName = minify ? "data-sz-m" : "data-sz-map";
@@ -1842,14 +1851,7 @@ function injectRecoveryManifest(html, manifest) {
1842
1851
  }
1843
1852
  const json = JSON.stringify(manifest);
1844
1853
  const scriptTag = `<script id="__SZ_RECOVERY_MANIFEST__" type="application/json">${json}<\/script>`;
1845
- if (html.includes("</head>")) {
1846
- return html.replace("</head>", `${scriptTag}
1847
- </head>`);
1848
- } else if (html.includes("</html>")) {
1849
- return html.replace("</html>", `${scriptTag}
1850
- </html>`);
1851
- }
1852
- return html + scriptTag;
1854
+ return withScriptTag(html, scriptTag);
1853
1855
  }
1854
1856
 
1855
1857
  const LINE_SEPARATOR = String.fromCodePoint(8232);
@@ -1861,10 +1863,87 @@ function escapeJsonForInlineScript(json) {
1861
1863
  escaped = replaceEveryLiteral(escaped, LINE_SEPARATOR, unicodeEscape("2028"));
1862
1864
  return replaceEveryLiteral(escaped, PARAGRAPH_SEPARATOR, unicodeEscape("2029"));
1863
1865
  }
1866
+ function escapeJsonForStringLiteral(json) {
1867
+ let escaped = replaceEveryLiteral(json, "\\", unicodeEscape("005c"));
1868
+ for (const [character, code] of [
1869
+ ['"', "0022"],
1870
+ ["'", "0027"],
1871
+ ["`", "0060"],
1872
+ ["$", "0024"],
1873
+ ["<", "003c"],
1874
+ [">", "003e"],
1875
+ [LINE_SEPARATOR, "2028"],
1876
+ [PARAGRAPH_SEPARATOR, "2029"]
1877
+ ]) {
1878
+ escaped = replaceEveryLiteral(escaped, character, unicodeEscape(code));
1879
+ }
1880
+ return escaped;
1881
+ }
1864
1882
  function escapeForDoubleQuotedString(value) {
1865
1883
  return escapeDoubleQuotedString(value);
1866
1884
  }
1867
1885
 
1886
+ function createLazyAggregate(build, initial) {
1887
+ const entries = /* @__PURE__ */ new Map();
1888
+ let current = initial;
1889
+ let dirty = false;
1890
+ return {
1891
+ entries,
1892
+ set(key, entry) {
1893
+ entries.set(key, entry);
1894
+ dirty = true;
1895
+ },
1896
+ delete(key) {
1897
+ if (entries.delete(key)) dirty = true;
1898
+ },
1899
+ get() {
1900
+ if (dirty) {
1901
+ current = build(entries);
1902
+ dirty = false;
1903
+ }
1904
+ return current;
1905
+ }
1906
+ };
1907
+ }
1908
+
1909
+ function needsRuntimeMangleRegistration(manglingEnabled, mangleMap) {
1910
+ if (!manglingEnabled) return false;
1911
+ return Object.keys(mangleMap).length > 0;
1912
+ }
1913
+ function removedMangleMapDeliveryMessage() {
1914
+ return "[csszyx] production.mangleMapDelivery has been removed and is ignored. The runtime mangle map is always registered from inside the JS bundle now, on every lane, so the built HTML never carries an executable inline <script> and a strict script-src 'self' policy needs no exception. Delete the option. (`window.__csszyx` is now opt-in through `production.mangleDebugGlobal`.)";
1915
+ }
1916
+
1917
+ const MANGLE_RUNTIME_FILE = "mangle-runtime.mjs";
1918
+ function ensureMangleRuntimeFile(outputDir, globalVarAliasPrefix, exposeDebugGlobal) {
1919
+ const target = path__default.join(outputDir, MANGLE_RUNTIME_FILE);
1920
+ const staging = `${target}.${process.pid}.tmp`;
1921
+ try {
1922
+ fs__default.mkdirSync(outputDir, { recursive: true });
1923
+ fs__default.writeFileSync(
1924
+ staging,
1925
+ createMangleRuntimeModule(globalVarAliasPrefix, exposeDebugGlobal),
1926
+ "utf8"
1927
+ );
1928
+ fs__default.renameSync(staging, target);
1929
+ return target;
1930
+ } catch {
1931
+ try {
1932
+ fs__default.rmSync(staging, { force: true });
1933
+ } catch {
1934
+ }
1935
+ return null;
1936
+ }
1937
+ }
1938
+ function applyMangleRuntimeEntry(compiler, context, file, onRegistered) {
1939
+ const EntryPlugin = compiler.webpack?.EntryPlugin;
1940
+ if (EntryPlugin === void 0) {
1941
+ return;
1942
+ }
1943
+ new EntryPlugin(context, file, { name: void 0 }).apply(compiler);
1944
+ onRegistered();
1945
+ }
1946
+
1868
1947
  function createMangleSizeAccount() {
1869
1948
  return { cssGzBefore: 0, cssGzAfter: 0, codeGzBefore: 0, codeGzAfter: 0, channels: /* @__PURE__ */ new Set() };
1870
1949
  }
@@ -1912,7 +1991,7 @@ function mangleSizeMessage(verdict) {
1912
1991
  const cssPart = verdict.cssSaving >= 0 ? `the mangled CSS saves ${verdict.cssSaving} B` : `the mangled CSS COSTS ${-verdict.cssSaving} B (short tokens compress worse than the names they replaced)`;
1913
1992
  const codePart = verdict.codeSaving >= 0 ? `the shortened classes in code save ${verdict.codeSaving} B` : `the shortened classes in code COST ${-verdict.codeSaving} B`;
1914
1993
  const channelPart = verdict.channels.length > 1 ? `${verdict.channels.join(" + ")} (${verdict.channels.length} copies)` : verdict.channels[0];
1915
- return `[csszyx] production.mangle is making this build BIGGER: +${verdict.net} B gzipped. The runtime mangle map costs ${verdict.mapCost} B via ${channelPart}, while ${cssPart} and ${codePart}. Mangling is a name-obfuscation feature; over a compressed response it does not reduce payload, because utility class names compress far better than the map they need. If you enabled it for size, set \`production.mangle: false\`. If you enabled it to hide class names, this is the expected price and you can ignore this. Narrowing \`production.mangleMapDelivery\` removes a map copy when only one channel is needed.`;
1994
+ return `[csszyx] production.mangle is making this build BIGGER: +${verdict.net} B gzipped. The runtime mangle map costs ${verdict.mapCost} B via ${channelPart}, while ${cssPart} and ${codePart}. Mangling is a name-obfuscation feature; over a compressed response it does not reduce payload, because utility class names compress far better than the map they need. If you enabled it for size, set \`production.mangle: false\`. If you enabled it to hide class names, this is the expected price and you can ignore this. Two copies is not a misconfiguration: the bundle carries the map the runtime reads, and the HTML carries the same census for the hydration checksum.`;
1916
1995
  }
1917
1996
 
1918
1997
  function isParserMode(value) {
@@ -2113,41 +2192,6 @@ function resolveNativeCacheIdentity() {
2113
2192
  }
2114
2193
  const BENCH_TRACE_ENABLED = process.env.CSSZYX_BENCH_TRACE === "1";
2115
2194
  const BENCH_TRACE_FILE = process.env.CSSZYX_BENCH_TRACE_FILE;
2116
- function appendTailwindSourceDirective(code, relPath) {
2117
- const directive = `@source "${relPath}";`;
2118
- if (code.includes(directive)) {
2119
- return null;
2120
- }
2121
- const separator = code.length === 0 || code.endsWith("\n") ? "" : "\n";
2122
- return `${code}${separator}${directive}
2123
- `;
2124
- }
2125
- function stripCssBlockComments(code) {
2126
- const SLASH = 47;
2127
- const STAR = 42;
2128
- let out = "";
2129
- let last = 0;
2130
- let i = 0;
2131
- const n = code.length;
2132
- while (i < n) {
2133
- if (code.codePointAt(i) === SLASH && code.codePointAt(i + 1) === STAR) {
2134
- out += code.slice(last, i);
2135
- i += 2;
2136
- while (i < n && !(code.codePointAt(i) === STAR && code.codePointAt(i + 1) === SLASH)) {
2137
- i++;
2138
- }
2139
- i += 2;
2140
- last = i;
2141
- } else {
2142
- i++;
2143
- }
2144
- }
2145
- return out + code.slice(last);
2146
- }
2147
- function cssImportsTailwind(code) {
2148
- const withoutBlockComments = stripCssBlockComments(code);
2149
- return /@import\s+["']tailwindcss(?:\/[^"']*)?["']/.test(withoutBlockComments);
2150
- }
2151
2195
  function hasInjectableTailwindCandidate(classes) {
2152
2196
  for (const c of classes) {
2153
2197
  if (c.length >= 2 && /^[a-z]/.test(c)) {
@@ -2398,15 +2442,6 @@ function watchModeMangleMessage() {
2398
2442
  function realContentHashDisabledMessage() {
2399
2443
  return "[csszyx] optimization.realContentHash is off while production.mangle is on. csszyx mangles assets after webpack computes their content hashes, and realContentHash is what recomputes those hashes from the final bytes. Without it, two builds that differ only by mangling emit the same filenames with different contents and caches keep serving the old file.";
2400
2444
  }
2401
- function computeSafelistRelPath(rootDir, safelistFilename, cssId) {
2402
- const safelistPath = normalizePathSeparators(path.join(rootDir, safelistFilename));
2403
- const cssDir = normalizePathSeparators(path.dirname(cssId));
2404
- let relPath = path.posix.relative(cssDir, safelistPath);
2405
- if (!relPath.startsWith(".")) {
2406
- relPath = `./${relPath}`;
2407
- }
2408
- return relPath;
2409
- }
2410
2445
  function cssVariableEntries(result) {
2411
2446
  const entries = [];
2412
2447
  for (const [original, value] of result.cssVariableMap ?? []) {
@@ -2427,7 +2462,6 @@ function recordFileVarMangleEntries(state, filename, entries) {
2427
2462
  } else {
2428
2463
  state.varMangleEntriesByFile.set(normalizedFilename, entries);
2429
2464
  }
2430
- state.varMangleMap = buildVarMangleMap(state.varMangleEntriesByFile);
2431
2465
  }
2432
2466
  function shouldTrackGlobalVarSources(config) {
2433
2467
  return config?.enabled === true;
@@ -2662,7 +2696,6 @@ function recordFileCSSVariableMetrics(state, filename, code) {
2662
2696
  state.cssVarMetricsByFile.delete(normalizedFilename);
2663
2697
  }
2664
2698
  }
2665
- state.cssVarMetrics = buildCSSVariableMetrics(state.cssVarMetricsByFile);
2666
2699
  }
2667
2700
  function collectCSSVariableMetrics(code) {
2668
2701
  const componentUses = /* @__PURE__ */ new Map();
@@ -3095,20 +3128,18 @@ function createCsszyxPlugins(options = {}) {
3095
3128
  let specifierAliases = [];
3096
3129
  const mangleReserved = new Set(options.production?.mangleExclude ?? []);
3097
3130
  let mangleMapFrozen = false;
3131
+ let prescanSawServerModule = false;
3132
+ let skipRscRecords = false;
3133
+ let lastPrescanCacheMisses = 0;
3098
3134
  let frozenOwnedClasses = /* @__PURE__ */ new Set();
3099
3135
  let frozenAuthoredClasses = /* @__PURE__ */ new Set();
3100
3136
  let cssRewrittenInTransform = false;
3101
3137
  let projectCssFiles = [];
3102
3138
  const transformMangledSources = /* @__PURE__ */ new Set();
3103
3139
  const transformExternalClasses = /* @__PURE__ */ new Set();
3104
- const mangleMapDelivery = options.production?.mangleMapDelivery ?? "both";
3105
- if (!["both", "html", "bundle"].includes(mangleMapDelivery)) {
3106
- throw new Error(
3107
- `[csszyx] production.mangleMapDelivery must be 'both', 'html' or 'bundle'; got ${JSON.stringify(mangleMapDelivery)}.`
3108
- );
3140
+ if (options.production?.mangleMapDelivery !== void 0) {
3141
+ console.warn(removedMangleMapDeliveryMessage());
3109
3142
  }
3110
- const deliverMapInHtml = mangleMapDelivery !== "bundle";
3111
- const deliverMapInBundle = mangleMapDelivery !== "html";
3112
3143
  const sizeAccount = createMangleSizeAccount();
3113
3144
  const astBudgetOverride = options.build?.astBudgetLimit;
3114
3145
  const prescanAstBudget = astBudgetOverride ?? 5e5;
@@ -3119,7 +3150,6 @@ function createCsszyxPlugins(options = {}) {
3119
3150
  const globalVarMangleConfig = options.production?.mangleGlobalVars;
3120
3151
  const globalVarSourceTrackingEnabled = shouldTrackGlobalVarSources(globalVarMangleConfig);
3121
3152
  const globalVarAliasPrefix = globalVarMangleConfig?.aliasPrefix ?? CSSZYX_GLOBAL_ALIAS_PREFIX;
3122
- const encodedGlobalVarAliasPrefix = encodeURIComponent(globalVarAliasPrefix);
3123
3153
  const earlyGlobalVarAliasEntries = createEarlyGlobalVarAliasEntries(
3124
3154
  globalVarMangleConfig,
3125
3155
  globalVarAliasPrefix
@@ -3174,12 +3204,21 @@ function createCsszyxPlugins(options = {}) {
3174
3204
  const transformMemoryCache = /* @__PURE__ */ new Map();
3175
3205
  let transformMemoryCacheCodeChars = 0;
3176
3206
  const prescanResultHandoff = /* @__PURE__ */ new Map();
3207
+ const varMangleEntries = createLazyAggregate(
3208
+ buildVarMangleMap,
3209
+ Object.fromEntries(earlyGlobalVarAliasEntries)
3210
+ );
3211
+ const cssVarMetricTotals = createLazyAggregate(
3212
+ buildCSSVariableMetrics,
3213
+ emptyCSSVariableMetrics()
3214
+ );
3177
3215
  const state = {
3178
3216
  classes: /* @__PURE__ */ new Set(),
3179
3217
  parsedTheme: null,
3180
3218
  scanCssTheme: null,
3181
3219
  autoThemeCssFiles: [],
3182
3220
  sawTailwindEntry: false,
3221
+ tailwindEntryFiles: /* @__PURE__ */ new Set(),
3183
3222
  sawAnyCss: false,
3184
3223
  tailwindWarningEmitted: false,
3185
3224
  tailwindEntryScoped: false,
@@ -3193,10 +3232,14 @@ function createCsszyxPlugins(options = {}) {
3193
3232
  ownedClasses: /* @__PURE__ */ new Set(),
3194
3233
  authoredClasses: /* @__PURE__ */ new Set(),
3195
3234
  mangleMap: {},
3196
- varMangleEntriesByFile: /* @__PURE__ */ new Map(),
3197
- varMangleMap: Object.fromEntries(earlyGlobalVarAliasEntries),
3198
- cssVarMetricsByFile: /* @__PURE__ */ new Map(),
3199
- cssVarMetrics: emptyCSSVariableMetrics(),
3235
+ varMangleEntriesByFile: varMangleEntries,
3236
+ get varMangleMap() {
3237
+ return varMangleEntries.get();
3238
+ },
3239
+ cssVarMetricsByFile: cssVarMetricTotals,
3240
+ get cssVarMetrics() {
3241
+ return cssVarMetricTotals.get();
3242
+ },
3200
3243
  checksum: "",
3201
3244
  finalized: false,
3202
3245
  rootDir: process.cwd(),
@@ -3208,7 +3251,7 @@ function createCsszyxPlugins(options = {}) {
3208
3251
  if (earlyGlobalVarAliasEntries.length > 0) {
3209
3252
  state.varMangleEntriesByFile.set(GLOBAL_VAR_ALIAS_MAP_OWNER, earlyGlobalVarAliasEntries);
3210
3253
  }
3211
- const SAFELIST_FILENAME = "csszyx-classes.html";
3254
+ const SAFELIST_FILENAME = SAFELIST_FILE;
3212
3255
  const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
3213
3256
  ".tsx",
3214
3257
  ".jsx",
@@ -3361,6 +3404,7 @@ function createCsszyxPlugins(options = {}) {
3361
3404
  );
3362
3405
  if (cached) return cached;
3363
3406
  }
3407
+ lastPrescanCacheMisses++;
3364
3408
  const execution = runConfiguredParser(source, effectiveFilename, compilerOptions);
3365
3409
  if (cacheEnabled && cacheKey && execution.cacheable) {
3366
3410
  writeTransformCache(cacheRoot, cacheInput, execution.result, cacheKey);
@@ -3447,6 +3491,7 @@ function createCsszyxPlugins(options = {}) {
3447
3491
  if (cacheEnabled) evictTransformCacheOnce();
3448
3492
  ensureRustTransformAvailable();
3449
3493
  const misses = collectRustPrescanMisses(batchable, compilerOptions, cacheRoot, results);
3494
+ lastPrescanCacheMisses += misses.length;
3450
3495
  if (misses.length > 0) {
3451
3496
  try {
3452
3497
  runRustPrescanBatch(misses, compilerOptions, cacheRoot, results);
@@ -3590,12 +3635,7 @@ function createCsszyxPlugins(options = {}) {
3590
3635
  return;
3591
3636
  }
3592
3637
  const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
3593
- const classNames = Array.from(classes);
3594
- const classList = escapeHtmlAttribute(classNames.join(" "));
3595
- const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
3596
- <!-- Tailwind CSS scans this file for class name detection -->
3597
- <div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
3598
- ` + renderTailwindScannerCandidates(classNames);
3638
+ const content = renderSafelistFile(Array.from(classes));
3599
3639
  try {
3600
3640
  let existing = "";
3601
3641
  try {
@@ -3606,7 +3646,9 @@ function createCsszyxPlugins(options = {}) {
3606
3646
  }
3607
3647
  }
3608
3648
  if (existing !== content) {
3649
+ fs.mkdirSync(path.dirname(safelistPath), { recursive: true });
3609
3650
  fs.writeFileSync(safelistPath, content);
3651
+ removeLegacySafelists(state.rootDir, console.warn);
3610
3652
  }
3611
3653
  } catch {
3612
3654
  }
@@ -3746,6 +3788,7 @@ function createCsszyxPlugins(options = {}) {
3746
3788
  szvCrossModuleRegistry.clear();
3747
3789
  szvCrossModuleForwards.clear();
3748
3790
  szObjectProvidersExamined.clear();
3791
+ prescanSawServerModule = false;
3749
3792
  const prescanStarted = performance.now();
3750
3793
  const discoveredClasses = /* @__PURE__ */ new Set();
3751
3794
  const rawDiscoveredClasses = /* @__PURE__ */ new Set();
@@ -3764,6 +3807,9 @@ function createCsszyxPlugins(options = {}) {
3764
3807
  return;
3765
3808
  }
3766
3809
  recordAuthoredClasses(content);
3810
+ if (!prescanSawServerModule && isRSCServerModule(content, filePath)) {
3811
+ prescanSawServerModule = true;
3812
+ }
3767
3813
  recordSzvRegistryEntries(filePath, content);
3768
3814
  recordCrossModuleForwards(szvCrossModuleForwards, filePath, content);
3769
3815
  seenSourcePaths.add(normalizePathSeparators(filePath));
@@ -3803,6 +3849,7 @@ function createCsszyxPlugins(options = {}) {
3803
3849
  }
3804
3850
  }
3805
3851
  }
3852
+ const walkStarted = performance.now();
3806
3853
  scanDir(state.rootDir);
3807
3854
  const normRoot = normalizeForMatch(state.rootDir);
3808
3855
  for (const sourceDir of compileSourceDirs) {
@@ -3811,7 +3858,20 @@ function createCsszyxPlugins(options = {}) {
3811
3858
  }
3812
3859
  scanDir(sourceDir);
3813
3860
  }
3861
+ traceBenchTiming(
3862
+ `prescan:walk files=${seenSourcePaths.size} sz=${prescanSources.length}`,
3863
+ state.rootDir,
3864
+ performance.now() - walkStarted
3865
+ );
3866
+ const demandStarted = performance.now();
3814
3867
  recordDemandedSzObjectProviders(seenSourcePaths, szObjectDemand);
3868
+ traceBenchTiming(
3869
+ `prescan:demand providers=${szObjectProvidersExamined.size}`,
3870
+ state.rootDir,
3871
+ performance.now() - demandStarted
3872
+ );
3873
+ const batchStarted = performance.now();
3874
+ lastPrescanCacheMisses = 0;
3815
3875
  const prescanContentByPath = new Map(
3816
3876
  prescanSources.map((file) => [file.filePath, file.content])
3817
3877
  );
@@ -3824,12 +3884,23 @@ function createCsszyxPlugins(options = {}) {
3824
3884
  rawDiscoveredClasses
3825
3885
  );
3826
3886
  }
3887
+ traceBenchTiming(
3888
+ `prescan:batch files=${prescanSources.length} misses=${lastPrescanCacheMisses}`,
3889
+ state.rootDir,
3890
+ performance.now() - batchStarted
3891
+ );
3827
3892
  for (const cls of discoveredClasses) {
3828
3893
  addSafelistClass(cls);
3829
3894
  state.ownedClasses.add(cls);
3830
3895
  }
3831
3896
  const safelistClasses = /* @__PURE__ */ new Set([...discoveredClasses, ...rawDiscoveredClasses]);
3897
+ const safelistStarted = performance.now();
3832
3898
  writeSafelistFile(safelistClasses);
3899
+ traceBenchTiming(
3900
+ `prescan:safelist classes=${safelistClasses.size}`,
3901
+ state.rootDir,
3902
+ performance.now() - safelistStarted
3903
+ );
3833
3904
  traceBenchTiming("prescan", state.rootDir, performance.now() - prescanStarted);
3834
3905
  }
3835
3906
  function collectPrescanResult(result, filePath, discoveredClasses, rawDiscoveredClasses) {
@@ -4008,6 +4079,12 @@ function createCsszyxPlugins(options = {}) {
4008
4079
  result = result.split(CHECKSUM_PLACEHOLDER).join(state.checksum);
4009
4080
  }
4010
4081
  const isEvalWrapped = result.includes("eval(") && result.includes("sourceURL=webpack");
4082
+ if (result.includes(CENSUS_PLACEHOLDER)) {
4083
+ const census = safeJsonForScriptTag(
4084
+ createHydrationMangleMap(state.mangleMap, state.varMangleMap)
4085
+ );
4086
+ result = result.split(CENSUS_PLACEHOLDER).join(escapeJsonForStringLiteral(census));
4087
+ }
4011
4088
  if (result.includes(MANGLE_MAP_PLACEHOLDER)) {
4012
4089
  const jsonMap = escapeJsonForInlineScript(JSON.stringify(state.mangleMap));
4013
4090
  const escapedMap = isEvalWrapped ? escapeForDoubleQuotedString(jsonMap) : jsonMap;
@@ -4037,10 +4114,78 @@ function createCsszyxPlugins(options = {}) {
4037
4114
  usesBoolClass: false
4038
4115
  };
4039
4116
  }
4117
+ function recordUntransformedHotFile(file, content) {
4118
+ trackGlobalVarSourceFile(file, content);
4119
+ recordFileVarMangleEntries(state, file, []);
4120
+ recordFileCSSVariableMetrics(state, file, null);
4121
+ }
4122
+ function discoverHotFileClasses(file, watcher) {
4123
+ if (!shouldProcessSource(file)) {
4124
+ return;
4125
+ }
4126
+ let fileContent, result;
4127
+ try {
4128
+ fileContent = fs.readFileSync(file, "utf-8");
4129
+ } catch {
4130
+ refreshSzvRegistryEntry(file, null);
4131
+ return;
4132
+ }
4133
+ refreshSzvRegistryEntry(file, fileContent);
4134
+ if (!fileContent.includes("sz=") && !fileContent.includes("szs=") && !/\bsz\s*:\s*["'{]/.test(fileContent)) {
4135
+ recordUntransformedHotFile(file, fileContent);
4136
+ return;
4137
+ }
4138
+ try {
4139
+ const hmrTransformStarted = performance.now();
4140
+ result = transformConfiguredSource(fileContent, file);
4141
+ traceBenchTiming("handle-hot-update", file, performance.now() - hmrTransformStarted);
4142
+ } catch {
4143
+ recordUntransformedHotFile(file, fileContent);
4144
+ return;
4145
+ }
4146
+ if (!result.transformed) {
4147
+ recordUntransformedHotFile(file, fileContent);
4148
+ return;
4149
+ }
4150
+ recordHotTransformResult(file, fileContent, result, watcher);
4151
+ }
4152
+ function recordHotTransformResult(file, fileContent, result, watcher) {
4153
+ const sizeBefore = state.classes.size;
4154
+ trackGlobalVarSourceFile(file, fileContent);
4155
+ for (const cls of result.classes) {
4156
+ addSafelistClass(cls);
4157
+ state.ownedClasses.add(cls);
4158
+ }
4159
+ recordFileVarMangleEntries(state, file, cssVariableEntries(result));
4160
+ recordFileCSSVariableMetrics(state, file, result.code);
4161
+ for (const [token, data] of result.recoveryTokens) {
4162
+ state.recoveryTokens.set(token, data);
4163
+ }
4164
+ if (state.classes.size > sizeBefore) {
4165
+ writeSafelistFile(state.classes);
4166
+ const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
4167
+ watcher.emit("change", safelistPath);
4168
+ }
4169
+ }
4170
+ function tailwindEntryModules(moduleGraph) {
4171
+ const modules = [];
4172
+ for (const file of state.tailwindEntryFiles) {
4173
+ const found = moduleGraph.getModulesByFile(file);
4174
+ if (found) modules.push(...found);
4175
+ }
4176
+ return modules;
4177
+ }
4040
4178
  function transformTailwindCssEntry(code, id) {
4041
4179
  state.sawAnyCss = true;
4180
+ const [cssFile] = id.split("?");
4181
+ const legacy = findLegacySourceDirective(code, cssFile);
4182
+ if (legacy !== null) {
4183
+ throw new Error(legacySourceMessage(cssFile, legacy.target));
4184
+ }
4042
4185
  if (!cssImportsTailwind(code)) return null;
4043
4186
  state.sawTailwindEntry = true;
4187
+ const [entryFile] = id.split("?");
4188
+ state.tailwindEntryFiles.add(entryFile);
4044
4189
  if (cssHasContentScope(code)) state.tailwindEntryScoped = true;
4045
4190
  if (!hasInjectableTailwindCandidate(state.classes)) return null;
4046
4191
  const relPath = computeSafelistRelPath(state.rootDir, SAFELIST_FILENAME, id);
@@ -4112,16 +4257,16 @@ function createCsszyxPlugins(options = {}) {
4112
4257
  if (!code.includes("<html") || !/(?:layout|Root|Document|app)\.tsx?$/i.test(id)) {
4113
4258
  return null;
4114
4259
  }
4115
- let transformedCode = code;
4116
4260
  const attrName = options.production?.minify ? "data-sz-cs" : "data-sz-checksum";
4117
- const htmlTag = findOpeningTag(transformedCode, "html");
4118
- if (htmlTag) {
4119
- transformedCode = `${transformedCode.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${transformedCode.slice(htmlTag.close)}`;
4261
+ const htmlTag = findOpeningTag(code, "html");
4262
+ if (!htmlTag) {
4263
+ return code;
4120
4264
  }
4121
- const debugScript = `<script dangerouslySetInnerHTML={{__html: \`(function(){var m=${MANGLE_MAP_PLACEHOLDER};var vm=${VAR_MANGLE_MAP_PLACEHOLDER};var gp=decodeURIComponent(${escapeJsonForInlineScript(JSON.stringify(encodedGlobalVarAliasPrefix))});var r={};var vr={};for(var k in m)r[m[k]]=k;for(var vk in vm){var vv=vm[vk];var vs=Array.isArray(vv)?vv:[vv];for(var vi=0;vi<vs.length;vi++)(vr[vs[vi]]||(vr[vs[vi]]=[])).push(vk)}window.__csszyx={mangleMap:m,varMangleMap:vm,checksum:"${CHECKSUM_PLACEHOLDER}",decode:function(c){return r[c]},encode:function(c){return m[c]},decodeVar:function(v){return vr[v]||[]},encodeVar:function(v){return vm[v]},decodeGlobalVar:function(v){var a=vr[v]||[];return v.indexOf(gp)===0?a[0]:void 0},decodeAll:function(el){return(el.className||"").split(" ").map(function(c){return r[c]||c})}}})()\`}} />`;
4265
+ let transformedCode = `${code.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${code.slice(htmlTag.close)}`;
4266
+ const censusTag = `<script id="__CSSZYX_MANGLE_MAP__" type="application/json" dangerouslySetInnerHTML={{__html: \`${CENSUS_PLACEHOLDER}\`}} />`;
4122
4267
  const bodyTag = findOpeningTag(transformedCode, "body");
4123
4268
  if (bodyTag) {
4124
- transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${debugScript}${transformedCode.slice(bodyTag.close + 1)}`;
4269
+ transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${censusTag}${transformedCode.slice(bodyTag.close + 1)}`;
4125
4270
  }
4126
4271
  return transformedCode;
4127
4272
  }
@@ -4187,12 +4332,22 @@ ${transformedCode}`;
4187
4332
  if (activeFramework !== "vite" && activeFramework !== "rollup") {
4188
4333
  return null;
4189
4334
  }
4190
- if (!manglingEnabled || !deliverMapInBundle || !shouldProcessSource(id) || !MANGLE_RUNTIME_CONSUMER_RE.test(transformedCode) || transformedCode.includes(MANGLE_RUNTIME_VIRTUAL_ID)) {
4335
+ if (!manglingEnabled || !shouldProcessSource(id) || !MANGLE_RUNTIME_CONSUMER_RE.test(transformedCode) || transformedCode.includes(MANGLE_RUNTIME_VIRTUAL_ID)) {
4191
4336
  return null;
4192
4337
  }
4193
4338
  return insertRuntimeImport(transformedCode, `import '${MANGLE_RUNTIME_VIRTUAL_ID}';
4194
4339
  `);
4195
4340
  }
4341
+ function applyWebpackMangleRuntimeEntry(compiler) {
4342
+ const root = compiler.context;
4343
+ const file = ensureMangleRuntimeFile(
4344
+ path.join(root, ".csszyx"),
4345
+ globalVarAliasPrefix,
4346
+ options.production?.mangleDebugGlobal === true
4347
+ );
4348
+ if (file === null) return;
4349
+ applyMangleRuntimeEntry(compiler, root, file, () => sizeAccount.channels.add("bundle"));
4350
+ }
4196
4351
  function collectPreTransformClasses(output) {
4197
4352
  if (!output.transformed && !output.code.includes("class=") && !output.code.includes("className=")) {
4198
4353
  return null;
@@ -4258,7 +4413,10 @@ ${transformedCode}`;
4258
4413
  }
4259
4414
  if (id === RESOLVED_MANGLE_RUNTIME_VIRTUAL_ID) {
4260
4415
  sizeAccount.channels.add("bundle");
4261
- return createMangleRuntimeModule(globalVarAliasPrefix);
4416
+ return createMangleRuntimeModule(
4417
+ globalVarAliasPrefix,
4418
+ options.production?.mangleDebugGlobal === true
4419
+ );
4262
4420
  }
4263
4421
  if (id === RESOLVED_THEME_GROUPS_VIRTUAL_ID) {
4264
4422
  return createThemeGroupsModule(themeGroupTokens());
@@ -4336,8 +4494,10 @@ ${transformedCode}`;
4336
4494
  }
4337
4495
  if (matchesScriptExtension(id, SCRIPT_ID_EXTENSIONS)) {
4338
4496
  assertNoRSCBoundaryViolation(output.code, id);
4339
- const record = createRSCModuleRecord(output.code, id);
4340
- state.rscModules.set(record.id, record);
4497
+ if (!skipRscRecords) {
4498
+ const record = createRSCModuleRecord(output.code, id);
4499
+ state.rscModules.set(record.id, record);
4500
+ }
4341
4501
  }
4342
4502
  return collectPreTransformClasses(output);
4343
4503
  },
@@ -4414,10 +4574,8 @@ ${transformedCode}`;
4414
4574
  if (compiler.options?.mode === "development") {
4415
4575
  manglingEnabled = false;
4416
4576
  }
4417
- if (manglingEnabled && mangleMapDelivery !== "both") {
4418
- console.warn(
4419
- `[csszyx] production.mangleMapDelivery: '${mangleMapDelivery}' has no effect on the webpack lane \u2014 map delivery only narrows on vite/rollup builds.`
4420
- );
4577
+ if (manglingEnabled) {
4578
+ applyWebpackMangleRuntimeEntry(compiler);
4421
4579
  }
4422
4580
  compiler.hooks.beforeCompile.tap("csszyx:prescan", () => {
4423
4581
  announceActiveParser();
@@ -4476,6 +4634,7 @@ ${transformedCode}`;
4476
4634
  }
4477
4635
  evictTransformCacheOnce();
4478
4636
  prescanAndWriteClasses();
4637
+ skipRscRecords = config.command === "build" && !config.build?.watch && !prescanSawServerModule;
4479
4638
  state.scanCssTheme = runThemeScan(root, options.build?.scanCss) ?? state.scanCssTheme;
4480
4639
  runAutoThemeScan(root);
4481
4640
  if (config.command === "build") {
@@ -4489,8 +4648,11 @@ ${transformedCode}`;
4489
4648
  },
4490
4649
  /**
4491
4650
  * Vite HMR hook: re-runs theme scan when a watched CSS file changes,
4492
- * and incrementally updates csszyx-classes.html when a source file gains new sz classes.
4651
+ * and incrementally updates the safelist when a source file gains new sz classes.
4493
4652
  * @param ctx - HMR context containing the changed file
4653
+ * @returns The modules a safelist write affects, so Vite hot-updates
4654
+ * the stylesheet instead of reloading the page; undefined otherwise,
4655
+ * which leaves Vite's own handling in place.
4494
4656
  */
4495
4657
  handleHotUpdate(ctx) {
4496
4658
  prescanResultHandoff.clear();
@@ -4515,59 +4677,11 @@ ${transformedCode}`;
4515
4677
  ctx.server.ws.send({ type: "full-reload" });
4516
4678
  }
4517
4679
  }
4518
- if (!shouldProcessSource(ctx.file)) {
4519
- return;
4520
- }
4521
- let fileContent, result;
4522
- try {
4523
- fileContent = fs.readFileSync(ctx.file, "utf-8");
4524
- } catch {
4525
- refreshSzvRegistryEntry(ctx.file, null);
4526
- return;
4527
- }
4528
- refreshSzvRegistryEntry(ctx.file, fileContent);
4529
- if (!fileContent.includes("sz=") && !fileContent.includes("szs=") && !/\bsz\s*:\s*["'{]/.test(fileContent)) {
4530
- trackGlobalVarSourceFile(ctx.file, fileContent);
4531
- recordFileVarMangleEntries(state, ctx.file, []);
4532
- recordFileCSSVariableMetrics(state, ctx.file, null);
4533
- return;
4534
- }
4535
- try {
4536
- const hmrTransformStarted = performance.now();
4537
- result = transformConfiguredSource(fileContent, ctx.file);
4538
- traceBenchTiming(
4539
- "handle-hot-update",
4540
- ctx.file,
4541
- performance.now() - hmrTransformStarted
4542
- );
4543
- } catch {
4544
- trackGlobalVarSourceFile(ctx.file, fileContent);
4545
- recordFileVarMangleEntries(state, ctx.file, []);
4546
- recordFileCSSVariableMetrics(state, ctx.file, null);
4547
- return;
4548
- }
4549
- if (!result.transformed) {
4550
- trackGlobalVarSourceFile(ctx.file, fileContent);
4551
- recordFileVarMangleEntries(state, ctx.file, []);
4552
- recordFileCSSVariableMetrics(state, ctx.file, null);
4553
- return;
4554
- }
4555
- const sizeBefore = state.classes.size;
4556
- trackGlobalVarSourceFile(ctx.file, fileContent);
4557
- for (const cls of result.classes) {
4558
- addSafelistClass(cls);
4559
- state.ownedClasses.add(cls);
4560
- }
4561
- recordFileVarMangleEntries(state, ctx.file, cssVariableEntries(result));
4562
- recordFileCSSVariableMetrics(state, ctx.file, result.code);
4563
- for (const [token, data] of result.recoveryTokens) {
4564
- state.recoveryTokens.set(token, data);
4565
- }
4566
- if (state.classes.size > sizeBefore) {
4567
- writeSafelistFile(state.classes);
4568
- const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
4569
- ctx.server.watcher.emit("change", safelistPath);
4680
+ if (normalizePathSeparators(ctx.file) === normalizePathSeparators(path.join(state.rootDir, SAFELIST_FILENAME))) {
4681
+ return tailwindEntryModules(ctx.server.moduleGraph);
4570
4682
  }
4683
+ discoverHotFileClasses(ctx.file, ctx.server.watcher);
4684
+ return void 0;
4571
4685
  },
4572
4686
  transformIndexHtml: {
4573
4687
  order: "pre",
@@ -4581,13 +4695,11 @@ ${transformedCode}`;
4581
4695
  finalizeMangleMap();
4582
4696
  const injectedMangleMap = manglingEnabled ? state.mangleMap : {};
4583
4697
  let result = transformIndexHtml(html, injectedMangleMap, state.checksum, {
4584
- // Always 'script'; the checksum itself is injected by
4585
- // injectHydrationData regardless of this mode.
4698
+ // Always 'script' the inert JSON census; the
4699
+ // checksum attribute is injected regardless.
4586
4700
  mode: "script",
4587
4701
  minify: process.env.NODE_ENV === "production",
4588
- varMangleMap: state.varMangleMap,
4589
- globalVarAliasPrefix,
4590
- installRuntimeObject: deliverMapInHtml
4702
+ varMangleMap: state.varMangleMap
4591
4703
  });
4592
4704
  if (manglingEnabled) {
4593
4705
  sizeAccount.channels.add("html");
@@ -4608,6 +4720,18 @@ ${transformedCode}`;
4608
4720
  }
4609
4721
  result = injectRecoveryManifest(result, manifest);
4610
4722
  }
4723
+ if (needsRuntimeMangleRegistration(manglingEnabled, injectedMangleMap)) {
4724
+ return {
4725
+ html: result,
4726
+ tags: [
4727
+ {
4728
+ tag: "script",
4729
+ attrs: { type: "module", src: MANGLE_RUNTIME_VIRTUAL_ID },
4730
+ injectTo: "head-prepend"
4731
+ }
4732
+ ]
4733
+ };
4734
+ }
4611
4735
  return result;
4612
4736
  }
4613
4737
  }
@@ -4959,4 +5083,4 @@ const esbuildPlugin = (options = {}) => {
4959
5083
  };
4960
5084
  };
4961
5085
 
4962
- export { shouldWarnUnscopedMonorepo as $, isHardIgnoredPath as A, isMangleableCssId as B, isMonorepoPackage as C, isPackagesSkippedSource as D, isRSCServerModule as E, isTailwindReservedGlobalVar as F, lateMangleCensusMessage as G, mangleCodeClassesSync as H, mangleEligibleClasses as I, mangleHybridHazardMessage as J, missingTailwindEntryMessage as K, normalizeGlobalVarAliasesForCache as L, planGlobalVarAliases as M, readGlobalVarScanCache as N, realContentHashDisabledMessage as O, recordGlobalVarSourceFile as P, resolveCompileSourceDirs as Q, resolveGlobalVarScanCacheDir as R, resolveNativeCacheIdentity as S, resolveQuietMode as T, rewriteGlobalVarCssAliases as U, rollupPlugin as V, scanGlobalVarCss as W, shouldEmitMissingCssFallback as X, shouldEmitWarning as Y, shouldTrackGlobalVarSources as Z, shouldWarnMissingTailwindEntry as _, allocateMangleTokens as a, skippedSzFilesMessage as a0, suppressedAdvisoryMessage as a1, unscopedMonorepoMessage as a2, validateGlobalVarAliasInputs as a3, vitePlugin as a4, watchModeMangleMessage as a5, webpackPlugin as a6, writeGlobalVarScanCache as a7, appendTailwindSourceDirective as b, assertNoRSCBoundaryViolation as c, assertNoRSCGraphViolation as d, collectMangleHybridHazards as e, computeSafelistRelPath as f, createGlobalVarAliasValidationOptions as g, createGlobalVarMapAssetSource as h, createGlobalVarScanCacheKey as i, createRSCModuleRecord as j, cssHasContentScope as k, cssImportsTailwind as l, deleteRSCModuleRecord as m, emitMissingCssFallback as n, esbuildPlugin as o, extractGlobalVarAliasesForManifest as p, fileMayContainSafelistableSz as q, findLocalImportSources as r, findRSCBoundaryViolation as s, findRSCGraphViolation as t, unplugin as u, hasInjectableTailwindCandidate as v, hasUseClientDirective as w, hasUseServerDirective as x, isAdvisoryDiagnostic as y, isCompileSourceOptedIn as z };
5086
+ export { unscopedMonorepoMessage as $, isPackagesSkippedSource as A, isRSCServerModule as B, isTailwindReservedGlobalVar as C, lateMangleCensusMessage as D, mangleCodeClassesSync as E, mangleEligibleClasses as F, mangleHybridHazardMessage as G, missingTailwindEntryMessage as H, normalizeGlobalVarAliasesForCache as I, planGlobalVarAliases as J, readGlobalVarScanCache as K, realContentHashDisabledMessage as L, recordGlobalVarSourceFile as M, resolveCompileSourceDirs as N, resolveGlobalVarScanCacheDir as O, resolveNativeCacheIdentity as P, resolveQuietMode as Q, rewriteGlobalVarCssAliases as R, rollupPlugin as S, scanGlobalVarCss as T, shouldEmitMissingCssFallback as U, shouldEmitWarning as V, shouldTrackGlobalVarSources as W, shouldWarnMissingTailwindEntry as X, shouldWarnUnscopedMonorepo as Y, skippedSzFilesMessage as Z, suppressedAdvisoryMessage as _, allocateMangleTokens as a, validateGlobalVarAliasInputs as a0, vitePlugin as a1, watchModeMangleMessage as a2, webpackPlugin as a3, writeGlobalVarScanCache as a4, assertNoRSCBoundaryViolation as b, assertNoRSCGraphViolation as c, collectMangleHybridHazards as d, createGlobalVarAliasValidationOptions as e, createGlobalVarMapAssetSource as f, createGlobalVarScanCacheKey as g, createRSCModuleRecord as h, cssHasContentScope as i, deleteRSCModuleRecord as j, emitMissingCssFallback as k, esbuildPlugin as l, extractGlobalVarAliasesForManifest as m, fileMayContainSafelistableSz as n, findLocalImportSources as o, findRSCBoundaryViolation as p, findRSCGraphViolation as q, hasInjectableTailwindCandidate as r, hasUseClientDirective as s, hasUseServerDirective as t, unplugin as u, isAdvisoryDiagnostic as v, isCompileSourceOptedIn as w, isHardIgnoredPath as x, isMangleableCssId as y, isMonorepoPackage as z };