@csszyx/unplugin 0.11.7 → 0.11.9

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 (41) hide show
  1. package/README.md +6 -1
  2. package/dist/css-mangler.cjs +9 -6
  3. package/dist/css-mangler.mjs +9 -6
  4. package/dist/index.cjs +5 -4
  5. package/dist/index.d.cts +2 -2
  6. package/dist/index.d.mts +2 -2
  7. package/dist/index.mjs +4 -4
  8. package/dist/next-config.cjs +1 -1
  9. package/dist/next-config.mjs +1 -1
  10. package/dist/next-prebuild.cjs +5 -5
  11. package/dist/next-prebuild.mjs +5 -5
  12. package/dist/next-turbo-loader.cjs +7 -12
  13. package/dist/next-turbo-loader.mjs +7 -12
  14. package/dist/next-watcher.cjs +2 -2
  15. package/dist/next-watcher.mjs +2 -2
  16. package/dist/shared/{unplugin.Dqt1aLCX.mjs → unplugin.7TELUwsj.mjs} +5 -3
  17. package/dist/shared/unplugin.B3XoSRB8.mjs +40 -0
  18. package/dist/shared/unplugin.BkRah5Ot.cjs +48 -0
  19. package/dist/shared/{unplugin.VSslRpfN.mjs → unplugin.Bqx2WfBV.mjs} +51 -50
  20. package/dist/shared/{unplugin.PhOFTQpB.d.cts → unplugin.CjCKWnoX.d.cts} +25 -6
  21. package/dist/shared/{unplugin.PhOFTQpB.d.mts → unplugin.CjCKWnoX.d.mts} +25 -6
  22. package/dist/shared/{unplugin.CwcOd1q3.mjs → unplugin.D-K57LNR.mjs} +6 -1
  23. package/dist/shared/{unplugin.ByAzFdqO.cjs → unplugin.DUI48s3S.cjs} +1181 -766
  24. package/dist/shared/{unplugin.D8vSG36M.cjs → unplugin.DVCQC5wq.cjs} +6 -0
  25. package/dist/shared/{unplugin.Rov-j_Wm.cjs → unplugin.DmuOKVS4.cjs} +21 -0
  26. package/dist/shared/{unplugin.D6hes1O8.cjs → unplugin.WVn08Fln.cjs} +5 -3
  27. package/dist/shared/{unplugin.CZKUWN1J.cjs → unplugin.jZsBqx54.cjs} +51 -50
  28. package/dist/shared/unplugin.nnsa7OVW.mjs +49 -0
  29. package/dist/shared/{unplugin.CtHwCYxE.mjs → unplugin.wx3cvxxX.mjs} +1180 -766
  30. package/dist/vite.cjs +4 -4
  31. package/dist/vite.d.cts +2 -25
  32. package/dist/vite.d.mts +1 -25
  33. package/dist/vite.mjs +4 -8
  34. package/dist/webpack.cjs +4 -4
  35. package/dist/webpack.d.cts +2 -5
  36. package/dist/webpack.d.mts +1 -5
  37. package/dist/webpack.mjs +4 -8
  38. package/package.json +7 -7
  39. package/dist/shared/unplugin.B1mblcm-.mjs +0 -9
  40. package/dist/shared/unplugin.B3RHYokB.mjs +0 -29
  41. package/dist/shared/unplugin.BCwRIUs_.cjs +0 -12
@@ -6,7 +6,7 @@ import * as path from 'node:path';
6
6
  import { dirname } from 'node:path';
7
7
  import { performance } from 'node:perf_hooks';
8
8
  import { fileURLToPath } from 'node:url';
9
- import { scanGlobalVarUsages, sortStrings as sortStrings$1, ensureRustTransformAvailable, transformSourceCode, transformRust, transformOxc, transformRustBatch, ASTBudgetExceededError, transform, isRustTransformAvailable } from '@csszyx/compiler';
9
+ import { scanGlobalVarUsages, sortStrings as sortStrings$1, ensureRustTransformAvailable, transformSourceCode, transformRust, transformOxc, ASTBudgetExceededError, transformRustBatch, transform, isRustTransformAvailable } from '@csszyx/compiler';
10
10
  import { encode, compute_mangle_checksum } from '@csszyx/core';
11
11
  import { getNativePackageName } from '@csszyx/core/native';
12
12
  import { preprocess as preprocess$1 } from '@csszyx/svelte-adapter';
@@ -14,9 +14,9 @@ import { isTailwindReservedCustomProperty, CSSZYX_GLOBAL_ALIAS_PREFIX, isCsszyxG
14
14
  import { preprocess } from '@csszyx/vue-adapter';
15
15
  import { createUnplugin } from 'unplugin';
16
16
  import { mangleCSSSync } from '../css-mangler.mjs';
17
- import { s as sortStrings, e as escapeHtmlAttribute } from './unplugin.B1mblcm-.mjs';
18
- import { i as importsRuntimeHelper, f as findRuntimeImportClause } from './unplugin.B3RHYokB.mjs';
19
- import { r as resolveTransformCacheDir, c as createTransformCacheKey, a as readTransformCache, w as writeTransformCache, e as evictOldTransformCacheEntries, b as evictMemoryCacheToBudget } from './unplugin.CwcOd1q3.mjs';
17
+ import { i as importsRuntimeHelper, f as findRuntimeImportClause, a as insertAfterUseDirective } from './unplugin.nnsa7OVW.mjs';
18
+ import { n as normalizePathSeparators, r as resolveTransformCacheDir, c as createTransformCacheKey, w as writeTransformCache, e as evictOldTransformCacheEntries, a as readTransformCache, b as evictMemoryCacheToBudget } from './unplugin.D-K57LNR.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';
20
20
  import postcss from 'postcss';
21
21
  import valueParser from 'postcss-value-parser';
22
22
 
@@ -96,7 +96,8 @@ function buildScopeId(node) {
96
96
  }
97
97
  current = current.parent;
98
98
  }
99
- return parts.reverse().join(" > ") || DEFAULT_SCOPE_ID;
99
+ parts.reverse();
100
+ return parts.join(" > ") || DEFAULT_SCOPE_ID;
100
101
  }
101
102
 
102
103
  const VAR_REFERENCE_RE = /var\(\s*(--[\w-]+)/g;
@@ -369,7 +370,7 @@ function rewriteGlobalVarValue(value, aliases) {
369
370
  return;
370
371
  }
371
372
  const firstArgument = node.nodes.find((child) => child.type !== "space");
372
- if (!firstArgument || firstArgument.type !== "word") {
373
+ if (firstArgument?.type !== "word") {
373
374
  return;
374
375
  }
375
376
  const alias = aliases.get(firstArgument.value);
@@ -519,8 +520,8 @@ function createRSCModuleRecord(code, id) {
519
520
  }
520
521
  function deleteRSCModuleRecord(records, id) {
521
522
  const normalized = normalizeModuleId(id);
522
- const clean = id.split("?")[0]?.replace(/\\/g, "/") ?? id;
523
- const resolved = path.resolve(clean).replace(/\\/g, "/");
523
+ const clean = normalizePathSeparators(id.split("?")[0] ?? id);
524
+ const resolved = normalizePathSeparators(path.resolve(clean));
524
525
  pruneRSCModulePathCaches(/* @__PURE__ */ new Set([normalized, resolved, clean]));
525
526
  let deleted = records.delete(normalized);
526
527
  if (resolved !== normalized) {
@@ -566,7 +567,7 @@ const APP_ROUTER_ENTRIES = /* @__PURE__ */ new Set([
566
567
  "route"
567
568
  ]);
568
569
  function isNextAppRouterEntry(id) {
569
- const clean = id.split("?")[0]?.replace(/\\/g, "/") ?? id;
570
+ const clean = normalizePathSeparators(id.split("?")[0] ?? id);
570
571
  if (!clean.includes("/app/") && !clean.startsWith("app/")) return false;
571
572
  const basename = clean.split("/").pop() ?? "";
572
573
  const dotIdx = basename.indexOf(".");
@@ -638,7 +639,7 @@ function findDirectiveStatementEnd(code, start) {
638
639
  }
639
640
  function readDirectivePrologue(code) {
640
641
  const out = [];
641
- let i = code.charCodeAt(0) === 65279 ? 1 : 0;
642
+ let i = readCodePoint(code, 0) === 65279 ? 1 : 0;
642
643
  while (i < code.length) {
643
644
  i = skipWhitespaceAndComments(code, i);
644
645
  const quote = code[i];
@@ -705,55 +706,50 @@ function findStaticImports(code) {
705
706
  let cursor = 0;
706
707
  while (cursor < code.length) {
707
708
  const importStart = code.indexOf("import", cursor);
708
- if (importStart === -1) {
709
- break;
710
- }
711
- cursor = importStart + 6;
712
- if (importStart > 0 && isIdentifierPart(code.charCodeAt(importStart - 1)) || isIdentifierPart(code.charCodeAt(cursor))) {
713
- continue;
714
- }
715
- let position = skipAsciiWhitespace(code, cursor);
716
- const opener = code.charAt(position);
717
- if (opener === "(") {
718
- continue;
719
- }
720
- if (opener === '"' || opener === "'") {
721
- const literal2 = readQuotedString(code, position);
722
- if (literal2) {
723
- imports.push({ clause: null, source: literal2.value });
724
- cursor = literal2.end;
725
- }
726
- continue;
727
- }
728
- const clauseStart = position;
729
- let fromStart = -1;
730
- while (position < code.length) {
731
- if (code.startsWith("from", position) && (position === clauseStart || !isIdentifierPart(code.charCodeAt(position - 1))) && !isIdentifierPart(code.charCodeAt(position + 4))) {
732
- fromStart = position;
733
- break;
734
- }
735
- if (code.charAt(position) === ";") {
736
- break;
737
- }
738
- position += 1;
739
- }
740
- if (fromStart === -1) {
741
- continue;
742
- }
743
- const clause = code.slice(clauseStart, fromStart).trim();
744
- if (splitAsciiWhitespace(clause)[0] === "type") {
745
- cursor = fromStart + 4;
746
- continue;
747
- }
748
- position = skipAsciiWhitespace(code, fromStart + 4);
749
- const literal = readQuotedString(code, position);
750
- if (literal) {
751
- imports.push({ clause, source: literal.value });
752
- cursor = literal.end;
753
- }
709
+ if (importStart === -1) break;
710
+ const result = scanStaticImport(code, importStart);
711
+ cursor = result.nextCursor;
712
+ if (result.value) imports.push(result.value);
754
713
  }
755
714
  return imports;
756
715
  }
716
+ function scanStaticImport(code, importStart) {
717
+ const afterKeyword = importStart + 6;
718
+ if (importStart > 0 && isIdentifierPart(readCodePoint(code, importStart - 1)) || isIdentifierPart(readCodePoint(code, afterKeyword))) {
719
+ return { nextCursor: afterKeyword };
720
+ }
721
+ const clauseStart = skipAsciiWhitespace(code, afterKeyword);
722
+ const opener = code.charAt(clauseStart);
723
+ if (opener === "(") return { nextCursor: afterKeyword };
724
+ if (opener === '"' || opener === "'") {
725
+ return scanSideEffectImport(code, clauseStart, afterKeyword);
726
+ }
727
+ return scanImportClause(code, clauseStart, afterKeyword);
728
+ }
729
+ function scanSideEffectImport(code, literalStart, fallbackCursor) {
730
+ const literal = readQuotedString(code, literalStart);
731
+ return literal ? { nextCursor: literal.end, value: { clause: null, source: literal.value } } : { nextCursor: fallbackCursor };
732
+ }
733
+ function scanImportClause(code, clauseStart, fallbackCursor) {
734
+ const fromStart = findImportFromKeyword(code, clauseStart);
735
+ if (fromStart === -1) return { nextCursor: fallbackCursor };
736
+ const clause = code.slice(clauseStart, fromStart).trim();
737
+ if (splitAsciiWhitespace(clause)[0] === "type") {
738
+ return { nextCursor: fromStart + 4 };
739
+ }
740
+ const literalStart = skipAsciiWhitespace(code, fromStart + 4);
741
+ const literal = readQuotedString(code, literalStart);
742
+ return literal ? { nextCursor: literal.end, value: { clause, source: literal.value } } : { nextCursor: fallbackCursor };
743
+ }
744
+ function findImportFromKeyword(code, clauseStart) {
745
+ for (let position = clauseStart; position < code.length; position += 1) {
746
+ if (code.charAt(position) === ";") return -1;
747
+ if (code.startsWith("from", position) && (position === clauseStart || !isIdentifierPart(readCodePoint(code, position - 1))) && !isIdentifierPart(readCodePoint(code, position + 4))) {
748
+ return position;
749
+ }
750
+ }
751
+ return -1;
752
+ }
757
753
  function readQuotedString(code, start) {
758
754
  const quote = code.charAt(start);
759
755
  if (quote !== '"' && quote !== "'") {
@@ -781,7 +777,7 @@ function readQuotedString(code, start) {
781
777
  function skipAsciiWhitespace(code, start) {
782
778
  let index = start;
783
779
  while (index < code.length) {
784
- const charCode = code.charCodeAt(index);
780
+ const charCode = readCodePoint(code, index);
785
781
  if (charCode !== 9 && charCode !== 10 && charCode !== 13 && charCode !== 32) {
786
782
  break;
787
783
  }
@@ -926,9 +922,9 @@ function normalizeModuleId(id) {
926
922
  }
927
923
  let normalized;
928
924
  try {
929
- normalized = fs.realpathSync.native(clean).replace(/\\/g, "/");
925
+ normalized = normalizePathSeparators(fs.realpathSync.native(clean));
930
926
  } catch {
931
- normalized = path.resolve(clean).replace(/\\/g, "/");
927
+ normalized = normalizePathSeparators(path.resolve(clean));
932
928
  }
933
929
  normalizedModuleIdCache.set(clean, normalized);
934
930
  return normalized;
@@ -974,7 +970,7 @@ function resolveLocalModule(importer, source) {
974
970
  }
975
971
  function pruneRSCModulePathCaches(moduleIds) {
976
972
  for (const [key, value] of normalizedModuleIdCache) {
977
- const normalizedKey = key.replace(/\\/g, "/");
973
+ const normalizedKey = normalizePathSeparators(key);
978
974
  if (moduleIds.has(value) || moduleIds.has(normalizedKey)) {
979
975
  normalizedModuleIdCache.delete(key);
980
976
  }
@@ -1018,11 +1014,11 @@ function readImportedSymbols(clause) {
1018
1014
  return symbols;
1019
1015
  }
1020
1016
  function isIdentifier(value) {
1021
- if (value.length === 0 || !isIdentifierStart(value.charCodeAt(0))) {
1017
+ if (value.length === 0 || !isIdentifierStart(readCodePoint(value, 0))) {
1022
1018
  return false;
1023
1019
  }
1024
1020
  for (let index = 1; index < value.length; index += 1) {
1025
- const code = value.charCodeAt(index);
1021
+ const code = readCodePoint(value, index);
1026
1022
  if (!isIdentifierStart(code) && (code < 48 || code > 57)) {
1027
1023
  return false;
1028
1024
  }
@@ -1032,11 +1028,14 @@ function isIdentifier(value) {
1032
1028
  function isIdentifierStart(code) {
1033
1029
  return code === 36 || code === 95 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
1034
1030
  }
1031
+ function readCodePoint(value, index) {
1032
+ return value.codePointAt(index) ?? -1;
1033
+ }
1035
1034
  function splitAsciiWhitespace(value) {
1036
1035
  const parts = [];
1037
1036
  let start = -1;
1038
1037
  for (let index = 0; index <= value.length; index += 1) {
1039
- const code = index < value.length ? value.charCodeAt(index) : 32;
1038
+ const code = index < value.length ? readCodePoint(value, index) : 32;
1040
1039
  const whitespace = code === 9 || code === 10 || code === 13 || code === 32;
1041
1040
  if (whitespace) {
1042
1041
  if (start !== -1) {
@@ -1059,13 +1058,7 @@ function stripCommentsForImportScan(code) {
1059
1058
  const next = code[i + 1];
1060
1059
  if (quote) {
1061
1060
  out += ch;
1062
- if (escaped) {
1063
- escaped = false;
1064
- } else if (ch === "\\") {
1065
- escaped = true;
1066
- } else if (ch === quote) {
1067
- quote = null;
1068
- }
1061
+ ({ quote, escaped } = advanceQuotedImportScan(ch, quote, escaped));
1069
1062
  i++;
1070
1063
  continue;
1071
1064
  }
@@ -1076,28 +1069,15 @@ function stripCommentsForImportScan(code) {
1076
1069
  continue;
1077
1070
  }
1078
1071
  if (ch === "/" && next === "/") {
1079
- out += " ";
1080
- i += 2;
1081
- while (i < code.length && code[i] !== "\n") {
1082
- out += " ";
1083
- i++;
1084
- }
1072
+ const masked = maskLineComment(code, i);
1073
+ out += masked.value;
1074
+ i = masked.end;
1085
1075
  continue;
1086
1076
  }
1087
1077
  if (ch === "/" && next === "*") {
1088
- out += " ";
1089
- i += 2;
1090
- while (i < code.length) {
1091
- const blockCh = code[i];
1092
- const blockNext = code[i + 1];
1093
- if (blockCh === "*" && blockNext === "/") {
1094
- out += " ";
1095
- i += 2;
1096
- break;
1097
- }
1098
- out += blockCh === "\n" ? "\n" : " ";
1099
- i++;
1100
- }
1078
+ const masked = maskBlockComment(code, i);
1079
+ out += masked.value;
1080
+ i = masked.end;
1101
1081
  continue;
1102
1082
  }
1103
1083
  out += ch;
@@ -1105,6 +1085,31 @@ function stripCommentsForImportScan(code) {
1105
1085
  }
1106
1086
  return out;
1107
1087
  }
1088
+ function advanceQuotedImportScan(character, quote, escaped) {
1089
+ if (escaped) return { quote, escaped: false };
1090
+ if (character === "\\") return { quote, escaped: true };
1091
+ return { quote: character === quote ? null : quote, escaped: false };
1092
+ }
1093
+ function maskLineComment(code, start) {
1094
+ const newline = code.indexOf("\n", start + 2);
1095
+ const end = newline === -1 ? code.length : newline;
1096
+ return { end, value: " ".repeat(end - start) };
1097
+ }
1098
+ function maskBlockComment(code, start) {
1099
+ let end = start + 2;
1100
+ while (end < code.length) {
1101
+ if (code.charAt(end) === "*" && code.charAt(end + 1) === "/") {
1102
+ end += 2;
1103
+ break;
1104
+ }
1105
+ end += 1;
1106
+ }
1107
+ let value = "";
1108
+ for (let index = start; index < end; index += 1) {
1109
+ value += code.charAt(index) === "\n" ? "\n" : " ";
1110
+ }
1111
+ return { end, value };
1112
+ }
1108
1113
 
1109
1114
  const EMPTY_THEME = {
1110
1115
  colors: [],
@@ -1155,15 +1160,44 @@ function stripLayerWrappers(css) {
1155
1160
  }
1156
1161
  return result;
1157
1162
  }
1163
+ function themePreludeStart(css, at) {
1164
+ const cursor = at + "@theme".length;
1165
+ const next = css[cursor];
1166
+ const validBoundary = next === "{" || next === " " || next === " " || next === "\n" || next === "\r";
1167
+ return validBoundary ? cursor : null;
1168
+ }
1169
+ function readThemeBlock(css, start) {
1170
+ for (let cursor = start; cursor < css.length; cursor++) {
1171
+ const character = css[cursor];
1172
+ if (character === "{") {
1173
+ const close = findMatchingBrace(css, cursor);
1174
+ return {
1175
+ body: close === -1 ? null : css.slice(cursor + 1, close),
1176
+ end: close === -1 ? cursor : close
1177
+ };
1178
+ }
1179
+ if (character === ";" || character === "}" || character === "@") {
1180
+ return { body: null, end: cursor };
1181
+ }
1182
+ }
1183
+ return { body: null, end: css.length };
1184
+ }
1158
1185
  function extractThemeBlocks(css) {
1159
1186
  const blocks = [];
1160
- const themeStart = /@theme\s+(?:inline\s+)?\{|@theme\{/g;
1161
- for (const match of css.matchAll(themeStart)) {
1162
- const openPos = css.indexOf("{", match.index);
1163
- const closePos = findMatchingBrace(css, openPos);
1164
- if (closePos !== -1) {
1165
- blocks.push(css.slice(openPos + 1, closePos));
1187
+ let searchFrom = 0;
1188
+ for (; ; ) {
1189
+ const at = css.indexOf("@theme", searchFrom);
1190
+ if (at === -1) {
1191
+ break;
1166
1192
  }
1193
+ const preludeStart = themePreludeStart(css, at);
1194
+ if (preludeStart === null) {
1195
+ searchFrom = at + "@theme".length;
1196
+ continue;
1197
+ }
1198
+ const match = readThemeBlock(css, preludeStart);
1199
+ if (match.body !== null) blocks.push(match.body);
1200
+ searchFrom = Math.max(match.end, at + "@theme".length);
1167
1201
  }
1168
1202
  return blocks;
1169
1203
  }
@@ -1308,13 +1342,382 @@ function scanCustomPropertyNames(block) {
1308
1342
  return names;
1309
1343
  }
1310
1344
 
1345
+ const REGEX_PREFIXES = new Set("([{:,;=!?&|+-*%^~<>/");
1346
+ const REGEX_PREFIX_KEYWORDS = /* @__PURE__ */ new Set([
1347
+ "await",
1348
+ "case",
1349
+ "delete",
1350
+ "do",
1351
+ "else",
1352
+ "in",
1353
+ "instanceof",
1354
+ "of",
1355
+ "return",
1356
+ "throw",
1357
+ "typeof",
1358
+ "void",
1359
+ "yield"
1360
+ ]);
1361
+ const SIMPLE_ESCAPES = {
1362
+ b: "\b",
1363
+ f: "\f",
1364
+ n: "\n",
1365
+ r: "\r",
1366
+ t: " ",
1367
+ v: "\v",
1368
+ "0": "\0"
1369
+ };
1370
+ function decodeBracedUnicodeEscape(value, cursor) {
1371
+ if (value[cursor] !== "u" || value[cursor + 1] !== "{") return null;
1372
+ const close = value.indexOf("}", cursor + 2);
1373
+ const hex = close === -1 ? "" : value.slice(cursor + 2, close);
1374
+ const codePoint = hex && /^[\dA-F]+$/i.test(hex) ? Number.parseInt(hex, 16) : -1;
1375
+ if (codePoint < 0 || codePoint > 1114111) return null;
1376
+ return { value: String.fromCodePoint(codePoint), cursor: close };
1377
+ }
1378
+ function decodeFixedWidthEscape(value, cursor) {
1379
+ const escaped = value[cursor];
1380
+ let width = 0;
1381
+ if (escaped === "x") width = 2;
1382
+ if (escaped === "u") width = 4;
1383
+ const hex = value.slice(cursor + 1, cursor + width + 1);
1384
+ if (width === 0 || !isFixedHex(hex, width)) return null;
1385
+ return {
1386
+ value: String.fromCodePoint(Number.parseInt(hex, 16)),
1387
+ cursor: cursor + width
1388
+ };
1389
+ }
1390
+ function isFixedHex(value, width) {
1391
+ if (value.length !== width) return false;
1392
+ for (const character of value) {
1393
+ if (!"0123456789abcdefABCDEF".includes(character)) return false;
1394
+ }
1395
+ return true;
1396
+ }
1397
+ function decodeEscape(value, cursor) {
1398
+ const escaped = value[cursor];
1399
+ if (SIMPLE_ESCAPES[escaped] !== void 0) {
1400
+ return { value: SIMPLE_ESCAPES[escaped], cursor };
1401
+ }
1402
+ if (escaped === "\r" && value[cursor + 1] === "\n") {
1403
+ return { value: "", cursor: cursor + 1 };
1404
+ }
1405
+ const bracedUnicode = decodeBracedUnicodeEscape(value, cursor);
1406
+ if (bracedUnicode) return bracedUnicode;
1407
+ const fixedWidth = decodeFixedWidthEscape(value, cursor);
1408
+ if (fixedWidth) return fixedWidth;
1409
+ const decoded = escaped === "\n" || escaped === "\r" ? "" : escaped;
1410
+ return { value: decoded, cursor };
1411
+ }
1412
+ function decodeJavaScriptString(value) {
1413
+ let output = "";
1414
+ let cursor = 0;
1415
+ while (cursor < value.length) {
1416
+ if (value[cursor] !== "\\" || cursor + 1 >= value.length) {
1417
+ output += value[cursor++];
1418
+ continue;
1419
+ }
1420
+ const decoded = decodeEscape(value, cursor + 1);
1421
+ output += decoded.value;
1422
+ cursor = decoded.cursor + 1;
1423
+ }
1424
+ return output;
1425
+ }
1426
+ function decodeAttributeWhitespace(value) {
1427
+ return value.replace(
1428
+ /&#(?:(\d+)|x([\da-f]+));|&(?:Tab|NewLine);/gi,
1429
+ (entity, decimal, hexadecimal) => {
1430
+ if (!decimal && !hexadecimal) return " ";
1431
+ const codePoint = Number.parseInt(decimal ?? hexadecimal ?? "", decimal ? 10 : 16);
1432
+ return [9, 10, 12, 13, 32].includes(codePoint) ? " " : entity;
1433
+ }
1434
+ );
1435
+ }
1436
+ function collectClassTokens(target, value) {
1437
+ for (const className of value.split(/\s+/)) {
1438
+ if (className) target.add(className);
1439
+ }
1440
+ }
1441
+ function quotedEnd(source, start, quote) {
1442
+ let cursor = start + 1;
1443
+ while (cursor < source.length) {
1444
+ if (source[cursor] === "\\") cursor += 2;
1445
+ else if (source[cursor++] === quote) break;
1446
+ }
1447
+ return cursor;
1448
+ }
1449
+ function commentEnd(source, start) {
1450
+ if (source[start + 1] === "/") {
1451
+ const end2 = source.indexOf("\n", start + 2);
1452
+ return end2 === -1 ? source.length : end2 + 1;
1453
+ }
1454
+ const end = source.indexOf("*/", start + 2);
1455
+ return end === -1 ? source.length : end + 2;
1456
+ }
1457
+ function isRegexStart(source, start) {
1458
+ let cursor = start - 1;
1459
+ while (cursor >= 0 && /\s/.test(source[cursor])) cursor--;
1460
+ if (source[cursor] === "<" && /[A-Z]/i.test(source[start + 1] ?? "")) return false;
1461
+ if (cursor < 0 || REGEX_PREFIXES.has(source[cursor])) return true;
1462
+ if (!/[\w$]/.test(source[cursor])) return false;
1463
+ const end = cursor + 1;
1464
+ while (cursor >= 0 && /[\w$]/.test(source[cursor])) cursor--;
1465
+ return REGEX_PREFIX_KEYWORDS.has(source.slice(cursor + 1, end));
1466
+ }
1467
+ function regexEnd(source, start) {
1468
+ let cursor = start + 1;
1469
+ let inCharacterClass = false;
1470
+ while (cursor < source.length) {
1471
+ const character = source[cursor];
1472
+ if (character === "\\") cursor += 2;
1473
+ else if (character === "[") {
1474
+ inCharacterClass = true;
1475
+ cursor++;
1476
+ } else if (character === "]") {
1477
+ inCharacterClass = false;
1478
+ cursor++;
1479
+ } else if (character === "/" && !inCharacterClass) {
1480
+ cursor++;
1481
+ while (/[A-Z]/i.test(source[cursor] ?? "")) cursor++;
1482
+ break;
1483
+ } else cursor++;
1484
+ }
1485
+ return cursor;
1486
+ }
1487
+ function templateEnd(source, start) {
1488
+ let cursor = start + 1;
1489
+ while (cursor < source.length) {
1490
+ if (source[cursor] === "\\") cursor += 2;
1491
+ else if (source[cursor] === "`") return cursor + 1;
1492
+ else if (source[cursor] === "$" && source[cursor + 1] === "{") {
1493
+ cursor = findBalancedCodeEnd(source, cursor + 2);
1494
+ } else cursor++;
1495
+ }
1496
+ return source.length;
1497
+ }
1498
+ function lexicalRegionEnd(source, start) {
1499
+ const character = source[start];
1500
+ if (character === '"' || character === "'") return quotedEnd(source, start, character);
1501
+ if (character === "`") return templateEnd(source, start);
1502
+ if (character === "/" && (source[start + 1] === "/" || source[start + 1] === "*")) {
1503
+ return commentEnd(source, start);
1504
+ }
1505
+ if (character === "/" && isRegexStart(source, start)) return regexEnd(source, start);
1506
+ return start;
1507
+ }
1508
+ function findBalancedCodeEnd(source, bodyStart) {
1509
+ let depth = 1;
1510
+ let cursor = bodyStart;
1511
+ while (cursor < source.length) {
1512
+ const regionEnd = lexicalRegionEnd(source, cursor);
1513
+ if (regionEnd !== cursor) {
1514
+ cursor = regionEnd;
1515
+ continue;
1516
+ }
1517
+ if (source[cursor] === "{") depth++;
1518
+ else if (source[cursor] === "}" && --depth === 0) return cursor;
1519
+ cursor++;
1520
+ }
1521
+ return source.length;
1522
+ }
1523
+ function collectTemplateTokens(target, source, start) {
1524
+ let cursor = start + 1;
1525
+ let quasiStart = cursor;
1526
+ while (cursor < source.length) {
1527
+ if (source[cursor] === "\\") {
1528
+ cursor += 2;
1529
+ continue;
1530
+ }
1531
+ if (source[cursor] === "`") {
1532
+ collectClassTokens(target, decodeJavaScriptString(source.slice(quasiStart, cursor)));
1533
+ return cursor + 1;
1534
+ }
1535
+ if (source[cursor] === "$" && source[cursor + 1] === "{") {
1536
+ collectClassTokens(target, decodeJavaScriptString(source.slice(quasiStart, cursor)));
1537
+ const expressionEnd = findBalancedCodeEnd(source, cursor + 2);
1538
+ collectExpressionTokens(target, source.slice(cursor + 2, expressionEnd));
1539
+ cursor = expressionEnd + 1;
1540
+ quasiStart = cursor;
1541
+ continue;
1542
+ }
1543
+ cursor++;
1544
+ }
1545
+ collectClassTokens(target, decodeJavaScriptString(source.slice(quasiStart)));
1546
+ return source.length;
1547
+ }
1548
+ function collectExpressionTokens(target, expression) {
1549
+ let cursor = 0;
1550
+ let pendingLiteral = "";
1551
+ let previousLiteralEnd = -1;
1552
+ const flushPending = () => {
1553
+ if (pendingLiteral) collectClassTokens(target, pendingLiteral);
1554
+ pendingLiteral = "";
1555
+ };
1556
+ while (cursor < expression.length) {
1557
+ const character = expression[cursor];
1558
+ if (character === "/" && (expression[cursor + 1] === "/" || expression[cursor + 1] === "*")) {
1559
+ cursor = commentEnd(expression, cursor);
1560
+ continue;
1561
+ }
1562
+ if (character === "/" && isRegexStart(expression, cursor)) {
1563
+ cursor = regexEnd(expression, cursor);
1564
+ continue;
1565
+ }
1566
+ if (character === "`") {
1567
+ flushPending();
1568
+ cursor = collectTemplateTokens(target, expression, cursor);
1569
+ previousLiteralEnd = -1;
1570
+ continue;
1571
+ }
1572
+ if (character !== '"' && character !== "'") {
1573
+ cursor++;
1574
+ continue;
1575
+ }
1576
+ const end = quotedEnd(expression, cursor, character);
1577
+ const decoded = decodeJavaScriptString(expression.slice(cursor + 1, end - 1));
1578
+ const joinsPrevious = previousLiteralEnd >= 0 && expression.slice(previousLiteralEnd, cursor).trim() === "+";
1579
+ if (!joinsPrevious) flushPending();
1580
+ pendingLiteral += decoded;
1581
+ previousLiteralEnd = end;
1582
+ cursor = end;
1583
+ }
1584
+ flushPending();
1585
+ }
1586
+ function triviaEnd(source, start) {
1587
+ let cursor = start;
1588
+ while (cursor < source.length) {
1589
+ if (/\s/.test(source[cursor])) cursor++;
1590
+ else if (source[cursor] === "/" && (source[cursor + 1] === "/" || source[cursor + 1] === "*")) {
1591
+ cursor = commentEnd(source, cursor);
1592
+ } else break;
1593
+ }
1594
+ return cursor;
1595
+ }
1596
+ function propertyExpressionEnd(source, start) {
1597
+ let cursor = start;
1598
+ let parenDepth = 0;
1599
+ let bracketDepth = 0;
1600
+ let braceDepth = 0;
1601
+ while (cursor < source.length) {
1602
+ const regionEnd = lexicalRegionEnd(source, cursor);
1603
+ if (regionEnd !== cursor) {
1604
+ cursor = regionEnd;
1605
+ continue;
1606
+ }
1607
+ const character = source[cursor];
1608
+ if (character === "(") parenDepth++;
1609
+ else if (character === ")") parenDepth--;
1610
+ else if (character === "[") bracketDepth++;
1611
+ else if (character === "]") bracketDepth--;
1612
+ else if (character === "{") braceDepth++;
1613
+ else if (character === "}" && braceDepth > 0) braceDepth--;
1614
+ else if ((character === "," || character === ";" || character === "}") && parenDepth === 0 && bracketDepth === 0 && braceDepth === 0)
1615
+ return cursor;
1616
+ cursor++;
1617
+ }
1618
+ return source.length;
1619
+ }
1620
+ function isClassSink(source, start, end) {
1621
+ const name = source.slice(start, end);
1622
+ if (name !== "class" && name !== "className") return false;
1623
+ let previous = start - 1;
1624
+ while (previous >= 0 && /\s/.test(source[previous])) previous--;
1625
+ return source[previous] !== "." && source[previous] !== "-";
1626
+ }
1627
+ function collectClassDirective(target, source, sinkStart, valueStart) {
1628
+ if (!/[\w$-]/.test(source[valueStart] ?? "")) return null;
1629
+ let directiveEnd = valueStart;
1630
+ while (/[\w$-]/.test(source[directiveEnd] ?? "")) directiveEnd++;
1631
+ const equals = triviaEnd(source, directiveEnd);
1632
+ if (source[equals] !== "=") {
1633
+ const insideMarkupTag = source.lastIndexOf("<", sinkStart) > source.lastIndexOf(">", sinkStart);
1634
+ const next = source[equals] ?? "";
1635
+ const continuesMarkupTag = next === "/" || next === ">" || next === "{" || /[A-Z_:]/i.test(next);
1636
+ if (!insideMarkupTag || !continuesMarkupTag) return null;
1637
+ collectClassTokens(target, source.slice(valueStart, directiveEnd));
1638
+ return directiveEnd;
1639
+ }
1640
+ const directive = source.slice(valueStart, directiveEnd);
1641
+ const directiveValueStart = triviaEnd(source, equals + 1);
1642
+ const directiveQuote = source[directiveValueStart];
1643
+ if (directive !== "list") collectClassTokens(target, directive);
1644
+ if (directiveQuote === "{") {
1645
+ const end = findBalancedCodeEnd(source, directiveValueStart + 1);
1646
+ if (directive === "list") {
1647
+ collectExpressionTokens(target, source.slice(directiveValueStart + 1, end));
1648
+ }
1649
+ return end + 1;
1650
+ }
1651
+ if (directive === "list" && (directiveQuote === '"' || directiveQuote === "'")) {
1652
+ const end = quotedEnd(source, directiveValueStart, directiveQuote);
1653
+ collectExpressionTokens(target, source.slice(directiveValueStart, end));
1654
+ return end;
1655
+ }
1656
+ return directiveValueStart;
1657
+ }
1658
+ function collectClassSink(target, source, start, nameEnd) {
1659
+ const operatorStart = triviaEnd(source, nameEnd);
1660
+ const operator = source[operatorStart];
1661
+ if (operator !== "=" && operator !== ":") return nameEnd;
1662
+ const valueStart = triviaEnd(source, operatorStart + 1);
1663
+ const quote = source[valueStart];
1664
+ const vueBinding = operator === "=" && source.slice(Math.max(0, start - 1), start) === ":";
1665
+ if (operator === ":" && valueStart === operatorStart + 1) {
1666
+ const directiveEnd = collectClassDirective(target, source, start, valueStart);
1667
+ if (directiveEnd !== null) return directiveEnd;
1668
+ }
1669
+ if (quote === '"' || quote === "'") {
1670
+ const end = quotedEnd(source, valueStart, quote);
1671
+ const value = source.slice(valueStart + 1, end - 1);
1672
+ if (vueBinding) collectExpressionTokens(target, decodeAttributeWhitespace(value));
1673
+ else collectClassTokens(target, decodeAttributeWhitespace(value));
1674
+ return end;
1675
+ }
1676
+ if (operator === "=" && quote === "{") {
1677
+ const end = findBalancedCodeEnd(source, valueStart + 1);
1678
+ collectExpressionTokens(target, source.slice(valueStart + 1, end));
1679
+ return end + 1;
1680
+ }
1681
+ if (operator === ":") {
1682
+ const end = propertyExpressionEnd(source, valueStart);
1683
+ collectExpressionTokens(target, source.slice(valueStart, end));
1684
+ return end;
1685
+ }
1686
+ return valueStart;
1687
+ }
1688
+ function collectAuthoredClassNames(source) {
1689
+ const classes = /* @__PURE__ */ new Set();
1690
+ let cursor = 0;
1691
+ while (cursor < source.length) {
1692
+ if (source[cursor] === '"' || source[cursor] === "'") {
1693
+ const keyEnd = quotedEnd(source, cursor, source[cursor]);
1694
+ const key = decodeJavaScriptString(source.slice(cursor + 1, keyEnd - 1));
1695
+ cursor = key === "class" || key === "className" ? collectClassSink(classes, source, cursor, keyEnd) : keyEnd;
1696
+ continue;
1697
+ }
1698
+ const regionEnd = lexicalRegionEnd(source, cursor);
1699
+ if (regionEnd !== cursor) {
1700
+ cursor = regionEnd;
1701
+ continue;
1702
+ }
1703
+ if (!/[A-Z_$]/i.test(source[cursor])) {
1704
+ cursor++;
1705
+ continue;
1706
+ }
1707
+ let nameEnd = cursor + 1;
1708
+ while (/[\w$]/.test(source[nameEnd] ?? "")) nameEnd++;
1709
+ cursor = isClassSink(source, cursor, nameEnd) ? collectClassSink(classes, source, cursor, nameEnd) : nameEnd;
1710
+ }
1711
+ return classes;
1712
+ }
1713
+
1311
1714
  const GLOB_MAGIC_RE = /[*?[\]{}]/;
1312
1715
  const DEFAULT_IGNORED_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".next", ".turbo", "dist", "build"]);
1313
1716
  function normalizeFileId(id) {
1314
- return id.split(/[?#]/, 1)[0].replace(/\\/g, "/");
1717
+ return normalizePathSeparators(id.split(/[?#]/, 1)[0]);
1315
1718
  }
1316
1719
  function normalizeRoot(rootDir) {
1317
- return path.resolve(rootDir).replace(/\\/g, "/");
1720
+ return normalizePathSeparators(path.resolve(rootDir));
1318
1721
  }
1319
1722
  function hasGlobMagic(pattern) {
1320
1723
  return GLOB_MAGIC_RE.test(pattern);
@@ -1323,7 +1726,7 @@ function escapeRegExp(ch) {
1323
1726
  return /[|\\{}()[\]^$+?.]/.test(ch) ? `\\${ch}` : ch;
1324
1727
  }
1325
1728
  function globToRegExp(pattern) {
1326
- const normalized = pattern.replace(/\\/g, "/");
1729
+ const normalized = normalizePathSeparators(pattern);
1327
1730
  let out = "^";
1328
1731
  for (let i = 0; i < normalized.length; i++) {
1329
1732
  const ch = normalized[i];
@@ -1346,7 +1749,7 @@ function globToRegExp(pattern) {
1346
1749
  function relativeToRoot(file, rootDir) {
1347
1750
  const root = normalizeRoot(rootDir);
1348
1751
  const normalizedFile = normalizeFileId(file);
1349
- return path.posix.relative(root, normalizedFile).replace(/\\/g, "/");
1752
+ return normalizePathSeparators(path.posix.relative(root, normalizedFile));
1350
1753
  }
1351
1754
  function matchesPattern(id, pattern, rootDir) {
1352
1755
  const file = normalizeFileId(id);
@@ -1355,7 +1758,7 @@ function matchesPattern(id, pattern, rootDir) {
1355
1758
  pattern.lastIndex = 0;
1356
1759
  return pattern.test(file) || pattern.test(relative);
1357
1760
  }
1358
- const normalizedPattern = pattern.replace(/\\/g, "/");
1761
+ const normalizedPattern = normalizePathSeparators(pattern);
1359
1762
  if (hasGlobMagic(normalizedPattern)) {
1360
1763
  const re = globToRegExp(normalizedPattern);
1361
1764
  return re.test(file) || re.test(relative);
@@ -1422,9 +1825,15 @@ function expandFilePatterns(rootDir, patterns) {
1422
1825
  return sortStrings(files);
1423
1826
  }
1424
1827
 
1828
+ const LINE_SEPARATOR$1 = String.fromCodePoint(8232);
1829
+ const PARAGRAPH_SEPARATOR$1 = String.fromCodePoint(8233);
1425
1830
  function safeJsonForScriptTag(value, prettyPrint = false) {
1426
1831
  const json = prettyPrint ? JSON.stringify(value, null, 2) : JSON.stringify(value);
1427
- return json.replace(/</g, "\\u003C").replace(/>/g, "\\u003E").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1832
+ let escaped = replaceEveryLiteral(json, "<", unicodeEscape("003C"));
1833
+ escaped = replaceEveryLiteral(escaped, ">", unicodeEscape("003E"));
1834
+ escaped = replaceEveryLiteral(escaped, "&", unicodeEscape("0026"));
1835
+ escaped = replaceEveryLiteral(escaped, LINE_SEPARATOR$1, unicodeEscape("2028"));
1836
+ return replaceEveryLiteral(escaped, PARAGRAPH_SEPARATOR$1, unicodeEscape("2029"));
1428
1837
  }
1429
1838
  function injectHtmlOpeningAttr(html, attr) {
1430
1839
  const lower = html.toLowerCase();
@@ -1556,11 +1965,17 @@ function injectRecoveryManifest(html, manifest) {
1556
1965
  return html + scriptTag;
1557
1966
  }
1558
1967
 
1968
+ const LINE_SEPARATOR = String.fromCodePoint(8232);
1969
+ const PARAGRAPH_SEPARATOR = String.fromCodePoint(8233);
1559
1970
  function escapeJsonForInlineScript(json) {
1560
- return json.replace(/`/g, "\\u0060").replace(/\$/g, "\\u0024").replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1971
+ let escaped = replaceEveryLiteral(json, "`", unicodeEscape("0060"));
1972
+ escaped = replaceEveryLiteral(escaped, "$", unicodeEscape("0024"));
1973
+ escaped = replaceEveryLiteral(escaped, "<", unicodeEscape("003c"));
1974
+ escaped = replaceEveryLiteral(escaped, LINE_SEPARATOR, unicodeEscape("2028"));
1975
+ return replaceEveryLiteral(escaped, PARAGRAPH_SEPARATOR, unicodeEscape("2029"));
1561
1976
  }
1562
1977
  function escapeForDoubleQuotedString(value) {
1563
- return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1978
+ return escapeDoubleQuotedString(value);
1564
1979
  }
1565
1980
 
1566
1981
  function isParserMode(value) {
@@ -1607,15 +2022,13 @@ function isSameFileVersion(before, after) {
1607
2022
  return before.dev === after.dev && before.ino === after.ino && before.size === after.size && before.mtimeNs === after.mtimeNs && before.ctimeNs === after.ctimeNs;
1608
2023
  }
1609
2024
 
1610
- function escapeTsString(value) {
1611
- return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
1612
- }
1613
2025
  function generateThemeDts(opts) {
1614
2026
  const { theme, sourceFiles } = opts;
1615
2027
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1616
- const sources = sourceFiles.join(", ").replace(/[\r\n]/g, " ");
1617
- const toUnion = (tokens) => tokens.map((t) => `'${escapeTsString(t)}'`).join(" | ");
1618
- const quoteKey = (key) => /^[a-z_$][\w$]*$/i.test(key) ? key : `'${escapeTsString(key)}'`;
2028
+ const withoutCarriageReturns = replaceEveryLiteral(sourceFiles.join(", "), "\r", " ");
2029
+ const sources = replaceEveryLiteral(withoutCarriageReturns, "\n", " ");
2030
+ const toUnion = (tokens) => tokens.map((t) => `'${escapeSingleQuotedString(t)}'`).join(" | ");
2031
+ const quoteKey = (key) => /^[a-z_$][\w$]*$/i.test(key) ? key : `'${escapeSingleQuotedString(key)}'`;
1619
2032
  const entries = [];
1620
2033
  if (theme.colors.length > 0) {
1621
2034
  entries.push(` colors: ${toUnion(theme.colors)};`);
@@ -1753,6 +2166,15 @@ function createThemeGroupsModule(tokens) {
1753
2166
  ].join("\n");
1754
2167
  }
1755
2168
 
2169
+ function registerWebpackAssetProcessor(compiler, processAssets) {
2170
+ compiler.hooks.compilation.tap("csszyx:post", (compilation) => {
2171
+ const stage = compiler.webpack?.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE || compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE;
2172
+ compilation.hooks.processAssets.tap(
2173
+ { name: "csszyx:post", stage: stage || 400 },
2174
+ (assets) => processAssets(assets, compilation, compiler)
2175
+ );
2176
+ });
2177
+ }
1756
2178
  const CHECKSUM_PLACEHOLDER = "___CSSZYX_CHECKSUM___";
1757
2179
  const MANGLE_MAP_PLACEHOLDER = "___CSSZYX_MANGLE_MAP___";
1758
2180
  const VAR_MANGLE_MAP_PLACEHOLDER = "___CSSZYX_VAR_MANGLE_MAP___";
@@ -1764,7 +2186,6 @@ const TRANSFORM_MEMORY_CACHE_MAX_CODE_CHARS = 32e6;
1764
2186
  const MAX_SAFELIST_CLASSES = 1e5;
1765
2187
  const DEFAULT_VAR_MANGLE_MAP_MAX_BYTES = 100 * 1024;
1766
2188
  const GLOBAL_VAR_ALIAS_MAP_OWNER = "\0csszyx:global-var-aliases";
1767
- const DIRECTIVE_PROLOGUE_PREFIX_RE = /^((?:\s|\/\/[^\n]*\n|\/\*(?:[^*]|\*(?!\/))*\*\/)*)(['"]use (?:client|server)['"];?\s*)/;
1768
2189
  function findOpeningTag(source, tag) {
1769
2190
  const lower = source.toLowerCase();
1770
2191
  const marker = `<${tag}`;
@@ -1837,10 +2258,10 @@ function stripCssBlockComments(code) {
1837
2258
  let i = 0;
1838
2259
  const n = code.length;
1839
2260
  while (i < n) {
1840
- if (code.charCodeAt(i) === SLASH && code.charCodeAt(i + 1) === STAR) {
2261
+ if (code.codePointAt(i) === SLASH && code.codePointAt(i + 1) === STAR) {
1841
2262
  out += code.slice(last, i);
1842
2263
  i += 2;
1843
- while (i < n && !(code.charCodeAt(i) === STAR && code.charCodeAt(i + 1) === SLASH)) {
2264
+ while (i < n && !(code.codePointAt(i) === STAR && code.codePointAt(i + 1) === SLASH)) {
1844
2265
  i++;
1845
2266
  }
1846
2267
  i += 2;
@@ -1946,9 +2367,17 @@ function shouldEmitWarning(quiet, devOnly, isProduction) {
1946
2367
  return true;
1947
2368
  }
1948
2369
  function normalizeForMatch(p) {
1949
- const n = p.replace(/\\/g, "/");
2370
+ const n = normalizePathSeparators(p);
1950
2371
  return n.length > 1 && n.endsWith("/") ? n.slice(0, -1) : n;
1951
2372
  }
2373
+ function findJsxExpressionEnd(code, bodyStart) {
2374
+ return findBalancedCodeEnd(code, bodyStart);
2375
+ }
2376
+ function warnPrescanBudgetSkip(filePath) {
2377
+ console.warn(
2378
+ `[csszyx] prescan skipped ${filePath}: the file exceeds the AST node budget, so NONE of its classes reached the safelist and their CSS will not be generated. Raise \`build.astBudgetLimit\` in the csszyx plugin options, or split the file.`
2379
+ );
2380
+ }
1952
2381
  function resolveCompileSourceDirs(root, sources, realpathDir = (p) => {
1953
2382
  try {
1954
2383
  const real = fs.realpathSync(p);
@@ -2001,6 +2430,9 @@ function fileMayContainSafelistableSz(content) {
2001
2430
  // engine-parity harness caught its classes missing on all engines.
2002
2431
  content.includes("dynamic(");
2003
2432
  }
2433
+ function mangleEligibleClasses(ownedClasses, authoredClasses) {
2434
+ return sortStrings$1([...ownedClasses].filter((className) => !authoredClasses.has(className)));
2435
+ }
2004
2436
  function isPackagesSkippedSource(id, sourceDirs = []) {
2005
2437
  const p = normalizeForMatch(id);
2006
2438
  if (p.includes("node_modules")) {
@@ -2021,8 +2453,8 @@ ${list}
2021
2453
  Add the package directory to \`compileSources\` (or move the file out of packages/) \u2014 otherwise their \`sz\` produces no CSS.`;
2022
2454
  }
2023
2455
  function computeSafelistRelPath(rootDir, safelistFilename, cssId) {
2024
- const safelistPath = path.join(rootDir, safelistFilename).replace(/\\/g, "/");
2025
- const cssDir = path.dirname(cssId).replace(/\\/g, "/");
2456
+ const safelistPath = normalizePathSeparators(path.join(rootDir, safelistFilename));
2457
+ const cssDir = normalizePathSeparators(path.dirname(cssId));
2026
2458
  let relPath = path.posix.relative(cssDir, safelistPath);
2027
2459
  if (!relPath.startsWith(".")) {
2028
2460
  relPath = `./${relPath}`;
@@ -2196,7 +2628,10 @@ function normalizeGlobalVarAliasesForCache(aliases) {
2196
2628
  if (!aliases) {
2197
2629
  return [];
2198
2630
  }
2199
- const entries = aliases instanceof Map ? aliases.entries() : Array.isArray(aliases) ? aliases : Object.entries(aliases);
2631
+ let entries;
2632
+ if (aliases instanceof Map) entries = aliases.entries();
2633
+ else if (Array.isArray(aliases)) entries = aliases;
2634
+ else entries = Object.entries(aliases);
2200
2635
  const normalized = /* @__PURE__ */ new Map();
2201
2636
  for (const [original, alias] of entries) {
2202
2637
  if (original.startsWith("--") && alias.startsWith("--")) {
@@ -2401,7 +2836,7 @@ function findPackageVersionFromFile(file, fallback) {
2401
2836
  }
2402
2837
  }
2403
2838
  function normalizeSourceFilename(filename) {
2404
- return filename.replace(/\\/g, "/");
2839
+ return normalizePathSeparators(filename);
2405
2840
  }
2406
2841
  const SCRIPT_ID_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
2407
2842
  const SOURCE_MODULE_EXTENSIONS = [...SCRIPT_ID_EXTENSIONS, ".cts", ".mts", ".cjs", ".mjs"];
@@ -2409,11 +2844,26 @@ function matchesScriptExtension(id, extensions) {
2409
2844
  return extensions.some((ext) => id.endsWith(ext) || id.includes(`${ext}?`));
2410
2845
  }
2411
2846
  function insertRuntimeImport(code, importStmt) {
2412
- const directiveMatch = code.match(DIRECTIVE_PROLOGUE_PREFIX_RE);
2413
- if (!directiveMatch) {
2414
- return `${importStmt}${code}`;
2847
+ return insertAfterUseDirective(code, importStmt);
2848
+ }
2849
+ function scanClassExpression(source, from) {
2850
+ let depth = 0;
2851
+ let index = from;
2852
+ while (index < source.length) {
2853
+ const char = source[index];
2854
+ if (char === "(" || char === "[") {
2855
+ depth++;
2856
+ } else if (char === ")" || char === "]") {
2857
+ if (depth === 0) {
2858
+ break;
2859
+ }
2860
+ depth--;
2861
+ } else if (depth === 0 && (char === "," || char === ";" || char === "\n" || char === "}")) {
2862
+ break;
2863
+ }
2864
+ index++;
2415
2865
  }
2416
- return code.replace(directiveMatch[0], `${directiveMatch[1]}${directiveMatch[2]}${importStmt}`);
2866
+ return index;
2417
2867
  }
2418
2868
  function mangleCodeClassesSync(code, mangleMap) {
2419
2869
  function mangleClassString(classString) {
@@ -2421,6 +2871,58 @@ function mangleCodeClassesSync(code, mangleMap) {
2421
2871
  return mangleMap[cls.replace(/\\(.)/g, "$1")] || cls;
2422
2872
  }).join(" ");
2423
2873
  }
2874
+ function mangleClassTemplate(fullMatch, templateContent) {
2875
+ let changed = false;
2876
+ let output = "";
2877
+ let cursor = 0;
2878
+ while (cursor < templateContent.length) {
2879
+ const interpolationStart = templateContent.indexOf("${", cursor);
2880
+ const quasiEnd = interpolationStart === -1 ? templateContent.length : interpolationStart;
2881
+ const quasi = mangleTemplateQuasi(templateContent.slice(cursor, quasiEnd));
2882
+ output += quasi.value;
2883
+ changed ||= quasi.changed;
2884
+ if (interpolationStart === -1) break;
2885
+ const interpolationEnd = findTemplateInterpolationEnd(
2886
+ templateContent,
2887
+ interpolationStart + 2
2888
+ );
2889
+ const inner = templateContent.slice(interpolationStart + 2, interpolationEnd - 1);
2890
+ const interpolation = mangleTemplateInterpolation(inner);
2891
+ output += `\${${interpolation.value}}`;
2892
+ changed ||= interpolation.changed;
2893
+ cursor = interpolationEnd;
2894
+ }
2895
+ return changed ? `className:\`${output}\`` : fullMatch;
2896
+ }
2897
+ function mangleTemplateQuasi(quasi) {
2898
+ const trimmed = quasi.trim();
2899
+ if (!trimmed) return { value: quasi, changed: false };
2900
+ const mangled = mangleClassString(trimmed);
2901
+ return {
2902
+ value: mangled === trimmed ? quasi : quasi.replace(trimmed, mangled),
2903
+ changed: mangled !== trimmed
2904
+ };
2905
+ }
2906
+ function findTemplateInterpolationEnd(templateContent, bodyStart) {
2907
+ let depth = 0;
2908
+ for (let cursor = bodyStart; cursor < templateContent.length; cursor++) {
2909
+ if (templateContent[cursor] === "{") depth++;
2910
+ else if (templateContent[cursor] === "}" && depth-- === 0) return cursor + 1;
2911
+ }
2912
+ return templateContent.length;
2913
+ }
2914
+ function mangleTemplateInterpolation(inner) {
2915
+ let changed = false;
2916
+ const value = inner.replace(/"([^"]*)"/g, (quoted, classString) => {
2917
+ const parts = classString.split(/\s+/).filter(Boolean);
2918
+ if (parts.length === 0) return quoted;
2919
+ const mangled = parts.map((className) => mangleMap[className] || className).join(" ");
2920
+ if (mangled === classString) return quoted;
2921
+ changed = true;
2922
+ return `"${mangled}"`;
2923
+ });
2924
+ return { value, changed };
2925
+ }
2424
2926
  let result = code.replace(/(?:class(?:Name)?|sz)[:=]\s*"((?:[^"\\]|\\.)*)"/g, (match, classes) => {
2425
2927
  const mangled = mangleClassString(classes);
2426
2928
  if (mangled === classes) {
@@ -2434,92 +2936,7 @@ function mangleCodeClassesSync(code, mangleMap) {
2434
2936
  }
2435
2937
  return match.replace(classes, mangled);
2436
2938
  });
2437
- result = result.replace(/className:\s*`([^`]+)`/g, (fullMatch, tplContent) => {
2438
- let changed = false;
2439
- let out = "";
2440
- let i = 0;
2441
- while (i < tplContent.length) {
2442
- const interStart = tplContent.indexOf("${", i);
2443
- if (interStart === -1) {
2444
- const quasi2 = tplContent.slice(i);
2445
- const trimmed2 = quasi2.trim();
2446
- if (trimmed2) {
2447
- const m = mangleClassString(trimmed2);
2448
- if (m !== trimmed2) {
2449
- changed = true;
2450
- out += quasi2.replace(trimmed2, m);
2451
- } else {
2452
- out += quasi2;
2453
- }
2454
- } else {
2455
- out += quasi2;
2456
- }
2457
- break;
2458
- }
2459
- const quasi = tplContent.slice(i, interStart);
2460
- const trimmed = quasi.trim();
2461
- if (trimmed) {
2462
- const m = mangleClassString(trimmed);
2463
- if (m !== trimmed) {
2464
- changed = true;
2465
- out += quasi.replace(trimmed, m);
2466
- } else {
2467
- out += quasi;
2468
- }
2469
- } else {
2470
- out += quasi;
2471
- }
2472
- let j = interStart + 2;
2473
- let depth = 0;
2474
- while (j < tplContent.length) {
2475
- if (tplContent[j] === "{") {
2476
- depth++;
2477
- } else if (tplContent[j] === "}") {
2478
- if (depth === 0) {
2479
- j++;
2480
- break;
2481
- }
2482
- depth--;
2483
- }
2484
- j++;
2485
- }
2486
- const interInner = tplContent.slice(interStart + 2, j - 1);
2487
- const mangledInner = interInner.replace(/"([^"]*)"/g, (qm, inner) => {
2488
- const parts = inner.split(/\s+/).filter(Boolean);
2489
- if (parts.length === 0) {
2490
- return qm;
2491
- }
2492
- const m = parts.map((p) => mangleMap[p] || p).join(" ");
2493
- if (m === inner) {
2494
- return qm;
2495
- }
2496
- changed = true;
2497
- return `"${m}"`;
2498
- });
2499
- out += `\${${mangledInner}}`;
2500
- i = j;
2501
- }
2502
- return changed ? `className:\`${out}\`` : fullMatch;
2503
- });
2504
- function scanClassExpression(source, from) {
2505
- let depth = 0;
2506
- let j = from;
2507
- while (j < source.length) {
2508
- const ch = source[j];
2509
- if (ch === "(" || ch === "[") {
2510
- depth++;
2511
- } else if (ch === ")" || ch === "]") {
2512
- if (depth === 0) {
2513
- break;
2514
- }
2515
- depth--;
2516
- } else if (depth === 0 && (ch === "," || ch === ";" || ch === "\n" || ch === "}")) {
2517
- break;
2518
- }
2519
- j++;
2520
- }
2521
- return j;
2522
- }
2939
+ result = result.replace(/className:\s*`([^`]+)`/g, mangleClassTemplate);
2523
2940
  function mangleTernaryClassStrings(expr) {
2524
2941
  const qIdx = expr.indexOf("?");
2525
2942
  if (qIdx === -1 || !expr.slice(qIdx).includes(":")) {
@@ -2727,7 +3144,12 @@ function createCsszyxPlugins(options = {}) {
2727
3144
  }
2728
3145
  if (!_loggedActiveParsers.has(parserMode)) {
2729
3146
  _loggedActiveParsers.add(parserMode);
2730
- const detail = parserDegraded ? "oxc (degraded from default `rust`: no native binary for this platform)" : parserMode === "rust" ? "rust (native engine)" : parserMode;
3147
+ let detail = parserMode;
3148
+ if (parserDegraded) {
3149
+ detail = "oxc (degraded from default `rust`: no native binary for this platform)";
3150
+ } else if (parserMode === "rust") {
3151
+ detail = "rust (native engine)";
3152
+ }
2731
3153
  console.warn(`[csszyx] active parser: ${detail}`);
2732
3154
  }
2733
3155
  }
@@ -2738,6 +3160,7 @@ function createCsszyxPlugins(options = {}) {
2738
3160
  const state = {
2739
3161
  classes: /* @__PURE__ */ new Set(),
2740
3162
  parsedTheme: null,
3163
+ autoThemeCssFiles: [],
2741
3164
  sawTailwindEntry: false,
2742
3165
  sawAnyCss: false,
2743
3166
  tailwindWarningEmitted: false,
@@ -2748,6 +3171,7 @@ function createCsszyxPlugins(options = {}) {
2748
3171
  skipWarningEmitted: false,
2749
3172
  classesCapped: false,
2750
3173
  ownedClasses: /* @__PURE__ */ new Set(),
3174
+ authoredClasses: /* @__PURE__ */ new Set(),
2751
3175
  mangleMap: {},
2752
3176
  varMangleEntriesByFile: /* @__PURE__ */ new Map(),
2753
3177
  varMangleMap: Object.fromEntries(earlyGlobalVarAliasEntries),
@@ -2837,6 +3261,59 @@ function createCsszyxPlugins(options = {}) {
2837
3261
  );
2838
3262
  }
2839
3263
  }
3264
+ function runAutoThemeScan(rootDir) {
3265
+ if (options.build?.scanCss) {
3266
+ return;
3267
+ }
3268
+ refreshCompileSourceDirs();
3269
+ const cssFiles = [];
3270
+ const walk = (dir) => {
3271
+ let entries;
3272
+ try {
3273
+ entries = fs.readdirSync(dir, { withFileTypes: true });
3274
+ } catch {
3275
+ return;
3276
+ }
3277
+ for (const entry of entries) {
3278
+ if (entry.isDirectory()) {
3279
+ if (!IGNORE_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
3280
+ walk(path.join(dir, entry.name));
3281
+ }
3282
+ continue;
3283
+ }
3284
+ if (entry.name.endsWith(".css")) {
3285
+ cssFiles.push(path.join(dir, entry.name));
3286
+ }
3287
+ }
3288
+ };
3289
+ walk(rootDir);
3290
+ const normRoot = normalizeForMatch(rootDir);
3291
+ for (const sourceDir of compileSourceDirs) {
3292
+ if (sourceDir === normRoot || sourceDir.startsWith(`${normRoot}/`)) {
3293
+ continue;
3294
+ }
3295
+ walk(sourceDir);
3296
+ }
3297
+ const themes = [];
3298
+ const themeFiles = [];
3299
+ for (const file of cssFiles) {
3300
+ let content;
3301
+ try {
3302
+ content = fs.readFileSync(file, "utf-8");
3303
+ } catch {
3304
+ continue;
3305
+ }
3306
+ if (!content.includes("@theme")) {
3307
+ continue;
3308
+ }
3309
+ themes.push(parseThemeBlocks(content));
3310
+ themeFiles.push(file);
3311
+ }
3312
+ state.autoThemeCssFiles = themeFiles;
3313
+ if (themes.length > 0) {
3314
+ state.parsedTheme = mergeThemes(themes);
3315
+ }
3316
+ }
2840
3317
  function isHardIgnored(id) {
2841
3318
  refreshCompileSourceDirs();
2842
3319
  return isHardIgnoredPath(id, compileSourceDirs);
@@ -2864,53 +3341,76 @@ function createCsszyxPlugins(options = {}) {
2864
3341
  }
2865
3342
  const cacheKey = cacheEnabled ? createTransformCacheKey(cacheInput) : null;
2866
3343
  if (cacheEnabled && cacheKey) {
2867
- const memoryCached = transformMemoryCache.get(cacheKey.key);
2868
- if (memoryCached) {
2869
- transformMemoryCache.delete(cacheKey.key);
2870
- transformMemoryCache.set(cacheKey.key, memoryCached);
2871
- return memoryCached;
2872
- }
2873
- const cached = readTransformCache(cacheRoot, cacheInput, cacheKey);
2874
- if (cached) {
2875
- rememberTransformCacheEntry(cacheKey.key, cached);
2876
- return cached;
2877
- }
2878
- if (astBudget === void 0) {
2879
- const handoff = prescanResultHandoff.get(effectiveFilename);
2880
- if (handoff) {
2881
- prescanResultHandoff.delete(effectiveFilename);
2882
- if (handoff.inputSha256 === cacheKey.inputSha256) {
2883
- return handoff.result;
2884
- }
2885
- }
2886
- }
2887
- }
2888
- let result;
3344
+ const cached = findConfiguredTransformCacheEntry(
3345
+ cacheRoot,
3346
+ cacheInput,
3347
+ cacheKey,
3348
+ effectiveFilename,
3349
+ astBudget
3350
+ );
3351
+ if (cached) return cached;
3352
+ }
3353
+ const execution = runConfiguredParser(source, effectiveFilename, compilerOptions);
3354
+ if (cacheEnabled && cacheKey && execution.cacheable) {
3355
+ writeTransformCache(cacheRoot, cacheInput, execution.result, cacheKey);
3356
+ rememberTransformCacheEntry(cacheKey.key, execution.result);
3357
+ }
3358
+ return execution.result;
3359
+ }
3360
+ function findConfiguredTransformCacheEntry(cacheRoot, cacheInput, cacheKey, effectiveFilename, astBudget) {
3361
+ const memoryCached = transformMemoryCache.get(cacheKey.key);
3362
+ if (memoryCached) {
3363
+ transformMemoryCache.delete(cacheKey.key);
3364
+ transformMemoryCache.set(cacheKey.key, memoryCached);
3365
+ return memoryCached;
3366
+ }
3367
+ const diskCached = readTransformCache(cacheRoot, cacheInput, cacheKey);
3368
+ if (diskCached) {
3369
+ rememberTransformCacheEntry(cacheKey.key, diskCached);
3370
+ return diskCached;
3371
+ }
3372
+ if (astBudget !== void 0) return null;
3373
+ const handoff = prescanResultHandoff.get(effectiveFilename);
3374
+ if (!handoff) return null;
3375
+ prescanResultHandoff.delete(effectiveFilename);
3376
+ return handoff.inputSha256 === cacheKey.inputSha256 ? handoff.result : null;
3377
+ }
3378
+ function runConfiguredParser(source, effectiveFilename, compilerOptions) {
2889
3379
  if (parserMode === "babel") {
2890
- result = transformSourceCode(source, effectiveFilename, compilerOptions);
2891
- } else if (parserMode === "rust") {
2892
- result = transformRust(source, effectiveFilename, compilerOptions);
2893
- } else {
2894
- try {
2895
- result = transformOxc(source, effectiveFilename, compilerOptions);
2896
- } catch (err) {
2897
- result = transformSourceCode(source, effectiveFilename, compilerOptions);
2898
- const reason = err instanceof Error ? err.message : String(err);
2899
- result.diagnostics.push(
2900
- `[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason}`
2901
- );
2902
- if (!_babelFallbackFiles.has(effectiveFilename)) {
2903
- _babelFallbackFiles.add(effectiveFilename);
2904
- console.warn(
2905
- `[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason} (${_babelFallbackFiles.size} file(s) so far). Output is still correct; this usually means the file uses a syntax the oxc lane does not yet handle.`
2906
- );
2907
- }
2908
- return result;
2909
- }
3380
+ return {
3381
+ result: transformSourceCode(source, effectiveFilename, compilerOptions),
3382
+ cacheable: true
3383
+ };
2910
3384
  }
2911
- if (cacheEnabled && cacheKey) {
2912
- writeTransformCache(cacheRoot, cacheInput, result, cacheKey);
2913
- rememberTransformCacheEntry(cacheKey.key, result);
3385
+ if (parserMode === "rust") {
3386
+ return {
3387
+ result: transformRust(source, effectiveFilename, compilerOptions),
3388
+ cacheable: true
3389
+ };
3390
+ }
3391
+ try {
3392
+ return {
3393
+ result: transformOxc(source, effectiveFilename, compilerOptions),
3394
+ cacheable: true
3395
+ };
3396
+ } catch (error) {
3397
+ return {
3398
+ result: runBabelFallback(source, effectiveFilename, compilerOptions, error),
3399
+ cacheable: false
3400
+ };
3401
+ }
3402
+ }
3403
+ function runBabelFallback(source, effectiveFilename, compilerOptions, error) {
3404
+ const result = transformSourceCode(source, effectiveFilename, compilerOptions);
3405
+ const reason = error instanceof Error ? error.message : String(error);
3406
+ result.diagnostics.push(
3407
+ `[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason}`
3408
+ );
3409
+ if (!_babelFallbackFiles.has(effectiveFilename)) {
3410
+ _babelFallbackFiles.add(effectiveFilename);
3411
+ console.warn(
3412
+ `[csszyx] oxc parser fell back to Babel for ${effectiveFilename}: ${reason} (${_babelFallbackFiles.size} file(s) so far). Output is still correct; this usually means the file uses a syntax the oxc lane does not yet handle.`
3413
+ );
2914
3414
  }
2915
3415
  return result;
2916
3416
  }
@@ -2949,11 +3449,19 @@ function createCsszyxPlugins(options = {}) {
2949
3449
  const compilerOptions = createCompilerOptions(prescanAstBudget);
2950
3450
  const cacheRoot = resolveTransformCacheDir(state.rootDir, options.build?.cacheDir);
2951
3451
  const results = /* @__PURE__ */ new Map();
2952
- const misses = [];
2953
- if (cacheEnabled) {
2954
- evictTransformCacheOnce();
2955
- }
3452
+ if (cacheEnabled) evictTransformCacheOnce();
2956
3453
  ensureRustTransformAvailable();
3454
+ const misses = collectRustPrescanMisses(files, compilerOptions, cacheRoot, results);
3455
+ if (misses.length === 0) return orderPrescanResults(files, results);
3456
+ try {
3457
+ runRustPrescanBatch(misses, compilerOptions, cacheRoot, results);
3458
+ } catch {
3459
+ runRustPrescanFallback(misses, results);
3460
+ }
3461
+ return orderPrescanResults(files, results);
3462
+ }
3463
+ function collectRustPrescanMisses(files, compilerOptions, cacheRoot, results) {
3464
+ const misses = [];
2957
3465
  for (const file of files) {
2958
3466
  const effectiveFilename = normalizeSourceFilename(file.filePath);
2959
3467
  const cacheInput = createConfiguredTransformCacheInput(
@@ -2962,79 +3470,54 @@ function createCsszyxPlugins(options = {}) {
2962
3470
  compilerOptions
2963
3471
  );
2964
3472
  const cacheKey = cacheEnabled ? createTransformCacheKey(cacheInput) : null;
2965
- if (cacheEnabled && cacheKey) {
2966
- const memoryCached = transformMemoryCache.get(cacheKey.key);
2967
- if (memoryCached) {
2968
- transformMemoryCache.delete(cacheKey.key);
2969
- transformMemoryCache.set(cacheKey.key, memoryCached);
2970
- results.set(file.filePath, memoryCached);
2971
- continue;
2972
- }
2973
- const cached = readTransformCache(cacheRoot, cacheInput, cacheKey);
2974
- if (cached) {
2975
- rememberTransformCacheEntry(cacheKey.key, cached);
2976
- results.set(file.filePath, cached);
2977
- continue;
2978
- }
2979
- }
2980
- misses.push({
2981
- filePath: file.filePath,
2982
- effectiveFilename,
2983
- content: file.content,
3473
+ const cached = cacheKey ? findConfiguredTransformCacheEntry(
3474
+ cacheRoot,
2984
3475
  cacheInput,
2985
- cacheKey
2986
- });
3476
+ cacheKey,
3477
+ effectiveFilename,
3478
+ prescanAstBudget
3479
+ ) : null;
3480
+ if (cached) results.set(file.filePath, cached);
3481
+ else misses.push({ ...file, effectiveFilename, cacheInput, cacheKey });
2987
3482
  }
2988
- if (misses.length === 0) {
2989
- return files.map((file) => {
2990
- const result = results.get(file.filePath);
2991
- return result ? { filePath: file.filePath, result } : null;
2992
- }).filter((entry) => entry !== null);
3483
+ return misses;
3484
+ }
3485
+ function runRustPrescanBatch(misses, compilerOptions, cacheRoot, results) {
3486
+ const batchResults = transformRustBatch(
3487
+ misses.map((file) => ({ filename: file.effectiveFilename, source: file.content })),
3488
+ compilerOptions
3489
+ );
3490
+ for (let index = 0; index < misses.length; index++) {
3491
+ const miss = misses[index];
3492
+ const result = batchResults[index];
3493
+ if (!miss || !result) continue;
3494
+ cacheRustPrescanResult(miss, result, cacheRoot);
3495
+ results.set(miss.filePath, result);
2993
3496
  }
2994
- try {
2995
- const batchResults = transformRustBatch(
2996
- misses.map((file) => ({
2997
- filename: file.effectiveFilename,
2998
- source: file.content
2999
- })),
3000
- compilerOptions
3001
- );
3002
- for (let index = 0; index < misses.length; index++) {
3003
- const miss = misses[index];
3004
- const result = batchResults[index];
3005
- if (!miss || !result) {
3006
- continue;
3007
- }
3008
- if (cacheEnabled && miss.cacheKey) {
3009
- writeTransformCache(cacheRoot, miss.cacheInput, result, miss.cacheKey);
3010
- rememberTransformCacheEntry(miss.cacheKey.key, result);
3011
- }
3497
+ }
3498
+ function cacheRustPrescanResult(miss, result, cacheRoot) {
3499
+ if (!cacheEnabled || !miss.cacheKey) return;
3500
+ writeTransformCache(cacheRoot, miss.cacheInput, result, miss.cacheKey);
3501
+ rememberTransformCacheEntry(miss.cacheKey.key, result);
3502
+ }
3503
+ function runRustPrescanFallback(misses, results) {
3504
+ for (const miss of misses) {
3505
+ try {
3506
+ const result = transformConfiguredSource(
3507
+ miss.content,
3508
+ miss.effectiveFilename,
3509
+ prescanAstBudget
3510
+ );
3012
3511
  results.set(miss.filePath, result);
3013
- }
3014
- } catch {
3015
- for (const miss of misses) {
3016
- try {
3017
- results.set(
3018
- miss.filePath,
3019
- transformConfiguredSource(
3020
- miss.content,
3021
- miss.effectiveFilename,
3022
- prescanAstBudget
3023
- )
3024
- );
3025
- } catch {
3026
- }
3512
+ } catch {
3027
3513
  }
3028
3514
  }
3029
- return files.map((file) => {
3030
- const result = results.get(file.filePath);
3031
- return result ? { filePath: file.filePath, result } : null;
3032
- }).filter((entry) => entry !== null);
3033
3515
  }
3034
- function warnPrescanBudgetSkip(filePath) {
3035
- console.warn(
3036
- `[csszyx] prescan skipped ${filePath}: the file exceeds the AST node budget, so NONE of its classes reached the safelist and their CSS will not be generated. Raise \`build.astBudgetLimit\` in the csszyx plugin options, or split the file.`
3037
- );
3516
+ function orderPrescanResults(files, results) {
3517
+ return files.flatMap((file) => {
3518
+ const result = results.get(file.filePath);
3519
+ return result ? [{ filePath: file.filePath, result }] : [];
3520
+ });
3038
3521
  }
3039
3522
  function transformPrescanSourcesIndividually(files) {
3040
3523
  const results = [];
@@ -3101,11 +3584,12 @@ function createCsszyxPlugins(options = {}) {
3101
3584
  return;
3102
3585
  }
3103
3586
  const safelistPath = path.join(state.rootDir, SAFELIST_FILENAME);
3104
- const classList = escapeHtmlAttribute(Array.from(classes).join(" "));
3587
+ const classNames = Array.from(classes);
3588
+ const classList = escapeHtmlAttribute(classNames.join(" "));
3105
3589
  const content = `<!-- Auto-generated by csszyx \u2014 DO NOT EDIT -->
3106
3590
  <!-- Tailwind CSS scans this file for class name detection -->
3107
3591
  <div class="${classList}"><div class="${classList}">x</div><div class="${classList}">x</div></div>
3108
- `;
3592
+ ` + renderTailwindScannerCandidates(classNames);
3109
3593
  try {
3110
3594
  let existing = "";
3111
3595
  try {
@@ -3180,6 +3664,7 @@ function createCsszyxPlugins(options = {}) {
3180
3664
  } catch {
3181
3665
  return;
3182
3666
  }
3667
+ recordAuthoredClasses(content);
3183
3668
  if (fileMayContainSafelistableSz(content)) {
3184
3669
  prescanSources.push({ filePath, content });
3185
3670
  }
@@ -3282,7 +3767,7 @@ function createCsszyxPlugins(options = {}) {
3282
3767
  for (const kv of objStr.matchAll(numKv)) {
3283
3768
  try {
3284
3769
  collectTransformClasses(
3285
- transform({ [kv[1]]: parseFloat(kv[2]) }),
3770
+ transform({ [kv[1]]: Number.parseFloat(kv[2]) }),
3286
3771
  discoveredClasses
3287
3772
  );
3288
3773
  } catch {
@@ -3322,19 +3807,6 @@ function createCsszyxPlugins(options = {}) {
3322
3807
  }
3323
3808
  }
3324
3809
  }
3325
- function findJsxExpressionEnd(code, bodyStart) {
3326
- let depth = 1;
3327
- let index = bodyStart;
3328
- while (index < code.length && depth > 0) {
3329
- if (code[index] === "{") {
3330
- depth++;
3331
- } else if (code[index] === "}") {
3332
- depth--;
3333
- }
3334
- index++;
3335
- }
3336
- return index - 1;
3337
- }
3338
3810
  function collectExpressionClasses(code) {
3339
3811
  for (const match of code.matchAll(/className=\{/g)) {
3340
3812
  const bodyStart = (match.index ?? 0) + match[0].length;
@@ -3348,17 +3820,22 @@ function createCsszyxPlugins(options = {}) {
3348
3820
  collectQuotedAttributeClasses(code);
3349
3821
  collectExpressionClasses(code);
3350
3822
  }
3823
+ function recordAuthoredClasses(code) {
3824
+ for (const className of collectAuthoredClassNames(code)) {
3825
+ addSafelistClass(className);
3826
+ state.authoredClasses.add(className);
3827
+ }
3828
+ }
3351
3829
  function finalizeMangleMap() {
3352
- const sortedClasses = Array.from(state.ownedClasses);
3353
3830
  const newMap = {};
3354
3831
  let tokenIndex = 0;
3355
- for (let i = 0; i < sortedClasses.length; i++) {
3832
+ for (const className of mangleEligibleClasses(state.ownedClasses, state.authoredClasses)) {
3356
3833
  let token = encode(tokenIndex);
3357
- while (mangleReserved.has(token)) {
3834
+ while (mangleReserved.has(token) || state.authoredClasses.has(token)) {
3358
3835
  tokenIndex++;
3359
3836
  token = encode(tokenIndex);
3360
3837
  }
3361
- newMap[sortedClasses[i]] = token;
3838
+ newMap[className] = token;
3362
3839
  tokenIndex++;
3363
3840
  }
3364
3841
  state.mangleMap = newMap;
@@ -3406,6 +3883,147 @@ function createCsszyxPlugins(options = {}) {
3406
3883
  }
3407
3884
  return result;
3408
3885
  }
3886
+ function unchangedPreTransform(code) {
3887
+ return {
3888
+ code,
3889
+ transformed: false,
3890
+ usesRuntime: false,
3891
+ usesMerge: false,
3892
+ usesSzcn: false,
3893
+ usesSzPart: false,
3894
+ usesColorVar: false,
3895
+ usesSpacingVar: false,
3896
+ usesUnitVar: false
3897
+ };
3898
+ }
3899
+ function transformTailwindCssEntry(code, id) {
3900
+ state.sawAnyCss = true;
3901
+ if (!cssImportsTailwind(code)) return null;
3902
+ state.sawTailwindEntry = true;
3903
+ if (cssHasContentScope(code)) state.tailwindEntryScoped = true;
3904
+ if (!hasInjectableTailwindCandidate(state.classes)) return null;
3905
+ const relPath = computeSafelistRelPath(state.rootDir, SAFELIST_FILENAME, id);
3906
+ const transformed = appendTailwindSourceDirective(code, relPath);
3907
+ return transformed === null ? null : { code: transformed, map: null };
3908
+ }
3909
+ function reportTransformDiagnostics(result, id, warn) {
3910
+ for (const message of result.diagnostics) {
3911
+ if (message.includes("unresolvable sz spread")) {
3912
+ state.spreadWarnings.add(`${id}
3913
+ ${message}`);
3914
+ } else if (message.includes("AST budget exceeded")) {
3915
+ console.warn(`[csszyx] ${id}
3916
+ ${message}`);
3917
+ }
3918
+ }
3919
+ if (quiet || result.diagnostics.length === 0 || process.env.NODE_ENV === "production") {
3920
+ return;
3921
+ }
3922
+ for (const message of result.diagnostics) {
3923
+ if (message.includes("unresolvable sz spread") || message.includes("AST budget exceeded")) {
3924
+ continue;
3925
+ }
3926
+ warn(`[csszyx] ${id}
3927
+ ${message}`);
3928
+ }
3929
+ }
3930
+ function compilerPreTransformOutput(result) {
3931
+ return {
3932
+ code: result.code,
3933
+ transformed: result.transformed,
3934
+ usesRuntime: result.usesRuntime,
3935
+ usesMerge: result.usesMerge,
3936
+ usesSzcn: result.usesSzcn,
3937
+ usesSzPart: result.usesSzPart,
3938
+ usesColorVar: result.usesColorVar,
3939
+ usesSpacingVar: result.usesSpacingVar,
3940
+ usesUnitVar: result.usesUnitVar,
3941
+ szClasses: result.classes
3942
+ };
3943
+ }
3944
+ function transformSzSource(code, id, warn) {
3945
+ if (id.endsWith(".vue")) {
3946
+ const result2 = preprocess(code, options);
3947
+ return { ...unchangedPreTransform(result2.code), transformed: result2.transformed };
3948
+ }
3949
+ if (id.endsWith(".svelte")) {
3950
+ const result2 = preprocess$1(code, options);
3951
+ return result2 ? { ...unchangedPreTransform(result2.code), transformed: true } : unchangedPreTransform(code);
3952
+ }
3953
+ const transformStarted = performance.now();
3954
+ const result = transformConfiguredSource(code, id);
3955
+ traceBenchTiming("transform-hook", id, performance.now() - transformStarted);
3956
+ recordFileVarMangleEntries(state, id, cssVariableEntries(result));
3957
+ recordFileCSSVariableMetrics(state, id, result.code);
3958
+ reportTransformDiagnostics(result, id, warn);
3959
+ for (const [token, data] of result.recoveryTokens) state.recoveryTokens.set(token, data);
3960
+ return compilerPreTransformOutput(result);
3961
+ }
3962
+ function injectLayoutHydration(code, id) {
3963
+ if (!code.includes("<html") || !/(?:layout|Root|Document|app)\.tsx?$/i.test(id)) {
3964
+ return null;
3965
+ }
3966
+ let transformedCode = code;
3967
+ const attrName = options.production?.minify ? "data-sz-cs" : "data-sz-checksum";
3968
+ const htmlTag = findOpeningTag(transformedCode, "html");
3969
+ if (htmlTag) {
3970
+ transformedCode = `${transformedCode.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${transformedCode.slice(htmlTag.close)}`;
3971
+ }
3972
+ 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})}}})()\`}} />`;
3973
+ const bodyTag = findOpeningTag(transformedCode, "body");
3974
+ if (bodyTag) {
3975
+ transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${debugScript}${transformedCode.slice(bodyTag.close + 1)}`;
3976
+ }
3977
+ return transformedCode;
3978
+ }
3979
+ function requiredRuntimeHelpers(output) {
3980
+ const helpers = [];
3981
+ if (output.usesRuntime) helpers.push("_sz");
3982
+ if (output.usesMerge) helpers.push("_szMerge");
3983
+ if (output.usesSzcn) helpers.push("_szcn");
3984
+ if (output.usesSzPart) helpers.push("_szPart");
3985
+ if (output.usesColorVar) helpers.push("__szColorVar");
3986
+ if (output.usesSpacingVar) helpers.push("__szSpacingVar");
3987
+ if (output.usesUnitVar) helpers.push("__szUnitVar");
3988
+ return helpers;
3989
+ }
3990
+ function injectRuntimeHelpers(code, output) {
3991
+ const imports = requiredRuntimeHelpers(output);
3992
+ const hasRuntimeImport = imports.length > 0 && code.includes("@csszyx/runtime");
3993
+ const needed = hasRuntimeImport ? imports.filter((name) => !importsRuntimeHelper(code, name)) : imports;
3994
+ if (needed.length === 0) return null;
3995
+ const existingImport = findRuntimeImportClause(code);
3996
+ if (existingImport) {
3997
+ return code.replace(
3998
+ existingImport.statement,
3999
+ `${existingImport.prefixWithBody}, ${needed.join(", ")} } from '@csszyx/runtime'`
4000
+ );
4001
+ }
4002
+ const importStatement = `import { ${needed.join(", ")} } from '@csszyx/runtime';
4003
+ `;
4004
+ return insertRuntimeImport(code, importStatement);
4005
+ }
4006
+ function injectThemeGroups(code, transformedCode, id, usesSzcn) {
4007
+ if (!usesSzcn && !/\bszcn\s*\(/.test(code) || transformedCode.includes(THEME_GROUPS_VIRTUAL_ID) || !shouldProcessSource(id)) {
4008
+ return null;
4009
+ }
4010
+ return `import '${THEME_GROUPS_VIRTUAL_ID}';
4011
+ ${transformedCode}`;
4012
+ }
4013
+ function collectPreTransformClasses(output) {
4014
+ if (!output.transformed && !output.code.includes("class=") && !output.code.includes("className=")) {
4015
+ return null;
4016
+ }
4017
+ if (output.szClasses) {
4018
+ for (const className of output.szClasses) {
4019
+ addSafelistClass(className);
4020
+ state.ownedClasses.add(className);
4021
+ }
4022
+ } else {
4023
+ extractClasses(output.code);
4024
+ }
4025
+ return { code: output.code, map: null };
4026
+ }
3409
4027
  const prePlugin = createUnplugin(
3410
4028
  (_pluginOptions) => ({
3411
4029
  name: "csszyx:pre",
@@ -3492,176 +4110,41 @@ function createCsszyxPlugins(options = {}) {
3492
4110
  }
3493
4111
  if (shouldProcessSource(id)) {
3494
4112
  trackGlobalVarSourceFile(id, code);
4113
+ recordAuthoredClasses(code);
3495
4114
  }
3496
4115
  if (matchesScriptExtension(id, SCRIPT_ID_EXTENSIONS)) {
3497
4116
  assertNoRSCBoundaryViolation(code, id);
3498
4117
  }
3499
4118
  if (matchesScriptExtension(id, [".css"])) {
3500
- state.sawAnyCss = true;
3501
- if (cssImportsTailwind(code)) {
3502
- state.sawTailwindEntry = true;
3503
- if (cssHasContentScope(code)) {
3504
- state.tailwindEntryScoped = true;
3505
- }
3506
- if (hasInjectableTailwindCandidate(state.classes)) {
3507
- const relPath = computeSafelistRelPath(
3508
- state.rootDir,
3509
- SAFELIST_FILENAME,
3510
- id
3511
- );
3512
- const transformed2 = appendTailwindSourceDirective(code, relPath);
3513
- if (transformed2 !== null) {
3514
- return { code: transformed2, map: null };
3515
- }
3516
- }
3517
- }
3518
- return null;
4119
+ return transformTailwindCssEntry(code, id);
3519
4120
  }
3520
- let transformedCode = code;
3521
- let usesRuntime = false;
3522
- let usesMerge = false;
3523
- let usesSzcn = false;
3524
- let usesSzPart = false;
3525
- let usesColorVar = false;
3526
- let usesSpacingVar = false;
3527
- let usesUnitVar = false;
3528
- let transformed = false;
3529
- let szClasses;
3530
4121
  const hasSzProp = code.includes("sz=") || code.includes("szs=") || /\bsz\s*:\s*["'{]/.test(code) || code.includes('sz: "');
3531
- if (hasSzProp) {
3532
- if (id.endsWith(".vue")) {
3533
- const result = preprocess(code, options);
3534
- if (result.transformed) {
3535
- transformedCode = result.code;
3536
- transformed = true;
3537
- }
3538
- } else if (id.endsWith(".svelte")) {
3539
- const result = preprocess$1(code, options);
3540
- if (result) {
3541
- transformedCode = result.code;
3542
- transformed = true;
3543
- }
3544
- } else {
3545
- const transformStarted = performance.now();
3546
- const result = transformConfiguredSource(code, id);
3547
- traceBenchTiming(
3548
- "transform-hook",
3549
- id,
3550
- performance.now() - transformStarted
3551
- );
3552
- transformedCode = result.code;
3553
- usesRuntime = result.usesRuntime;
3554
- usesMerge = result.usesMerge;
3555
- usesSzcn = result.usesSzcn;
3556
- usesSzPart = result.usesSzPart;
3557
- usesColorVar = result.usesColorVar;
3558
- usesSpacingVar = result.usesSpacingVar;
3559
- usesUnitVar = result.usesUnitVar;
3560
- transformed = result.transformed;
3561
- szClasses = result.classes;
3562
- recordFileVarMangleEntries(state, id, cssVariableEntries(result));
3563
- recordFileCSSVariableMetrics(state, id, result.code);
3564
- for (const msg of result.diagnostics) {
3565
- if (msg.includes("unresolvable sz spread")) {
3566
- state.spreadWarnings.add(`${id}
3567
- ${msg}`);
3568
- } else if (msg.includes("AST budget exceeded")) {
3569
- console.warn(`[csszyx] ${id}
3570
- ${msg}`);
3571
- }
3572
- }
3573
- if (!quiet && result.diagnostics.length > 0 && process.env.NODE_ENV !== "production") {
3574
- for (const msg of result.diagnostics) {
3575
- if (msg.includes("unresolvable sz spread") || msg.includes("AST budget exceeded")) {
3576
- continue;
3577
- }
3578
- this.warn(`[csszyx] ${id}
3579
- ${msg}`);
3580
- }
3581
- }
3582
- for (const [token, data] of result.recoveryTokens) {
3583
- state.recoveryTokens.set(token, data);
3584
- }
3585
- }
3586
- } else if (shouldProcessSource(id)) {
4122
+ const output = hasSzProp ? transformSzSource(code, id, (message) => this.warn(message)) : unchangedPreTransform(code);
4123
+ if (!hasSzProp && shouldProcessSource(id)) {
3587
4124
  recordFileVarMangleEntries(state, id, []);
3588
4125
  recordFileCSSVariableMetrics(state, id, null);
3589
4126
  }
3590
- if (transformedCode.includes("<html") && /(?:layout|Root|Document|app)\.tsx?$/i.test(id)) {
3591
- const attrName = options.production?.minify ? "data-sz-cs" : "data-sz-checksum";
3592
- const htmlTag = findOpeningTag(transformedCode, "html");
3593
- if (htmlTag) {
3594
- transformedCode = `${transformedCode.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${transformedCode.slice(htmlTag.close)}`;
3595
- }
3596
- 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})}}})()\`}} />`;
3597
- const bodyTag = findOpeningTag(transformedCode, "body");
3598
- if (bodyTag) {
3599
- transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${debugScript}${transformedCode.slice(bodyTag.close + 1)}`;
3600
- }
3601
- transformed = true;
4127
+ const layoutCode = injectLayoutHydration(output.code, id);
4128
+ if (layoutCode !== null) {
4129
+ output.code = layoutCode;
4130
+ output.transformed = true;
3602
4131
  }
3603
- {
3604
- const imports = [];
3605
- if (usesRuntime) {
3606
- imports.push("_sz");
3607
- }
3608
- if (usesMerge) {
3609
- imports.push("_szMerge");
3610
- }
3611
- if (usesSzcn) {
3612
- imports.push("_szcn");
3613
- }
3614
- if (usesSzPart) {
3615
- imports.push("_szPart");
3616
- }
3617
- if (usesColorVar) {
3618
- imports.push("__szColorVar");
3619
- }
3620
- if (usesSpacingVar) {
3621
- imports.push("__szSpacingVar");
3622
- }
3623
- if (usesUnitVar) {
3624
- imports.push("__szUnitVar");
3625
- }
3626
- const hasRuntimeImport = imports.length > 0 && transformedCode.includes("@csszyx/runtime");
3627
- const needed = hasRuntimeImport ? imports.filter((name) => !importsRuntimeHelper(transformedCode, name)) : imports;
3628
- if (needed.length > 0) {
3629
- const existingImport = findRuntimeImportClause(transformedCode);
3630
- if (existingImport) {
3631
- transformedCode = transformedCode.replace(
3632
- existingImport.statement,
3633
- `${existingImport.prefixWithBody}, ${needed.join(", ")} } from '@csszyx/runtime'`
3634
- );
3635
- } else {
3636
- const importStmt = `import { ${needed.join(", ")} } from '@csszyx/runtime';
3637
- `;
3638
- transformedCode = insertRuntimeImport(transformedCode, importStmt);
3639
- }
3640
- transformed = true;
3641
- }
4132
+ const runtimeCode = injectRuntimeHelpers(output.code, output);
4133
+ if (runtimeCode !== null) {
4134
+ output.code = runtimeCode;
4135
+ output.transformed = true;
3642
4136
  }
3643
- if ((usesSzcn || /\bszcn\s*\(/.test(code)) && !transformedCode.includes(THEME_GROUPS_VIRTUAL_ID) && shouldProcessSource(id)) {
3644
- transformedCode = `import '${THEME_GROUPS_VIRTUAL_ID}';
3645
- ${transformedCode}`;
3646
- transformed = true;
4137
+ const themedCode = injectThemeGroups(code, output.code, id, output.usesSzcn);
4138
+ if (themedCode !== null) {
4139
+ output.code = themedCode;
4140
+ output.transformed = true;
3647
4141
  }
3648
4142
  if (matchesScriptExtension(id, SCRIPT_ID_EXTENSIONS)) {
3649
- assertNoRSCBoundaryViolation(transformedCode, id);
3650
- const record = createRSCModuleRecord(transformedCode, id);
4143
+ assertNoRSCBoundaryViolation(output.code, id);
4144
+ const record = createRSCModuleRecord(output.code, id);
3651
4145
  state.rscModules.set(record.id, record);
3652
4146
  }
3653
- if (transformed || transformedCode.includes("class=") || transformedCode.includes("className=")) {
3654
- if (szClasses !== void 0) {
3655
- for (const cls of szClasses) {
3656
- addSafelistClass(cls);
3657
- state.ownedClasses.add(cls);
3658
- }
3659
- } else {
3660
- extractClasses(transformedCode);
3661
- }
3662
- return { code: transformedCode, map: null };
3663
- }
3664
- return null;
4147
+ return collectPreTransformClasses(output);
3665
4148
  },
3666
4149
  /** Finalizes the mangle map after all source modules have been processed. */
3667
4150
  buildEnd() {
@@ -3730,6 +4213,7 @@ ${transformedCode}`;
3730
4213
  prescanAndWriteClasses();
3731
4214
  }
3732
4215
  state.parsedTheme = runThemeScan(root, options.build?.scanCss) ?? state.parsedTheme;
4216
+ runAutoThemeScan(root);
3733
4217
  });
3734
4218
  if (options.build?.scanCss) {
3735
4219
  compiler.hooks.thisCompilation.tap("csszyx:theme-deps", (compilation) => {
@@ -3756,6 +4240,7 @@ ${transformedCode}`;
3756
4240
  evictTransformCacheOnce();
3757
4241
  prescanAndWriteClasses();
3758
4242
  state.parsedTheme = runThemeScan(root, options.build?.scanCss) ?? state.parsedTheme;
4243
+ runAutoThemeScan(root);
3759
4244
  },
3760
4245
  /**
3761
4246
  * Vite HMR hook: re-runs theme scan when a watched CSS file changes,
@@ -3765,17 +4250,23 @@ ${transformedCode}`;
3765
4250
  handleHotUpdate(ctx) {
3766
4251
  prescanResultHandoff.clear();
3767
4252
  const scanCss = options.build?.scanCss;
4253
+ const reloadThemeGroupsModule = () => {
4254
+ const themeGroupsModule = ctx.server.moduleGraph.getModuleById(
4255
+ RESOLVED_THEME_GROUPS_VIRTUAL_ID
4256
+ );
4257
+ if (themeGroupsModule) {
4258
+ ctx.server.moduleGraph.invalidateModule(themeGroupsModule);
4259
+ }
4260
+ };
3768
4261
  if (scanCss) {
3769
4262
  const root = ctx.server.config.root || process.cwd();
3770
4263
  if (matchesAnyPattern(ctx.file, scanCss, root)) {
3771
4264
  state.parsedTheme = runThemeScan(root, scanCss) ?? state.parsedTheme;
3772
- const themeGroupsModule = ctx.server.moduleGraph.getModuleById(
3773
- RESOLVED_THEME_GROUPS_VIRTUAL_ID
3774
- );
3775
- if (themeGroupsModule) {
3776
- ctx.server.moduleGraph.invalidateModule(themeGroupsModule);
3777
- }
4265
+ reloadThemeGroupsModule();
3778
4266
  }
4267
+ } else if (ctx.file.endsWith(".css")) {
4268
+ runAutoThemeScan(ctx.server.config.root || process.cwd());
4269
+ reloadThemeGroupsModule();
3779
4270
  }
3780
4271
  if (!shouldProcessSource(ctx.file)) {
3781
4272
  return;
@@ -3870,6 +4361,166 @@ ${transformedCode}`;
3870
4361
  }
3871
4362
  })
3872
4363
  );
4364
+ function createBundleManifest(includeMangleMap) {
4365
+ const manifest = {
4366
+ version: "0.4.0",
4367
+ buildId: state.checksum,
4368
+ classes: Object.keys(state.mangleMap)
4369
+ };
4370
+ if (includeMangleMap && Object.keys(state.mangleMap).length > 0) {
4371
+ manifest.mangleMap = state.mangleMap;
4372
+ }
4373
+ if (Object.keys(state.varMangleMap).length > 0) {
4374
+ manifest.varMangleMap = state.varMangleMap;
4375
+ }
4376
+ const globalVarAliases = extractGlobalVarAliasesForManifest(
4377
+ state.varMangleMap,
4378
+ globalVarAliasPrefix,
4379
+ state.globalVarValidationResult
4380
+ );
4381
+ if (Object.keys(globalVarAliases).length > 0) {
4382
+ manifest.globalVarAliases = globalVarAliases;
4383
+ }
4384
+ if (hasCSSVariableMetrics(state.cssVarMetrics)) {
4385
+ manifest.cssVarMetrics = state.cssVarMetrics;
4386
+ }
4387
+ return manifest;
4388
+ }
4389
+ function isCssSyntaxError(error) {
4390
+ return !!error && typeof error === "object" && "name" in error && error.name === "CssSyntaxError";
4391
+ }
4392
+ function rewriteOutputCss(source, file, shouldMangle, mangledSources, externalClasses) {
4393
+ let css = rewriteCssWithValidatedGlobalVarPlan(
4394
+ source,
4395
+ file,
4396
+ state.globalVarValidationResult
4397
+ );
4398
+ if (!shouldMangle) return css;
4399
+ try {
4400
+ const result = mangleCSSSync(css, state.mangleMap, {
4401
+ debug: options.development?.debug,
4402
+ from: file
4403
+ });
4404
+ for (const className of result.mangledClasses) mangledSources.add(className);
4405
+ for (const className of result.unmangledClasses) externalClasses.add(className);
4406
+ if (result.transformedCount > 0) css = result.css;
4407
+ return css;
4408
+ } catch (error) {
4409
+ if (isCssSyntaxError(error)) return css;
4410
+ throw error;
4411
+ }
4412
+ }
4413
+ function reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses) {
4414
+ if (!shouldMangle) return;
4415
+ const message = mangleHybridHazardMessage(
4416
+ collectMangleHybridHazards(state.mangleMap, mangledSources, externalClasses)
4417
+ );
4418
+ if (message) console.warn(message);
4419
+ }
4420
+ function rewriteWebpackCodeAsset(file, source, shouldMangle, compilation, compiler) {
4421
+ if (shouldMangle && file.endsWith(".html")) {
4422
+ const mangledHtml = mangleHtmlClasses(source);
4423
+ if (mangledHtml !== source) {
4424
+ compilation.updateAsset(file, new compiler.webpack.sources.RawSource(mangledHtml));
4425
+ }
4426
+ return;
4427
+ }
4428
+ if (!file.endsWith(".js")) return;
4429
+ const rewritten = shouldMangle ? replacePlaceholders(mangleCodeClasses(source)) : replacePlaceholders(source);
4430
+ if (rewritten !== source) {
4431
+ compilation.updateAsset(file, new compiler.webpack.sources.RawSource(rewritten));
4432
+ }
4433
+ }
4434
+ function processWebpackAssets(assets, compilation, compiler) {
4435
+ finalizeMangleMap();
4436
+ state.globalVarValidationResult = validateGlobalVarBundleInputs(
4437
+ collectWebpackGlobalVarCssAssets(assets)
4438
+ );
4439
+ const shouldMangle = manglingEnabled && compiler.options.mode !== "development" && Object.keys(state.mangleMap).length > 0;
4440
+ const manifest = createBundleManifest(shouldMangle);
4441
+ compilation.emitAsset(
4442
+ "csszyx-manifest.json",
4443
+ new compiler.webpack.sources.RawSource(JSON.stringify(manifest))
4444
+ );
4445
+ if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
4446
+ const globalVarMap = createGlobalVarMapAssetSource(
4447
+ state.varMangleMap,
4448
+ globalVarAliasPrefix,
4449
+ state.globalVarValidationResult
4450
+ );
4451
+ if (globalVarMap) {
4452
+ compilation.emitAsset(
4453
+ ".csszyx/global-var-map.json",
4454
+ new compiler.webpack.sources.RawSource(globalVarMap)
4455
+ );
4456
+ }
4457
+ }
4458
+ const mangledSources = /* @__PURE__ */ new Set();
4459
+ const externalClasses = /* @__PURE__ */ new Set();
4460
+ for (const file in assets) {
4461
+ const source = assets[file].source().toString();
4462
+ if (file.endsWith(".css")) {
4463
+ const css = rewriteOutputCss(
4464
+ source,
4465
+ file,
4466
+ shouldMangle,
4467
+ mangledSources,
4468
+ externalClasses
4469
+ );
4470
+ if (css !== source) {
4471
+ compilation.updateAsset(file, new compiler.webpack.sources.RawSource(css));
4472
+ }
4473
+ } else {
4474
+ rewriteWebpackCodeAsset(file, source, shouldMangle, compilation, compiler);
4475
+ }
4476
+ }
4477
+ reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses);
4478
+ }
4479
+ function rewriteViteBundleEntry(chunk, file, shouldMangle, mangledSources, externalClasses) {
4480
+ if (chunk.type === "asset" && chunk.fileName.endsWith(".css") && chunk.source !== void 0) {
4481
+ const originalCss = chunk.source.toString();
4482
+ const css = rewriteOutputCss(
4483
+ originalCss,
4484
+ file,
4485
+ shouldMangle,
4486
+ mangledSources,
4487
+ externalClasses
4488
+ );
4489
+ if (css !== originalCss) chunk.source = css;
4490
+ return;
4491
+ }
4492
+ if (chunk.type !== "chunk" || chunk.code === void 0) return;
4493
+ const rewritten = shouldMangle ? replacePlaceholders(mangleCodeClasses(chunk.code)) : replacePlaceholders(chunk.code);
4494
+ if (rewritten !== chunk.code) chunk.code = rewritten;
4495
+ }
4496
+ function processRollupBundle(bundle, emitAsset) {
4497
+ finalizeMangleMap();
4498
+ state.globalVarValidationResult = validateGlobalVarBundleInputs(
4499
+ collectRollupGlobalVarCssAssets(bundle)
4500
+ );
4501
+ const shouldMangle = manglingEnabled && Object.keys(state.mangleMap).length > 0;
4502
+ emitAsset("csszyx-manifest.json", JSON.stringify(createBundleManifest(shouldMangle)));
4503
+ if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
4504
+ const globalVarMap = createGlobalVarMapAssetSource(
4505
+ state.varMangleMap,
4506
+ globalVarAliasPrefix,
4507
+ state.globalVarValidationResult
4508
+ );
4509
+ if (globalVarMap) emitAsset(".csszyx/global-var-map.json", globalVarMap);
4510
+ }
4511
+ const mangledSources = /* @__PURE__ */ new Set();
4512
+ const externalClasses = /* @__PURE__ */ new Set();
4513
+ for (const file in bundle) {
4514
+ rewriteViteBundleEntry(
4515
+ bundle[file],
4516
+ file,
4517
+ shouldMangle,
4518
+ mangledSources,
4519
+ externalClasses
4520
+ );
4521
+ }
4522
+ reportOutputMangleHazards(shouldMangle, mangledSources, externalClasses);
4523
+ }
3873
4524
  const postPlugin = createUnplugin(() => ({
3874
4525
  name: "csszyx:post",
3875
4526
  enforce: "post",
@@ -3880,266 +4531,20 @@ ${transformedCode}`;
3880
4531
  * @param compiler - the Webpack compiler instance
3881
4532
  */
3882
4533
  webpack(compiler) {
3883
- compiler.hooks.compilation.tap("csszyx:post", (compilation) => {
3884
- const stage = compiler.webpack?.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE || compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE;
3885
- compilation.hooks.processAssets.tap(
3886
- {
3887
- name: "csszyx:post",
3888
- stage: stage || 400
3889
- // Fallback integer
3890
- },
3891
- (assets) => {
3892
- finalizeMangleMap();
3893
- state.globalVarValidationResult = validateGlobalVarBundleInputs(
3894
- collectWebpackGlobalVarCssAssets(assets)
3895
- );
3896
- const isWebpackDevMode = compiler.options.mode === "development";
3897
- const manifestData = {
3898
- version: "0.4.0",
3899
- buildId: state.checksum,
3900
- classes: Object.keys(state.mangleMap)
3901
- };
3902
- if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
3903
- manifestData.mangleMap = state.mangleMap;
3904
- }
3905
- if (Object.keys(state.varMangleMap).length > 0) {
3906
- manifestData.varMangleMap = state.varMangleMap;
3907
- }
3908
- const globalVarAliases = extractGlobalVarAliasesForManifest(
3909
- state.varMangleMap,
3910
- globalVarAliasPrefix,
3911
- state.globalVarValidationResult
3912
- );
3913
- if (Object.keys(globalVarAliases).length > 0) {
3914
- manifestData.globalVarAliases = globalVarAliases;
3915
- }
3916
- if (hasCSSVariableMetrics(state.cssVarMetrics)) {
3917
- manifestData.cssVarMetrics = state.cssVarMetrics;
3918
- }
3919
- compilation.emitAsset(
3920
- "csszyx-manifest.json",
3921
- new compiler.webpack.sources.RawSource(JSON.stringify(manifestData))
3922
- );
3923
- if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
3924
- const globalVarMapAsset = createGlobalVarMapAssetSource(
3925
- state.varMangleMap,
3926
- globalVarAliasPrefix,
3927
- state.globalVarValidationResult
3928
- );
3929
- if (globalVarMapAsset) {
3930
- compilation.emitAsset(
3931
- ".csszyx/global-var-map.json",
3932
- new compiler.webpack.sources.RawSource(globalVarMapAsset)
3933
- );
3934
- }
3935
- }
3936
- const mangledSources = /* @__PURE__ */ new Set();
3937
- const externalClasses = /* @__PURE__ */ new Set();
3938
- for (const file in assets) {
3939
- const asset = assets[file];
3940
- const source = asset.source().toString();
3941
- if (file.endsWith(".css")) {
3942
- let css = rewriteCssWithValidatedGlobalVarPlan(
3943
- source,
3944
- file,
3945
- state.globalVarValidationResult
3946
- );
3947
- if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
3948
- try {
3949
- const result = mangleCSSSync(css, state.mangleMap, {
3950
- debug: options.development?.debug,
3951
- from: file
3952
- });
3953
- for (const c of result.mangledClasses) {
3954
- mangledSources.add(c);
3955
- }
3956
- for (const c of result.unmangledClasses) {
3957
- externalClasses.add(c);
3958
- }
3959
- if (result.transformedCount > 0) {
3960
- css = result.css;
3961
- }
3962
- } catch (e) {
3963
- if (e && typeof e === "object" && "name" in e && e.name === "CssSyntaxError") ; else {
3964
- throw e;
3965
- }
3966
- }
3967
- }
3968
- if (css !== source) {
3969
- compilation.updateAsset(
3970
- file,
3971
- new compiler.webpack.sources.RawSource(css)
3972
- );
3973
- }
3974
- continue;
3975
- }
3976
- if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
3977
- if (file.endsWith(".html")) {
3978
- const mangledHtml = mangleHtmlClasses(source);
3979
- if (mangledHtml !== source) {
3980
- compilation.updateAsset(
3981
- file,
3982
- new compiler.webpack.sources.RawSource(mangledHtml)
3983
- );
3984
- continue;
3985
- }
3986
- } else if (file.endsWith(".js")) {
3987
- let mangled = mangleCodeClasses(source);
3988
- mangled = replacePlaceholders(mangled);
3989
- if (mangled !== source) {
3990
- compilation.updateAsset(
3991
- file,
3992
- new compiler.webpack.sources.RawSource(mangled)
3993
- );
3994
- continue;
3995
- }
3996
- }
3997
- }
3998
- if (file.endsWith(".js") && (source.includes(CHECKSUM_PLACEHOLDER) || source.includes(MANGLE_MAP_PLACEHOLDER))) {
3999
- const replaced = replacePlaceholders(source);
4000
- if (replaced !== source) {
4001
- compilation.updateAsset(
4002
- file,
4003
- new compiler.webpack.sources.RawSource(replaced)
4004
- );
4005
- }
4006
- }
4007
- }
4008
- if (manglingEnabled && !isWebpackDevMode && Object.keys(state.mangleMap).length > 0) {
4009
- const hazardMessage = mangleHybridHazardMessage(
4010
- collectMangleHybridHazards(
4011
- state.mangleMap,
4012
- mangledSources,
4013
- externalClasses
4014
- )
4015
- );
4016
- if (hazardMessage) {
4017
- console.warn(hazardMessage);
4018
- }
4019
- }
4020
- }
4021
- );
4022
- });
4534
+ registerWebpackAssetProcessor(compiler, processWebpackAssets);
4023
4535
  },
4024
- vite: {
4025
- /**
4026
- * Vite hook: mangles CSS selectors and JS class strings in the final bundle.
4027
- * @param _options - the output options (unused)
4028
- * @param bundle - the output bundle containing chunks and assets to process
4029
- */
4030
- generateBundle(_options, bundle) {
4031
- finalizeMangleMap();
4032
- state.globalVarValidationResult = validateGlobalVarBundleInputs(
4033
- collectRollupGlobalVarCssAssets(bundle)
4034
- );
4035
- const manifestData = {
4036
- version: "0.4.0",
4037
- buildId: state.checksum,
4038
- classes: Object.keys(state.mangleMap)
4039
- };
4040
- if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
4041
- manifestData.mangleMap = state.mangleMap;
4042
- }
4043
- if (Object.keys(state.varMangleMap).length > 0) {
4044
- manifestData.varMangleMap = state.varMangleMap;
4045
- }
4046
- const globalVarAliases = extractGlobalVarAliasesForManifest(
4047
- state.varMangleMap,
4048
- globalVarAliasPrefix,
4049
- state.globalVarValidationResult
4050
- );
4051
- if (Object.keys(globalVarAliases).length > 0) {
4052
- manifestData.globalVarAliases = globalVarAliases;
4053
- }
4054
- if (hasCSSVariableMetrics(state.cssVarMetrics)) {
4055
- manifestData.cssVarMetrics = state.cssVarMetrics;
4056
- }
4057
- this.emitFile({
4058
- type: "asset",
4059
- fileName: "csszyx-manifest.json",
4060
- source: JSON.stringify(manifestData)
4061
- });
4062
- if (shouldEmitGlobalVarMapAsset(globalVarMangleConfig)) {
4063
- const globalVarMapAsset = createGlobalVarMapAssetSource(
4064
- state.varMangleMap,
4065
- globalVarAliasPrefix,
4066
- state.globalVarValidationResult
4067
- );
4068
- if (globalVarMapAsset) {
4069
- this.emitFile({
4070
- type: "asset",
4071
- fileName: ".csszyx/global-var-map.json",
4072
- source: globalVarMapAsset
4073
- });
4074
- }
4075
- }
4076
- const mangledSources = /* @__PURE__ */ new Set();
4077
- const externalClasses = /* @__PURE__ */ new Set();
4078
- for (const file in bundle) {
4079
- const chunk = bundle[file];
4080
- if (chunk.type === "asset" && chunk.fileName.endsWith(".css")) {
4081
- const originalCss = chunk.source.toString();
4082
- let css = rewriteCssWithValidatedGlobalVarPlan(
4083
- originalCss,
4084
- file,
4085
- state.globalVarValidationResult
4086
- );
4087
- if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
4088
- try {
4089
- const result = mangleCSSSync(css, state.mangleMap, {
4090
- debug: options.development?.debug,
4091
- from: file
4092
- });
4093
- for (const c of result.mangledClasses) {
4094
- mangledSources.add(c);
4095
- }
4096
- for (const c of result.unmangledClasses) {
4097
- externalClasses.add(c);
4098
- }
4099
- if (result.transformedCount > 0) {
4100
- css = result.css;
4101
- }
4102
- } catch (e) {
4103
- if (e && typeof e === "object" && "name" in e && e.name === "CssSyntaxError") ; else {
4104
- throw e;
4105
- }
4106
- }
4107
- }
4108
- if (css !== originalCss) {
4109
- chunk.source = css;
4110
- }
4111
- continue;
4112
- }
4113
- if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
4114
- if (chunk.type === "chunk") {
4115
- let mangledCode = mangleCodeClasses(chunk.code);
4116
- mangledCode = replacePlaceholders(mangledCode);
4117
- if (mangledCode !== chunk.code) {
4118
- chunk.code = mangledCode;
4119
- }
4120
- continue;
4121
- }
4122
- }
4123
- if (chunk.type === "chunk" && (chunk.code.includes(CHECKSUM_PLACEHOLDER) || chunk.code.includes(MANGLE_MAP_PLACEHOLDER))) {
4124
- const replaced = replacePlaceholders(chunk.code);
4125
- if (replaced !== chunk.code) {
4126
- chunk.code = replaced;
4127
- }
4128
- }
4129
- }
4130
- if (manglingEnabled && Object.keys(state.mangleMap).length > 0) {
4131
- const hazardMessage = mangleHybridHazardMessage(
4132
- collectMangleHybridHazards(
4133
- state.mangleMap,
4134
- mangledSources,
4135
- externalClasses
4136
- )
4137
- );
4138
- if (hazardMessage) {
4139
- console.warn(hazardMessage);
4140
- }
4141
- }
4142
- }
4536
+ /**
4537
+ * Rollup-compatible hook used by both pure Rollup and Vite adapters.
4538
+ *
4539
+ * @param this Rollup-compatible output hook context.
4540
+ * @param this.emitFile Output asset emitter.
4541
+ * @param _options Output options (unused).
4542
+ * @param bundle Complete Rollup output bundle.
4543
+ */
4544
+ generateBundle(_options, bundle) {
4545
+ processRollupBundle(bundle, (fileName, source) => {
4546
+ this.emitFile({ type: "asset", fileName, source });
4547
+ });
4143
4548
  }
4144
4549
  }));
4145
4550
  return { prePlugin, postPlugin };
@@ -4171,7 +4576,16 @@ const rollupPlugin = (options = {}) => {
4171
4576
  ];
4172
4577
  };
4173
4578
  const esbuildPlugin = (options = {}) => {
4174
- const { prePlugin, postPlugin } = createCsszyxPlugins(options);
4579
+ if (options.production?.mangle === true) {
4580
+ console.warn(
4581
+ "[csszyx] production.mangle is not supported by the esbuild adapter; class mangling is disabled so emitted JS and CSS keep matching names."
4582
+ );
4583
+ }
4584
+ const safeOptions = {
4585
+ ...options,
4586
+ production: { ...options.production, mangle: false }
4587
+ };
4588
+ const { prePlugin, postPlugin } = createCsszyxPlugins(safeOptions);
4175
4589
  return {
4176
4590
  name: "csszyx",
4177
4591
  /**
@@ -4180,10 +4594,10 @@ const esbuildPlugin = (options = {}) => {
4180
4594
  */
4181
4595
  setup(build) {
4182
4596
  const b = build;
4183
- prePlugin.esbuild(options).setup(b);
4184
- postPlugin.esbuild(options).setup(b);
4597
+ prePlugin.esbuild(safeOptions).setup(b);
4598
+ postPlugin.esbuild(safeOptions).setup(b);
4185
4599
  }
4186
4600
  };
4187
4601
  };
4188
4602
 
4189
- export { webpackPlugin as $, isPackagesSkippedSource as A, isRSCServerModule as B, isTailwindReservedGlobalVar as C, mangleCodeClassesSync as D, mangleHybridHazardMessage as E, mergeThemes as F, missingTailwindEntryMessage as G, normalizeGlobalVarAliasesForCache as H, parseThemeBlocks as I, planGlobalVarAliases as J, readGlobalVarScanCache as K, recordGlobalVarSourceFile as L, resolveCompileSourceDirs as M, resolveGlobalVarScanCacheDir as N, resolveNativeCacheIdentity as O, rewriteGlobalVarCssAliases as P, rollupPlugin as Q, scanCustomPropertyNames as R, scanGlobalVarCss as S, shouldEmitWarning as T, shouldTrackGlobalVarSources as U, shouldWarnMissingTailwindEntry as V, shouldWarnUnscopedMonorepo as W, skippedSzFilesMessage as X, unscopedMonorepoMessage as Y, validateGlobalVarAliasInputs as Z, vitePlugin as _, appendTailwindSourceDirective as a, writeGlobalVarScanCache as a0, assertNoRSCBoundaryViolation as b, assertNoRSCGraphViolation as c, collectMangleHybridHazards as d, computeSafelistRelPath as e, createGlobalVarAliasValidationOptions as f, createGlobalVarMapAssetSource as g, createGlobalVarScanCacheKey as h, createRSCModuleRecord as i, cssHasContentScope as j, cssImportsTailwind as k, deleteRSCModuleRecord as l, esbuildPlugin as m, extractGlobalVarAliasesForManifest as n, fileMayContainSafelistableSz as o, findLocalImportSources as p, findRSCBoundaryViolation as q, findRSCGraphViolation as r, hasInjectableTailwindCandidate as s, hasTokens as t, unplugin as u, hasUseClientDirective as v, hasUseServerDirective as w, isCompileSourceOptedIn as x, isHardIgnoredPath as y, isMonorepoPackage as z };
4603
+ export { vitePlugin as $, isPackagesSkippedSource as A, isRSCServerModule as B, isTailwindReservedGlobalVar as C, mangleCodeClassesSync as D, mangleEligibleClasses as E, mangleHybridHazardMessage as F, mergeThemes as G, missingTailwindEntryMessage as H, normalizeGlobalVarAliasesForCache as I, parseThemeBlocks as J, planGlobalVarAliases as K, readGlobalVarScanCache as L, recordGlobalVarSourceFile as M, resolveCompileSourceDirs as N, resolveGlobalVarScanCacheDir as O, resolveNativeCacheIdentity as P, rewriteGlobalVarCssAliases as Q, rollupPlugin as R, scanCustomPropertyNames as S, scanGlobalVarCss as T, shouldEmitWarning as U, shouldTrackGlobalVarSources as V, shouldWarnMissingTailwindEntry as W, shouldWarnUnscopedMonorepo as X, skippedSzFilesMessage as Y, unscopedMonorepoMessage as Z, validateGlobalVarAliasInputs as _, appendTailwindSourceDirective as a, webpackPlugin as a0, writeGlobalVarScanCache as a1, assertNoRSCBoundaryViolation as b, assertNoRSCGraphViolation as c, collectMangleHybridHazards as d, computeSafelistRelPath as e, createGlobalVarAliasValidationOptions as f, createGlobalVarMapAssetSource as g, createGlobalVarScanCacheKey as h, createRSCModuleRecord as i, cssHasContentScope as j, cssImportsTailwind as k, deleteRSCModuleRecord as l, esbuildPlugin as m, extractGlobalVarAliasesForManifest as n, fileMayContainSafelistableSz as o, findLocalImportSources as p, findRSCBoundaryViolation as q, findRSCGraphViolation as r, hasInjectableTailwindCandidate as s, hasTokens as t, unplugin as u, hasUseClientDirective as v, hasUseServerDirective as w, isCompileSourceOptedIn as x, isHardIgnoredPath as y, isMonorepoPackage as z };