weapp-tailwindcss 4.10.3 → 4.11.0-alpha.1

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 (64) hide show
  1. package/dist/{chunk-3XVUGMTY.mjs → chunk-2LH6PZH3.mjs} +8 -4
  2. package/dist/{chunk-3WUHHFLF.mjs → chunk-35EI5JMK.mjs} +4 -2
  3. package/dist/{chunk-RYC23C3K.js → chunk-4LPOQMFS.js} +203 -198
  4. package/dist/{chunk-5U24PLVV.js → chunk-ACTJYB33.js} +4 -2
  5. package/dist/chunk-CZLXTEHN.js +1936 -0
  6. package/dist/{chunk-TNYEOBAC.mjs → chunk-DOH7FULQ.mjs} +1 -1
  7. package/dist/{chunk-E7775SFS.mjs → chunk-FZNYV7VH.mjs} +914 -334
  8. package/dist/{chunk-6Z4GEN2Y.js → chunk-G3G437UE.js} +2 -2
  9. package/dist/{chunk-DEIJXHGJ.js → chunk-G5NLM3AL.js} +978 -398
  10. package/dist/{chunk-W2N6G2QQ.js → chunk-GWDHNCL2.js} +60 -46
  11. package/dist/{chunk-QOTLDKI4.mjs → chunk-IEZ5RBMG.mjs} +197 -192
  12. package/dist/{chunk-RM3SY4S4.mjs → chunk-JBM3HGHP.mjs} +52 -12
  13. package/dist/{chunk-WXT2GI5R.mjs → chunk-KKT2DKMW.mjs} +30 -16
  14. package/dist/chunk-LD7LZ4IK.mjs +1933 -0
  15. package/dist/{chunk-GCRL3ZYP.js → chunk-NOKJXG3W.js} +5 -5
  16. package/dist/{chunk-YUTKX7JZ.js → chunk-OV7FX6XR.js} +1 -1
  17. package/dist/{chunk-SR4GC2F4.js → chunk-OYSABARD.js} +8 -4
  18. package/dist/{chunk-LICQ6EGN.mjs → chunk-QYZCRG7F.mjs} +2 -2
  19. package/dist/{chunk-UYTCZXNE.mjs → chunk-R6KEYO3F.mjs} +6 -5
  20. package/dist/{chunk-WF636Q5E.js → chunk-SQG2MOFQ.js} +10 -9
  21. package/dist/{chunk-L7OBNTRI.js → chunk-W2EMGF7H.js} +57 -17
  22. package/dist/cli.js +45 -42
  23. package/dist/cli.mjs +9 -6
  24. package/dist/core.d.mts +4 -3
  25. package/dist/core.d.ts +4 -3
  26. package/dist/core.js +124 -30
  27. package/dist/core.mjs +119 -25
  28. package/dist/css-macro/postcss.js +6 -5
  29. package/dist/css-macro/postcss.mjs +4 -3
  30. package/dist/css-macro.js +5 -5
  31. package/dist/css-macro.mjs +2 -2
  32. package/dist/defaults.js +3 -3
  33. package/dist/defaults.mjs +2 -2
  34. package/dist/escape.js +2 -1
  35. package/dist/escape.mjs +2 -1
  36. package/dist/gulp.d.mts +1 -1
  37. package/dist/gulp.d.ts +1 -1
  38. package/dist/gulp.js +8 -7
  39. package/dist/gulp.mjs +8 -7
  40. package/dist/index.js +11 -11
  41. package/dist/index.mjs +9 -9
  42. package/dist/postcss-html-transform.js +1 -1
  43. package/dist/postcss-html-transform.mjs +1 -1
  44. package/dist/presets.js +5 -5
  45. package/dist/presets.mjs +2 -2
  46. package/dist/reset.js +1 -1
  47. package/dist/reset.mjs +1 -1
  48. package/dist/types.js +1 -1
  49. package/dist/types.mjs +1 -1
  50. package/dist/vite.d.mts +1 -1
  51. package/dist/vite.d.ts +1 -1
  52. package/dist/vite.js +9 -8
  53. package/dist/vite.mjs +8 -7
  54. package/dist/webpack.d.mts +1 -1
  55. package/dist/webpack.d.ts +1 -1
  56. package/dist/webpack.js +10 -9
  57. package/dist/webpack.mjs +8 -7
  58. package/dist/webpack4.d.mts +1 -1
  59. package/dist/webpack4.d.ts +1 -1
  60. package/dist/webpack4.js +64 -49
  61. package/dist/webpack4.mjs +33 -18
  62. package/package.json +7 -7
  63. package/dist/chunk-PALDKVKG.mjs +0 -1291
  64. package/dist/chunk-YJSFFRNZ.js +0 -1291
@@ -3,10 +3,10 @@ import {
3
3
  createTailwindcssPatcherFromContext,
4
4
  findNearestPackageRoot,
5
5
  warnMissingCssEntries
6
- } from "./chunk-QOTLDKI4.mjs";
6
+ } from "./chunk-IEZ5RBMG.mjs";
7
7
  import {
8
8
  getDefaultOptions
9
- } from "./chunk-3WUHHFLF.mjs";
9
+ } from "./chunk-35EI5JMK.mjs";
10
10
  import {
11
11
  defuOverrideArray,
12
12
  isMap
@@ -16,15 +16,24 @@ import {
16
16
  import _createDebug from "debug";
17
17
  var _debug = _createDebug("weapp-tw");
18
18
  function createDebug(prefix) {
19
- function debug3(formatter, ...args) {
19
+ const debug3 = ((formatter, ...args) => {
20
20
  return _debug((prefix ?? "") + formatter, ...args);
21
- }
21
+ });
22
+ Object.defineProperty(debug3, "enabled", {
23
+ enumerable: false,
24
+ configurable: false,
25
+ get() {
26
+ return _debug.enabled;
27
+ }
28
+ });
22
29
  return debug3;
23
30
  }
24
31
 
25
32
  // src/tailwindcss/runtime/cache.ts
26
33
  import { statSync } from "fs";
27
34
  var runtimeClassSetCache = /* @__PURE__ */ new WeakMap();
35
+ var runtimeConfigSignatureCache = /* @__PURE__ */ new Map();
36
+ var runtimeConfigSignatureCacheClearTimer;
28
37
  function getCacheEntry(twPatcher) {
29
38
  let entry = runtimeClassSetCache.get(twPatcher);
30
39
  if (!entry) {
@@ -33,17 +42,35 @@ function getCacheEntry(twPatcher) {
33
42
  }
34
43
  return entry;
35
44
  }
45
+ function scheduleRuntimeConfigSignatureCacheClear() {
46
+ if (runtimeConfigSignatureCacheClearTimer) {
47
+ return;
48
+ }
49
+ runtimeConfigSignatureCacheClearTimer = setTimeout(() => {
50
+ runtimeConfigSignatureCache.clear();
51
+ runtimeConfigSignatureCacheClearTimer = void 0;
52
+ }, 0);
53
+ runtimeConfigSignatureCacheClearTimer.unref?.();
54
+ }
36
55
  function getTailwindConfigSignature(twPatcher) {
37
56
  const configPath = twPatcher.options?.tailwind?.config;
38
57
  if (typeof configPath !== "string" || configPath.length === 0) {
39
58
  return void 0;
40
59
  }
60
+ const cached = runtimeConfigSignatureCache.get(configPath);
61
+ if (cached !== void 0) {
62
+ return cached;
63
+ }
64
+ let signature;
41
65
  try {
42
66
  const stats = statSync(configPath);
43
- return `${configPath}:${stats.size}:${stats.mtimeMs}`;
67
+ signature = `${configPath}:${stats.size}:${stats.mtimeMs}`;
44
68
  } catch {
45
- return `${configPath}:missing`;
69
+ signature = `${configPath}:missing`;
46
70
  }
71
+ runtimeConfigSignatureCache.set(configPath, signature);
72
+ scheduleRuntimeConfigSignatureCacheClear();
73
+ return signature;
47
74
  }
48
75
  function getPatchTargetSignature(twPatcher) {
49
76
  const packageInfo = twPatcher.packageInfo;
@@ -53,6 +80,10 @@ function invalidateRuntimeClassSet(twPatcher) {
53
80
  if (!twPatcher) {
54
81
  return;
55
82
  }
83
+ const configPath = twPatcher.options?.tailwind?.config;
84
+ if (typeof configPath === "string" && configPath.length > 0) {
85
+ runtimeConfigSignatureCache.delete(configPath);
86
+ }
56
87
  runtimeClassSetCache.delete(twPatcher);
57
88
  }
58
89
  function getRuntimeClassSetCacheEntry(twPatcher) {
@@ -285,7 +316,7 @@ async function collectRuntimeClassSet(twPatcher, options = {}) {
285
316
  // package.json
286
317
  var package_default = {
287
318
  name: "weapp-tailwindcss",
288
- version: "4.10.3",
319
+ version: "4.11.0-alpha.1",
289
320
  description: "\u628A tailwindcss \u539F\u5B50\u5316\u6837\u5F0F\u601D\u60F3\uFF0C\u5E26\u7ED9\u5C0F\u7A0B\u5E8F\u5F00\u53D1\u8005\u4EEC! bring tailwindcss to miniprogram developers!",
290
321
  author: "ice breaker <1324318532@qq.com>",
291
322
  license: "MIT",
@@ -469,7 +500,7 @@ var package_default = {
469
500
  "lint:fix": "eslint ./src --fix",
470
501
  postinstall: "node bin/weapp-tailwindcss.js patch",
471
502
  "bench:vite-dev-hmr": "tsx scripts/vite-dev-hmr-bench.ts",
472
- "test:watch-hmr": "tsx scripts/watch-hmr-regression/index.ts"
503
+ "test:watch-hmr": "node --import tsx scripts/watch-hmr-regression/index.ts"
473
504
  },
474
505
  publishConfig: {
475
506
  access: "public",
@@ -859,13 +890,13 @@ import { Buffer } from "buffer";
859
890
  import path4 from "path";
860
891
  import process4 from "process";
861
892
  import { logger as logger3 } from "@weapp-tailwindcss/logger";
893
+ var PAREN_CONTENT_RE = /\(([^)]+)\)/u;
894
+ var AT_LOCATION_RE = /at\s+(\S.*)$/u;
895
+ var TRAILING_LINE_COL_RE = /:\d+(?::\d+)?$/u;
862
896
  var globalCacheHolder = globalThis;
863
897
  var compilerContextCache = globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ ?? (globalCacheHolder.__WEAPP_TW_COMPILER_CONTEXT_CACHE__ = /* @__PURE__ */ new Map());
864
- function compareNormalizedValues(a, b) {
865
- const aStr = JSON.stringify(a);
866
- const bStr = JSON.stringify(b);
867
- return aStr.localeCompare(bStr);
868
- }
898
+ var compilerContextKeyCacheByOptions = /* @__PURE__ */ new WeakMap();
899
+ var compilerContextKeyCacheWithoutOptions = /* @__PURE__ */ new Map();
869
900
  function withCircularGuard(value, stack, factory) {
870
901
  if (stack.has(value)) {
871
902
  throw new TypeError("Cannot serialize circular structure in compiler context options");
@@ -884,6 +915,15 @@ function encodeTaggedValue(type, value) {
884
915
  }
885
916
  return record;
886
917
  }
918
+ function hasExplicitOptionBasedir(opts) {
919
+ return typeof opts?.tailwindcssBasedir === "string" && opts.tailwindcssBasedir.length > 0;
920
+ }
921
+ function shouldProbeCallerLocation(opts) {
922
+ if (hasExplicitOptionBasedir(opts)) {
923
+ return false;
924
+ }
925
+ return !(process4.env.WEAPP_TAILWINDCSS_BASEDIR || process4.env.WEAPP_TAILWINDCSS_BASE_DIR || process4.env.TAILWINDCSS_BASEDIR || process4.env.TAILWINDCSS_BASE_DIR);
926
+ }
887
927
  function detectCallerLocation() {
888
928
  const stack = new Error("compiler-context-cache stack probe").stack;
889
929
  if (!stack) {
@@ -891,12 +931,12 @@ function detectCallerLocation() {
891
931
  }
892
932
  const lines = stack.split("\n");
893
933
  for (const line of lines) {
894
- const match = line.match(/\(([^)]+)\)/u) ?? line.match(/at\s+(\S.*)$/u);
934
+ const match = line.match(PAREN_CONTENT_RE) ?? line.match(AT_LOCATION_RE);
895
935
  const location = match?.[1];
896
936
  if (!location) {
897
937
  continue;
898
938
  }
899
- const candidatePath = location.replace(/:\d+(?::\d+)?$/u, "");
939
+ const candidatePath = location.replace(TRAILING_LINE_COL_RE, "");
900
940
  if (!candidatePath || !path4.isAbsolute(candidatePath)) {
901
941
  continue;
902
942
  }
@@ -907,23 +947,62 @@ function detectCallerLocation() {
907
947
  }
908
948
  return void 0;
909
949
  }
910
- function getRuntimeCacheScope() {
911
- return {
950
+ function getRuntimeCacheScope(opts) {
951
+ if (hasExplicitOptionBasedir(opts)) {
952
+ return {
953
+ caller: void 0
954
+ };
955
+ }
956
+ const runtimeScope = {
957
+ caller: void 0,
912
958
  cwd: process4.cwd(),
913
- npm_package_json: process4.env.npm_package_json,
959
+ init_cwd: process4.env.INIT_CWD,
914
960
  npm_config_local_prefix: process4.env.npm_config_local_prefix,
961
+ npm_package_json: process4.env.npm_package_json,
915
962
  pnpm_package_name: process4.env.PNPM_PACKAGE_NAME,
916
- init_cwd: process4.env.INIT_CWD,
917
963
  pwd: process4.env.PWD,
918
- weapp_tailwindcss_basedir: process4.env.WEAPP_TAILWINDCSS_BASEDIR,
919
- weapp_tailwindcss_base_dir: process4.env.WEAPP_TAILWINDCSS_BASE_DIR,
920
- tailwindcss_basedir: process4.env.TAILWINDCSS_BASEDIR,
921
964
  tailwindcss_base_dir: process4.env.TAILWINDCSS_BASE_DIR,
965
+ tailwindcss_basedir: process4.env.TAILWINDCSS_BASEDIR,
966
+ uni_app_input_dir: process4.env.UNI_APP_INPUT_DIR,
967
+ uni_cli_root: process4.env.UNI_CLI_ROOT,
922
968
  uni_input_dir: process4.env.UNI_INPUT_DIR,
923
969
  uni_input_root: process4.env.UNI_INPUT_ROOT,
924
- uni_cli_root: process4.env.UNI_CLI_ROOT,
925
- uni_app_input_dir: process4.env.UNI_APP_INPUT_DIR,
926
- caller: detectCallerLocation()
970
+ weapp_tailwindcss_base_dir: process4.env.WEAPP_TAILWINDCSS_BASE_DIR,
971
+ weapp_tailwindcss_basedir: process4.env.WEAPP_TAILWINDCSS_BASEDIR
972
+ };
973
+ if (shouldProbeCallerLocation(opts)) {
974
+ runtimeScope.caller = detectCallerLocation();
975
+ }
976
+ return runtimeScope;
977
+ }
978
+ function serializeNormalizedValue(value) {
979
+ return JSON.stringify(value);
980
+ }
981
+ function createRuntimeCacheScopeKey(opts) {
982
+ return serializeNormalizedValue(normalizeOptionsValue(getRuntimeCacheScope(opts)));
983
+ }
984
+ function getCompilerContextKeyCacheStore(opts) {
985
+ if (!opts) {
986
+ return compilerContextKeyCacheWithoutOptions;
987
+ }
988
+ let store = compilerContextKeyCacheByOptions.get(opts);
989
+ if (!store) {
990
+ store = /* @__PURE__ */ new Map();
991
+ compilerContextKeyCacheByOptions.set(opts, store);
992
+ }
993
+ return store;
994
+ }
995
+ function createComparableNormalizedValue(rawValue, stack) {
996
+ const normalized = normalizeOptionsValue(rawValue, stack);
997
+ return {
998
+ normalized,
999
+ sortKey: serializeNormalizedValue(normalized)
1000
+ };
1001
+ }
1002
+ function getRuntimeCacheScopeValue(opts) {
1003
+ return {
1004
+ options: opts ?? {},
1005
+ runtime: getRuntimeCacheScope(opts)
927
1006
  };
928
1007
  }
929
1008
  function normalizeOptionsValue(rawValue, stack = /* @__PURE__ */ new WeakSet()) {
@@ -989,21 +1068,25 @@ function normalizeOptionsValue(rawValue, stack = /* @__PURE__ */ new WeakSet())
989
1068
  }
990
1069
  if (rawValue instanceof Set) {
991
1070
  return withCircularGuard(rawValue, stack, () => {
992
- const normalizedEntries = Array.from(rawValue, (element) => normalizeOptionsValue(element, stack));
993
- normalizedEntries.sort(compareNormalizedValues);
1071
+ const normalizedEntries = Array.from(rawValue, (element) => createComparableNormalizedValue(element, stack));
1072
+ normalizedEntries.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
994
1073
  return {
995
1074
  __type: "Set",
996
- value: normalizedEntries
1075
+ value: normalizedEntries.map((entry) => entry.normalized)
997
1076
  };
998
1077
  });
999
1078
  }
1000
1079
  if (rawValue instanceof Map) {
1001
1080
  return withCircularGuard(rawValue, stack, () => {
1002
- const normalizedEntries = Array.from(rawValue.entries()).map(([key, entryValue]) => ({
1003
- key: normalizeOptionsValue(key, stack),
1004
- value: normalizeOptionsValue(entryValue, stack)
1005
- }));
1006
- normalizedEntries.sort((a, b) => compareNormalizedValues(a.key, b.key));
1081
+ const normalizedEntries = Array.from(rawValue.entries(), ([key, entryValue]) => {
1082
+ const normalizedKey = createComparableNormalizedValue(key, stack);
1083
+ return {
1084
+ key: normalizedKey.normalized,
1085
+ sortKey: normalizedKey.sortKey,
1086
+ value: normalizeOptionsValue(entryValue, stack)
1087
+ };
1088
+ });
1089
+ normalizedEntries.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
1007
1090
  return {
1008
1091
  __type: "Map",
1009
1092
  value: normalizedEntries.map((entry) => [entry.key, entry.value])
@@ -1046,12 +1129,16 @@ function normalizeOptionsValue(rawValue, stack = /* @__PURE__ */ new WeakSet())
1046
1129
  }
1047
1130
  function createCompilerContextCacheKey(opts) {
1048
1131
  try {
1049
- const normalized = normalizeOptionsValue({
1050
- options: opts ?? {},
1051
- runtime: getRuntimeCacheScope()
1052
- });
1053
- const serialized = JSON.stringify(normalized);
1054
- return md5(serialized);
1132
+ const runtimeCacheScopeKey = createRuntimeCacheScopeKey(opts);
1133
+ const keyStore = getCompilerContextKeyCacheStore(opts);
1134
+ const cached = keyStore.get(runtimeCacheScopeKey);
1135
+ if (cached !== void 0) {
1136
+ return cached;
1137
+ }
1138
+ const normalized = normalizeOptionsValue(getRuntimeCacheScopeValue(opts));
1139
+ const cacheKey = md5(serializeNormalizedValue(normalized));
1140
+ keyStore.set(runtimeCacheScopeKey, cacheKey);
1141
+ return cacheKey;
1055
1142
  } catch (error) {
1056
1143
  logger3.debug("skip compiler context cache: %O", error);
1057
1144
  return void 0;
@@ -1098,6 +1185,8 @@ var traverse = _interopDefaultCompat(_babelTraverse);
1098
1185
 
1099
1186
  // src/utils/nameMatcher.ts
1100
1187
  import { escapeStringRegexp } from "@weapp-core/regex";
1188
+ var NEVER_MATCH_NAME = () => false;
1189
+ var GLOBAL_FLAG_REGEXP = /g/g;
1101
1190
  function buildFuzzyMatcher(fuzzyStrings) {
1102
1191
  if (fuzzyStrings.length === 0) {
1103
1192
  return void 0;
@@ -1115,11 +1204,11 @@ function normaliseRegex(regex) {
1115
1204
  if (!flags.includes("g")) {
1116
1205
  return regex;
1117
1206
  }
1118
- return new RegExp(source, flags.replace(/g/g, ""));
1207
+ return new RegExp(source, flags.replace(GLOBAL_FLAG_REGEXP, ""));
1119
1208
  }
1120
1209
  function createNameMatcher(list, { exact = false } = {}) {
1121
1210
  if (!list || list.length === 0) {
1122
- return () => false;
1211
+ return NEVER_MATCH_NAME;
1123
1212
  }
1124
1213
  const exactStrings = exact ? /* @__PURE__ */ new Set() : void 0;
1125
1214
  const fuzzyStrings = [];
@@ -1135,12 +1224,36 @@ function createNameMatcher(list, { exact = false } = {}) {
1135
1224
  regexList.push(normaliseRegex(item));
1136
1225
  }
1137
1226
  }
1227
+ if (exact) {
1228
+ const exactStringCount = exactStrings?.size ?? 0;
1229
+ if (exactStringCount === 1 && regexList.length === 0) {
1230
+ const [needle] = exactStrings;
1231
+ return (value) => value === needle;
1232
+ }
1233
+ if (regexList.length === 0) {
1234
+ return (value) => exactStrings.has(value);
1235
+ }
1236
+ if (exactStringCount === 0 && regexList.length === 1) {
1237
+ const [regex] = regexList;
1238
+ return (value) => regex.test(value);
1239
+ }
1240
+ return (value) => {
1241
+ if (exactStrings?.has(value)) {
1242
+ return true;
1243
+ }
1244
+ return regexList.some((regex) => regex.test(value));
1245
+ };
1246
+ }
1138
1247
  const fuzzyMatcher = exact ? void 0 : buildFuzzyMatcher(fuzzyStrings);
1139
1248
  const hasRegex = regexList.length > 0;
1249
+ if (fuzzyMatcher && !hasRegex) {
1250
+ return fuzzyMatcher;
1251
+ }
1252
+ if (!fuzzyMatcher && regexList.length === 1) {
1253
+ const [regex] = regexList;
1254
+ return (value) => regex.test(value);
1255
+ }
1140
1256
  return (value) => {
1141
- if (exact && exactStrings?.has(value)) {
1142
- return true;
1143
- }
1144
1257
  if (fuzzyMatcher?.(value)) {
1145
1258
  return true;
1146
1259
  }
@@ -1186,11 +1299,11 @@ import MagicString from "magic-string";
1186
1299
 
1187
1300
  // src/js/handlers.ts
1188
1301
  import { jsStringEscape } from "@ast-core/escape";
1189
- import { escapeStringRegexp as escapeStringRegexp2 } from "@weapp-core/regex";
1190
1302
  import { splitCode } from "@weapp-tailwindcss/shared/extractors";
1191
1303
 
1192
1304
  // src/wxml/shared.ts
1193
1305
  import { escape, MappingChars2String } from "@weapp-core/escape";
1306
+ var NEWLINE_RE = /[\n\r]+/g;
1194
1307
  function replaceWxml(original, options = {
1195
1308
  keepEOL: false,
1196
1309
  escapeMap: MappingChars2String
@@ -1198,7 +1311,7 @@ function replaceWxml(original, options = {
1198
1311
  const { keepEOL, escapeMap, ignoreHead } = options;
1199
1312
  let res = original;
1200
1313
  if (!keepEOL) {
1201
- res = res.replaceAll(/[\n\r]+/g, "");
1314
+ res = res.replaceAll(NEWLINE_RE, "");
1202
1315
  }
1203
1316
  res = escape(res, {
1204
1317
  map: escapeMap,
@@ -1208,21 +1321,37 @@ function replaceWxml(original, options = {
1208
1321
  }
1209
1322
 
1210
1323
  // src/shared/classname-transform.ts
1324
+ var escapedCandidateCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
1325
+ var defaultEscapedCandidateCache = /* @__PURE__ */ new Map();
1326
+ var lastEscapedCandidateEscapeMap;
1327
+ var lastEscapedCandidateCacheStore;
1328
+ function isUrlLikeCandidate(candidate) {
1329
+ return candidate.startsWith("//") || candidate.startsWith("http://") || candidate.startsWith("https://");
1330
+ }
1211
1331
  function isArbitraryValueCandidate(candidate) {
1212
- const normalized = candidate.trim();
1213
- if (!normalized.includes("[") || !normalized.includes("]")) {
1332
+ let hasOpenBracket = false;
1333
+ let hasCloseBracket = false;
1334
+ for (let i = 0; i < candidate.length; i++) {
1335
+ const char = candidate[i];
1336
+ if (char === "[") {
1337
+ hasOpenBracket = true;
1338
+ } else if (char === "]") {
1339
+ hasCloseBracket = true;
1340
+ }
1341
+ if (hasOpenBracket && hasCloseBracket) {
1342
+ break;
1343
+ }
1344
+ }
1345
+ if (!hasOpenBracket || !hasCloseBracket) {
1214
1346
  return false;
1215
1347
  }
1216
- if (/^(?:https?:)?\/\//.test(normalized)) {
1348
+ const normalized = candidate.trim();
1349
+ if (isUrlLikeCandidate(normalized)) {
1217
1350
  return false;
1218
1351
  }
1219
1352
  return true;
1220
1353
  }
1221
- function shouldEnableArbitraryValueFallback({
1222
- classNameSet,
1223
- jsArbitraryValueFallback,
1224
- tailwindcssMajorVersion
1225
- }) {
1354
+ function shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) {
1226
1355
  if (jsArbitraryValueFallback === true) {
1227
1356
  return true;
1228
1357
  }
@@ -1231,7 +1360,45 @@ function shouldEnableArbitraryValueFallback({
1231
1360
  }
1232
1361
  return tailwindcssMajorVersion === 4 && (!classNameSet || classNameSet.size === 0);
1233
1362
  }
1234
- function resolveClassNameTransformDecision(candidate, {
1363
+ function shouldEnableArbitraryValueFallback({
1364
+ classNameSet,
1365
+ jsArbitraryValueFallback,
1366
+ tailwindcssMajorVersion
1367
+ }) {
1368
+ return shouldEnableArbitraryValueFallbackByInputs(
1369
+ classNameSet,
1370
+ jsArbitraryValueFallback,
1371
+ tailwindcssMajorVersion
1372
+ );
1373
+ }
1374
+ var SKIP_RESULT = { decision: "skip" };
1375
+ var DIRECT_RESULT = { decision: "direct" };
1376
+ var FALLBACK_RESULT = { decision: "fallback" };
1377
+ function getEscapedCandidateCacheStore(escapeMap) {
1378
+ if (!escapeMap) {
1379
+ return defaultEscapedCandidateCache;
1380
+ }
1381
+ if (escapeMap === lastEscapedCandidateEscapeMap && lastEscapedCandidateCacheStore) {
1382
+ return lastEscapedCandidateCacheStore;
1383
+ }
1384
+ let store = escapedCandidateCacheByEscapeMap.get(escapeMap);
1385
+ if (!store) {
1386
+ store = /* @__PURE__ */ new Map();
1387
+ escapedCandidateCacheByEscapeMap.set(escapeMap, store);
1388
+ }
1389
+ lastEscapedCandidateEscapeMap = escapeMap;
1390
+ lastEscapedCandidateCacheStore = store;
1391
+ return store;
1392
+ }
1393
+ function getEscapedCandidate(candidate, escapeMap, store = getEscapedCandidateCacheStore(escapeMap)) {
1394
+ let cached = store.get(candidate);
1395
+ if (cached === void 0) {
1396
+ cached = replaceWxml(candidate, { escapeMap });
1397
+ store.set(candidate, cached);
1398
+ }
1399
+ return cached;
1400
+ }
1401
+ function resolveClassNameTransformWithResult(candidate, {
1235
1402
  alwaysEscape,
1236
1403
  classNameSet,
1237
1404
  escapeMap,
@@ -1241,28 +1408,24 @@ function resolveClassNameTransformDecision(candidate, {
1241
1408
  classContext
1242
1409
  }) {
1243
1410
  if (alwaysEscape) {
1244
- return "direct";
1411
+ return DIRECT_RESULT;
1245
1412
  }
1246
1413
  if (jsPreserveClass?.(candidate)) {
1247
- return "skip";
1414
+ return SKIP_RESULT;
1248
1415
  }
1249
1416
  if (classNameSet?.has(candidate)) {
1250
- return "direct";
1417
+ return DIRECT_RESULT;
1251
1418
  }
1252
1419
  if (classNameSet && classNameSet.size > 0) {
1253
- const escapedCandidate = replaceWxml(candidate, { escapeMap });
1420
+ const escapedCandidate = getEscapedCandidate(candidate, escapeMap);
1254
1421
  if (escapedCandidate !== candidate && classNameSet.has(escapedCandidate)) {
1255
- return "escaped";
1422
+ return { decision: "escaped", escapedValue: escapedCandidate };
1256
1423
  }
1257
1424
  }
1258
- if (classContext && isArbitraryValueCandidate(candidate) && shouldEnableArbitraryValueFallback({
1259
- classNameSet,
1260
- jsArbitraryValueFallback,
1261
- tailwindcssMajorVersion
1262
- })) {
1263
- return "fallback";
1425
+ if (classContext && shouldEnableArbitraryValueFallbackByInputs(classNameSet, jsArbitraryValueFallback, tailwindcssMajorVersion) && isArbitraryValueCandidate(candidate)) {
1426
+ return FALLBACK_RESULT;
1264
1427
  }
1265
- return "skip";
1428
+ return SKIP_RESULT;
1266
1429
  }
1267
1430
 
1268
1431
  // src/utils/decode.ts
@@ -1306,8 +1469,45 @@ var CLASS_HELPER_IDENTIFIERS = /* @__PURE__ */ new Set([
1306
1469
  "cx",
1307
1470
  "r"
1308
1471
  ]);
1472
+ var DASH_CODE = 45;
1473
+ var COLON_CODE = 58;
1474
+ var UPPERCASE_A_CODE = 65;
1475
+ var UPPERCASE_Z_CODE = 90;
1476
+ var UNDERSCORE_CODE = 95;
1477
+ var ASCII_MAX_CODE = 127;
1478
+ var NORMALIZE_KEYWORD_REGEXP = /[-_:]/g;
1309
1479
  function normalizeKeyword(name) {
1310
- return name.replace(/[-_:]/g, "").toLowerCase();
1480
+ const length = name.length;
1481
+ let firstNormalizedIndex = -1;
1482
+ for (let i = 0; i < length; i++) {
1483
+ const code = name.charCodeAt(i);
1484
+ if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE || code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
1485
+ firstNormalizedIndex = i;
1486
+ break;
1487
+ }
1488
+ if (code > ASCII_MAX_CODE) {
1489
+ return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
1490
+ }
1491
+ }
1492
+ if (firstNormalizedIndex === -1) {
1493
+ return name;
1494
+ }
1495
+ let normalized = name.slice(0, firstNormalizedIndex);
1496
+ for (let i = firstNormalizedIndex; i < length; i++) {
1497
+ const code = name.charCodeAt(i);
1498
+ if (code === DASH_CODE || code === UNDERSCORE_CODE || code === COLON_CODE) {
1499
+ continue;
1500
+ }
1501
+ if (code >= UPPERCASE_A_CODE && code <= UPPERCASE_Z_CODE) {
1502
+ normalized += String.fromCharCode(code + 32);
1503
+ continue;
1504
+ }
1505
+ if (code > ASCII_MAX_CODE) {
1506
+ return name.replace(NORMALIZE_KEYWORD_REGEXP, "").toLowerCase();
1507
+ }
1508
+ normalized += name[i];
1509
+ }
1510
+ return normalized;
1311
1511
  }
1312
1512
  function readObjectKeyName(path5) {
1313
1513
  if (path5.isIdentifier()) {
@@ -1344,28 +1544,30 @@ function isClassLikeJsxAttribute(path5) {
1344
1544
  }
1345
1545
  return CLASS_LIKE_KEYWORDS.has(normalizeKeyword(namePath.node.name));
1346
1546
  }
1347
- function isClassLikeCallExpression(path5, valuePath) {
1348
- if (!path5.isCallExpression()) {
1349
- return false;
1350
- }
1351
- const args = path5.get("arguments");
1352
- if (!args.includes(valuePath)) {
1353
- return false;
1354
- }
1355
- const calleePath = path5.get("callee");
1547
+ function readCallHelperName(calleePath) {
1356
1548
  if (calleePath.isIdentifier()) {
1357
- return CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(calleePath.node.name));
1549
+ return calleePath.node.name;
1358
1550
  }
1359
1551
  if (calleePath.isMemberExpression()) {
1360
1552
  const propertyPath = calleePath.get("property");
1361
1553
  if (propertyPath.isIdentifier()) {
1362
- return CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(propertyPath.node.name));
1554
+ return propertyPath.node.name;
1363
1555
  }
1364
1556
  if (propertyPath.isStringLiteral()) {
1365
- return CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(propertyPath.node.value));
1557
+ return propertyPath.node.value;
1366
1558
  }
1367
1559
  }
1368
- return false;
1560
+ return void 0;
1561
+ }
1562
+ function isClassLikeCallExpression(path5, valuePath) {
1563
+ if (!path5.isCallExpression()) {
1564
+ return false;
1565
+ }
1566
+ const helperName = readCallHelperName(path5.get("callee"));
1567
+ if (!helperName || !CLASS_HELPER_IDENTIFIERS.has(normalizeKeyword(helperName))) {
1568
+ return false;
1569
+ }
1570
+ return path5.get("arguments").includes(valuePath);
1369
1571
  }
1370
1572
  function isClassContextLiteralPath(path5) {
1371
1573
  let current = path5;
@@ -1387,31 +1589,22 @@ function isClassContextLiteralPath(path5) {
1387
1589
 
1388
1590
  // src/js/handlers.ts
1389
1591
  var debug2 = createDebug("[js:handlers] ");
1390
- var patternCache = /* @__PURE__ */ new Map();
1391
1592
  var replacementCacheByEscapeMap = /* @__PURE__ */ new WeakMap();
1392
1593
  var defaultReplacementCache = /* @__PURE__ */ new Map();
1393
- function getPattern(candidate) {
1394
- let cached = patternCache.get(candidate);
1395
- if (!cached) {
1396
- cached = new RegExp(escapeStringRegexp2(candidate));
1397
- patternCache.set(candidate, cached);
1398
- }
1399
- return cached;
1400
- }
1401
- function getReplacement(candidate, escapeMap) {
1594
+ var WEAPP_TW_IGNORE_MARKER = "weapp-tw";
1595
+ var IGNORE_MARKER = "ignore";
1596
+ function getReplacementCacheStore(escapeMap) {
1402
1597
  if (!escapeMap) {
1403
- let cached2 = defaultReplacementCache.get(candidate);
1404
- if (cached2 === void 0) {
1405
- cached2 = replaceWxml(candidate, { escapeMap });
1406
- defaultReplacementCache.set(candidate, cached2);
1407
- }
1408
- return cached2;
1598
+ return defaultReplacementCache;
1409
1599
  }
1410
1600
  let store = replacementCacheByEscapeMap.get(escapeMap);
1411
1601
  if (!store) {
1412
1602
  store = /* @__PURE__ */ new Map();
1413
1603
  replacementCacheByEscapeMap.set(escapeMap, store);
1414
1604
  }
1605
+ return store;
1606
+ }
1607
+ function getReplacement(candidate, escapeMap, store = getReplacementCacheStore(escapeMap)) {
1415
1608
  let cached = store.get(candidate);
1416
1609
  if (cached === void 0) {
1417
1610
  cached = replaceWxml(candidate, { escapeMap });
@@ -1420,17 +1613,28 @@ function getReplacement(candidate, escapeMap) {
1420
1613
  return cached;
1421
1614
  }
1422
1615
  function hasIgnoreComment(node) {
1423
- return Array.isArray(node.leadingComments) && node.leadingComments.some((comment) => comment.value.includes("weapp-tw") && comment.value.includes("ignore"));
1616
+ const { leadingComments } = node;
1617
+ if (!Array.isArray(leadingComments) || leadingComments.length === 0) {
1618
+ return false;
1619
+ }
1620
+ for (const comment of leadingComments) {
1621
+ const { value } = comment;
1622
+ if (value.includes(WEAPP_TW_IGNORE_MARKER) && value.includes(IGNORE_MARKER)) {
1623
+ return true;
1624
+ }
1625
+ }
1626
+ return false;
1424
1627
  }
1425
1628
  function extractLiteralValue(path5, { unescapeUnicode, arbitraryValues }) {
1426
1629
  const allowDoubleQuotes = arbitraryValues?.allowDoubleQuotes;
1630
+ const { node } = path5;
1427
1631
  let offset = 0;
1428
1632
  let original;
1429
- if (path5.isStringLiteral()) {
1633
+ if (node.type === "StringLiteral") {
1430
1634
  offset = 1;
1431
- original = path5.node.value;
1432
- } else if (path5.isTemplateElement()) {
1433
- original = path5.node.value.raw;
1635
+ original = node.value;
1636
+ } else if (node.type === "TemplateElement") {
1637
+ original = node.value.raw;
1434
1638
  } else {
1435
1639
  original = "";
1436
1640
  }
@@ -1445,59 +1649,110 @@ function extractLiteralValue(path5, { unescapeUnicode, arbitraryValues }) {
1445
1649
  original
1446
1650
  };
1447
1651
  }
1652
+ function createCandidatePlanResolver(options, classContext) {
1653
+ const { escapeMap } = options;
1654
+ const replacementCache = getReplacementCacheStore(escapeMap);
1655
+ const transformOptions = classContext ? {
1656
+ ...options,
1657
+ classContext
1658
+ } : options;
1659
+ let firstCandidate = "";
1660
+ let firstPlan;
1661
+ let cache;
1662
+ const buildCandidatePlan = (candidate) => {
1663
+ const result = resolveClassNameTransformWithResult(candidate, transformOptions);
1664
+ if (result.decision === "skip") {
1665
+ return { result };
1666
+ }
1667
+ let replacement;
1668
+ if (result.decision === "escaped" && result.escapedValue) {
1669
+ replacement = result.escapedValue;
1670
+ replacementCache.set(candidate, replacement);
1671
+ } else {
1672
+ replacement = getReplacement(candidate, escapeMap, replacementCache);
1673
+ }
1674
+ return {
1675
+ result,
1676
+ replacement
1677
+ };
1678
+ };
1679
+ return (candidate) => {
1680
+ if (cache) {
1681
+ const cached = cache.get(candidate);
1682
+ if (cached) {
1683
+ return cached;
1684
+ }
1685
+ } else if (firstPlan && candidate === firstCandidate) {
1686
+ return firstPlan;
1687
+ }
1688
+ const plan = buildCandidatePlan(candidate);
1689
+ if (!firstPlan) {
1690
+ firstCandidate = candidate;
1691
+ firstPlan = plan;
1692
+ return plan;
1693
+ }
1694
+ if (!cache) {
1695
+ cache = /* @__PURE__ */ new Map();
1696
+ cache.set(firstCandidate, firstPlan);
1697
+ }
1698
+ cache.set(candidate, plan);
1699
+ return plan;
1700
+ };
1701
+ }
1448
1702
  function replaceHandleValue(path5, options) {
1449
- const {
1450
- escapeMap,
1451
- needEscaped = false
1452
- } = options;
1703
+ const { needEscaped = false } = options;
1453
1704
  const { classNameSet, alwaysEscape } = options;
1454
1705
  const fallbackEnabled = shouldEnableArbitraryValueFallback(options);
1455
- const classContext = options.wrapExpression || isClassContextLiteralPath(path5);
1456
1706
  if (!alwaysEscape && !fallbackEnabled && (!classNameSet || classNameSet.size === 0)) {
1457
1707
  return void 0;
1458
1708
  }
1459
- const { literal, original, allowDoubleQuotes, offset } = extractLiteralValue(path5, options);
1460
1709
  if (hasIgnoreComment(path5.node)) {
1461
1710
  return void 0;
1462
1711
  }
1712
+ const { literal, original, allowDoubleQuotes, offset } = extractLiteralValue(path5, options);
1463
1713
  const candidates = splitCode(literal, allowDoubleQuotes);
1464
1714
  if (candidates.length === 0) {
1465
1715
  return void 0;
1466
1716
  }
1717
+ const debugEnabled = debug2.enabled;
1718
+ const classContext = options.wrapExpression || isClassContextLiteralPath(path5);
1467
1719
  let transformed = literal;
1468
1720
  let mutated = false;
1469
1721
  let matchedCandidateCount = 0;
1470
1722
  let escapedDecisionCount = 0;
1471
1723
  let fallbackDecisionCount = 0;
1472
- const escapedSamples = [];
1473
- const skippedSamples = [];
1724
+ let escapedSamples;
1725
+ let skippedSamples;
1726
+ const resolveCandidatePlan = createCandidatePlanResolver(options, classContext);
1474
1727
  for (const candidate of candidates) {
1475
- const decision = resolveClassNameTransformDecision(candidate, {
1476
- ...options,
1477
- classContext
1478
- });
1479
- if (decision === "skip") {
1480
- if (skippedSamples.length < 6) {
1481
- skippedSamples.push(candidate);
1728
+ const plan = resolveCandidatePlan(candidate);
1729
+ if (plan.result.decision === "skip") {
1730
+ if (debugEnabled) {
1731
+ if (!skippedSamples) {
1732
+ skippedSamples = [];
1733
+ }
1734
+ if (skippedSamples.length < 6) {
1735
+ skippedSamples.push(candidate);
1736
+ }
1482
1737
  }
1483
1738
  continue;
1484
1739
  }
1485
- matchedCandidateCount += 1;
1486
- if (decision === "escaped") {
1487
- escapedDecisionCount += 1;
1488
- if (escapedSamples.length < 6) {
1489
- escapedSamples.push(candidate);
1740
+ if (debugEnabled) {
1741
+ matchedCandidateCount += 1;
1742
+ if (plan.result.decision === "escaped") {
1743
+ escapedDecisionCount += 1;
1744
+ if (!escapedSamples) {
1745
+ escapedSamples = [];
1746
+ }
1747
+ if (escapedSamples.length < 6) {
1748
+ escapedSamples.push(candidate);
1749
+ }
1750
+ }
1751
+ if (plan.result.decision === "fallback") {
1752
+ fallbackDecisionCount += 1;
1490
1753
  }
1491
1754
  }
1492
- if (decision === "fallback") {
1493
- fallbackDecisionCount += 1;
1494
- }
1495
- if (!transformed.includes(candidate)) {
1496
- continue;
1497
- }
1498
- const pattern = getPattern(candidate);
1499
- const replacement = getReplacement(candidate, escapeMap);
1500
- const replaced = transformed.replace(pattern, replacement);
1755
+ const replaced = transformed.replace(candidate, plan.replacement);
1501
1756
  if (replaced !== transformed) {
1502
1757
  transformed = replaced;
1503
1758
  mutated = true;
@@ -1507,18 +1762,20 @@ function replaceHandleValue(path5, options) {
1507
1762
  if (!mutated || typeof node.start !== "number" || typeof node.end !== "number") {
1508
1763
  return void 0;
1509
1764
  }
1510
- debug2(
1511
- "runtimeSet size=%d fallbackTriggered=%s candidates=%d matched=%d escapedHits=%d skipped=%d file=%s escapedSamples=%s skippedSamples=%s",
1512
- classNameSet?.size ?? 0,
1513
- fallbackDecisionCount > 0,
1514
- candidates.length,
1515
- matchedCandidateCount,
1516
- escapedDecisionCount,
1517
- skippedSamples.length,
1518
- options.filename ?? "unknown",
1519
- escapedSamples.join(",") || "-",
1520
- skippedSamples.join(",") || "-"
1521
- );
1765
+ if (debugEnabled) {
1766
+ debug2(
1767
+ "runtimeSet size=%d fallbackTriggered=%s candidates=%d matched=%d escapedHits=%d skipped=%d file=%s escapedSamples=%s skippedSamples=%s",
1768
+ classNameSet?.size ?? 0,
1769
+ fallbackDecisionCount > 0,
1770
+ candidates.length,
1771
+ matchedCandidateCount,
1772
+ escapedDecisionCount,
1773
+ skippedSamples?.length ?? 0,
1774
+ options.filename ?? "unknown",
1775
+ escapedSamples?.join(",") || "-",
1776
+ skippedSamples?.join(",") || "-"
1777
+ );
1778
+ }
1522
1779
  const start = node.start + offset;
1523
1780
  const end = node.end - offset;
1524
1781
  if (start >= end || transformed === original) {
@@ -1534,6 +1791,14 @@ function replaceHandleValue(path5, options) {
1534
1791
  }
1535
1792
 
1536
1793
  // src/js/sourceAnalysis.ts
1794
+ function hasReplacementEntries(replacements) {
1795
+ for (const key in replacements) {
1796
+ if (Object.hasOwn(replacements, key)) {
1797
+ return true;
1798
+ }
1799
+ }
1800
+ return false;
1801
+ }
1537
1802
  function createModuleSpecifierReplacementToken(path5, replacement) {
1538
1803
  const node = path5.node;
1539
1804
  if (node.value === replacement) {
@@ -1555,6 +1820,12 @@ function createModuleSpecifierReplacementToken(path5, replacement) {
1555
1820
  };
1556
1821
  }
1557
1822
  function collectModuleSpecifierReplacementTokens(analysis, replacements) {
1823
+ if (!hasReplacementEntries(replacements)) {
1824
+ return [];
1825
+ }
1826
+ if (analysis.importDeclarations.size === 0 && analysis.exportDeclarations.size === 0 && analysis.requireCallPaths.length === 0 && analysis.walker.imports.size === 0) {
1827
+ return [];
1828
+ }
1558
1829
  const tokens = [];
1559
1830
  const applyReplacement = (path5) => {
1560
1831
  const replacement = replacements[path5.node.value];
@@ -1593,8 +1864,38 @@ function collectModuleSpecifierReplacementTokens(analysis, replacements) {
1593
1864
  }
1594
1865
 
1595
1866
  // src/js/babel/process.ts
1867
+ var optionVariantsCache = /* @__PURE__ */ new WeakMap();
1868
+ function getNeedEscapedOptions(options, needEscaped) {
1869
+ if (options.needEscaped === needEscaped) {
1870
+ return options;
1871
+ }
1872
+ let cached = optionVariantsCache.get(options);
1873
+ if (!cached) {
1874
+ cached = {};
1875
+ optionVariantsCache.set(options, cached);
1876
+ }
1877
+ if (needEscaped) {
1878
+ if (!cached.stringLiteralOptions) {
1879
+ cached.stringLiteralOptions = {
1880
+ ...options,
1881
+ needEscaped: true
1882
+ };
1883
+ }
1884
+ return cached.stringLiteralOptions;
1885
+ }
1886
+ if (!cached.templateLiteralOptions) {
1887
+ cached.templateLiteralOptions = {
1888
+ ...options,
1889
+ needEscaped: false
1890
+ };
1891
+ }
1892
+ return cached.templateLiteralOptions;
1893
+ }
1596
1894
  function processUpdatedSource(rawSource, options, analysis) {
1597
1895
  const { targetPaths, jsTokenUpdater, ignoredPaths } = analysis;
1896
+ if (targetPaths.length === 0 && !options.moduleSpecifierReplacements && jsTokenUpdater.length === 0) {
1897
+ return new MagicString(rawSource);
1898
+ }
1598
1899
  const replacementTokens = [];
1599
1900
  for (const path5 of targetPaths) {
1600
1901
  if (ignoredPaths.has(path5)) {
@@ -1602,10 +1903,7 @@ function processUpdatedSource(rawSource, options, analysis) {
1602
1903
  }
1603
1904
  const token = replaceHandleValue(
1604
1905
  path5,
1605
- {
1606
- ...options,
1607
- needEscaped: path5.isStringLiteral() ? options.needEscaped ?? true : false
1608
- }
1906
+ path5.isStringLiteral() ? getNeedEscapedOptions(options, true) : getNeedEscapedOptions(options, false)
1609
1907
  );
1610
1908
  if (token) {
1611
1909
  replacementTokens.push(token);
@@ -1626,6 +1924,8 @@ function processUpdatedSource(rawSource, options, analysis) {
1626
1924
 
1627
1925
  // src/js/evalTransforms.ts
1628
1926
  import { jsStringEscape as jsStringEscape2 } from "@ast-core/escape";
1927
+ var evalHandlerOptionsCache = /* @__PURE__ */ new WeakMap();
1928
+ var EVAL_SCOPE_ERROR_REGEXP = /pass a scope and parentPath|traversing a Program\/File/i;
1629
1929
  function isEvalPath(path5) {
1630
1930
  if (path5.isCallExpression()) {
1631
1931
  const calleePath = path5.get("callee");
@@ -1664,12 +1964,8 @@ function createEvalReplacementToken(path5, updated) {
1664
1964
  path: path5
1665
1965
  };
1666
1966
  }
1667
- function handleEvalStringLiteral(path5, options, updater, handler) {
1668
- const { code } = handler(path5.node.value, {
1669
- ...options,
1670
- needEscaped: false,
1671
- generateMap: false
1672
- });
1967
+ function handleEvalStringLiteral(path5, handlerOptions, updater, handler) {
1968
+ const { code } = handler(path5.node.value, handlerOptions);
1673
1969
  if (!code) {
1674
1970
  return;
1675
1971
  }
@@ -1678,11 +1974,8 @@ function handleEvalStringLiteral(path5, options, updater, handler) {
1678
1974
  updater.addToken(token);
1679
1975
  }
1680
1976
  }
1681
- function handleEvalTemplateElement(path5, options, updater, handler) {
1682
- const { code } = handler(path5.node.value.raw, {
1683
- ...options,
1684
- generateMap: false
1685
- });
1977
+ function handleEvalTemplateElement(path5, handlerOptions, updater, handler) {
1978
+ const { code } = handler(path5.node.value.raw, handlerOptions);
1686
1979
  if (!code) {
1687
1980
  return;
1688
1981
  }
@@ -1691,21 +1984,58 @@ function handleEvalTemplateElement(path5, options, updater, handler) {
1691
1984
  updater.addToken(token);
1692
1985
  }
1693
1986
  }
1987
+ function getEvalStringHandlerOptions(options) {
1988
+ if (options.needEscaped === false && options.generateMap === false) {
1989
+ return options;
1990
+ }
1991
+ let cached = evalHandlerOptionsCache.get(options);
1992
+ if (!cached) {
1993
+ cached = {};
1994
+ evalHandlerOptionsCache.set(options, cached);
1995
+ }
1996
+ if (!cached.stringLiteralOptions) {
1997
+ cached.stringLiteralOptions = {
1998
+ ...options,
1999
+ needEscaped: false,
2000
+ generateMap: false
2001
+ };
2002
+ }
2003
+ return cached.stringLiteralOptions;
2004
+ }
2005
+ function getEvalTemplateHandlerOptions(options) {
2006
+ if (options.generateMap === false) {
2007
+ return options;
2008
+ }
2009
+ let cached = evalHandlerOptionsCache.get(options);
2010
+ if (!cached) {
2011
+ cached = {};
2012
+ evalHandlerOptionsCache.set(options, cached);
2013
+ }
2014
+ if (!cached.templateLiteralOptions) {
2015
+ cached.templateLiteralOptions = {
2016
+ ...options,
2017
+ generateMap: false
2018
+ };
2019
+ }
2020
+ return cached.templateLiteralOptions;
2021
+ }
1694
2022
  function walkEvalExpression(path5, options, updater, handler) {
2023
+ const stringHandlerOptions = getEvalStringHandlerOptions(options);
2024
+ const templateHandlerOptions = getEvalTemplateHandlerOptions(options);
1695
2025
  const maybeTraverse = path5?.traverse;
1696
2026
  if (typeof maybeTraverse === "function") {
1697
2027
  try {
1698
2028
  return maybeTraverse.call(path5, {
1699
2029
  StringLiteral(innerPath) {
1700
- handleEvalStringLiteral(innerPath, options, updater, handler);
2030
+ handleEvalStringLiteral(innerPath, stringHandlerOptions, updater, handler);
1701
2031
  },
1702
2032
  TemplateElement(innerPath) {
1703
- handleEvalTemplateElement(innerPath, options, updater, handler);
2033
+ handleEvalTemplateElement(innerPath, templateHandlerOptions, updater, handler);
1704
2034
  }
1705
2035
  });
1706
2036
  } catch (error) {
1707
2037
  const msg = error?.message ?? "";
1708
- const scopeError = /pass a scope and parentPath|traversing a Program\/File/i.test(msg);
2038
+ const scopeError = EVAL_SCOPE_ERROR_REGEXP.test(msg);
1709
2039
  if (!scopeError) {
1710
2040
  throw error;
1711
2041
  }
@@ -1715,12 +2045,12 @@ function walkEvalExpression(path5, options, updater, handler) {
1715
2045
  if (Array.isArray(getArgs)) {
1716
2046
  for (const arg of getArgs) {
1717
2047
  if (arg?.isStringLiteral?.()) {
1718
- handleEvalStringLiteral(arg, options, updater, handler);
2048
+ handleEvalStringLiteral(arg, stringHandlerOptions, updater, handler);
1719
2049
  continue;
1720
2050
  }
1721
2051
  if (arg?.isTemplateLiteral?.()) {
1722
2052
  for (const quasi of arg.get("quasis")) {
1723
- handleEvalTemplateElement(quasi, options, updater, handler);
2053
+ handleEvalTemplateElement(quasi, templateHandlerOptions, updater, handler);
1724
2054
  }
1725
2055
  }
1726
2056
  }
@@ -1734,14 +2064,14 @@ function walkEvalExpression(path5, options, updater, handler) {
1734
2064
  node: n,
1735
2065
  isStringLiteral: () => true
1736
2066
  };
1737
- handleEvalStringLiteral(stub, options, updater, handler);
2067
+ handleEvalStringLiteral(stub, stringHandlerOptions, updater, handler);
1738
2068
  } else if (n?.type === "TemplateLiteral" && Array.isArray(n.quasis)) {
1739
2069
  for (const q of n.quasis) {
1740
2070
  const stub = {
1741
2071
  node: q,
1742
2072
  isTemplateElement: () => true
1743
2073
  };
1744
- handleEvalTemplateElement(stub, options, updater, handler);
2074
+ handleEvalTemplateElement(stub, templateHandlerOptions, updater, handler);
1745
2075
  }
1746
2076
  }
1747
2077
  }
@@ -1969,7 +2299,7 @@ var JsModuleGraph = class {
1969
2299
  }
1970
2300
  build() {
1971
2301
  this.collectDependencies();
1972
- const linked = {};
2302
+ let linked;
1973
2303
  for (const [filename, state] of this.modules) {
1974
2304
  if (filename === this.rootFilename) {
1975
2305
  continue;
@@ -1981,6 +2311,9 @@ var JsModuleGraph = class {
1981
2311
  const ms = processUpdatedSource(state.source, childOptions, state.analysis);
1982
2312
  const code = ms.toString();
1983
2313
  if (code !== state.source) {
2314
+ if (!linked) {
2315
+ linked = {};
2316
+ }
1984
2317
  linked[filename] = { code };
1985
2318
  }
1986
2319
  }
@@ -2104,7 +2437,7 @@ function walkExportDefaultDeclaration(ctx, path5) {
2104
2437
  function walkExportAllDeclaration(ctx, path5) {
2105
2438
  const source = path5.get("source");
2106
2439
  if (source.isStringLiteral()) {
2107
- ctx.imports.add(
2440
+ ctx.addImportToken(
2108
2441
  {
2109
2442
  declaration: path5,
2110
2443
  source: source.node.value,
@@ -2152,14 +2485,35 @@ function maybeAddImportToken(imports, arg) {
2152
2485
  }
2153
2486
 
2154
2487
  // src/js/NodePathWalker.ts
2488
+ var EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS = [];
2489
+ var EMPTY_IMPORT_TOKENS = /* @__PURE__ */ new Set();
2490
+ function NOOP_STRING_PATH_CALLBACK() {
2491
+ }
2492
+ var NEVER_MATCH_NAME2 = () => false;
2155
2493
  var NodePathWalker = class {
2156
2494
  constructor({ ignoreCallExpressionIdentifiers, callback } = {}) {
2157
- this.ignoreCallExpressionIdentifiers = ignoreCallExpressionIdentifiers ?? [];
2158
- this.callback = callback ?? (() => {
2159
- });
2160
- this.imports = /* @__PURE__ */ new Set();
2161
- this.visited = /* @__PURE__ */ new WeakSet();
2162
- this.isIgnoredCallIdentifier = createNameMatcher(this.ignoreCallExpressionIdentifiers, { exact: true });
2495
+ this.hasIgnoredCallIdentifiers = Boolean(ignoreCallExpressionIdentifiers && ignoreCallExpressionIdentifiers.length > 0);
2496
+ this.ignoreCallExpressionIdentifiers = ignoreCallExpressionIdentifiers ?? EMPTY_IGNORE_CALL_EXPRESSION_IDENTIFIERS;
2497
+ this.callback = callback ?? NOOP_STRING_PATH_CALLBACK;
2498
+ this.isIgnoredCallIdentifier = this.hasIgnoredCallIdentifiers ? createNameMatcher(this.ignoreCallExpressionIdentifiers, { exact: true }) : NEVER_MATCH_NAME2;
2499
+ }
2500
+ get imports() {
2501
+ return this.importsStore ?? EMPTY_IMPORT_TOKENS;
2502
+ }
2503
+ getWritableImports() {
2504
+ if (!this.importsStore) {
2505
+ this.importsStore = /* @__PURE__ */ new Set();
2506
+ }
2507
+ return this.importsStore;
2508
+ }
2509
+ addImportToken(token) {
2510
+ this.getWritableImports().add(token);
2511
+ }
2512
+ getVisited() {
2513
+ if (!this.visitedStore) {
2514
+ this.visitedStore = /* @__PURE__ */ new WeakSet();
2515
+ }
2516
+ return this.visitedStore;
2163
2517
  }
2164
2518
  walkVariableDeclarator(path5) {
2165
2519
  const init = path5.get("init");
@@ -2206,10 +2560,11 @@ var NodePathWalker = class {
2206
2560
  }
2207
2561
  }
2208
2562
  walkNode(arg) {
2209
- if (this.visited.has(arg)) {
2563
+ const visited = this.getVisited();
2564
+ if (visited.has(arg)) {
2210
2565
  return;
2211
2566
  }
2212
- this.visited.add(arg);
2567
+ visited.add(arg);
2213
2568
  if (arg.isIdentifier()) {
2214
2569
  const binding = arg?.scope?.getBinding?.(arg.node.name);
2215
2570
  if (binding) {
@@ -2239,13 +2594,16 @@ var NodePathWalker = class {
2239
2594
  this.walkArrayExpression(arg);
2240
2595
  } else if (arg.isVariableDeclarator()) {
2241
2596
  this.walkVariableDeclarator(arg);
2242
- } else if (maybeAddImportToken(this.imports, arg)) {
2597
+ } else if (maybeAddImportToken(this.getWritableImports(), arg)) {
2243
2598
  }
2244
2599
  }
2245
2600
  /**
2246
2601
  * Walk the arguments of a desired call expression so their bindings can be analysed.
2247
2602
  */
2248
2603
  walkCallExpression(path5) {
2604
+ if (!this.hasIgnoredCallIdentifiers) {
2605
+ return;
2606
+ }
2249
2607
  const calleePath = path5.get("callee");
2250
2608
  if (calleePath.isIdentifier() && this.isIgnoredCallIdentifier(calleePath.node.name)) {
2251
2609
  for (const arg of path5.get("arguments")) {
@@ -2271,20 +2629,48 @@ var NodePathWalker = class {
2271
2629
  function createTaggedTemplateIgnore({ matcher, names }) {
2272
2630
  const bindingIgnoreCache = /* @__PURE__ */ new Map();
2273
2631
  const taggedTemplateIgnoreCache = /* @__PURE__ */ new WeakMap();
2274
- const canonicalIgnoreNames = new Set(
2275
- (names ?? []).filter((item) => typeof item === "string")
2276
- );
2632
+ const seenBindings = /* @__PURE__ */ new Set();
2633
+ let singleCanonicalIgnoreName;
2634
+ let canonicalIgnoreNames;
2635
+ for (const item of names ?? []) {
2636
+ if (typeof item !== "string") {
2637
+ continue;
2638
+ }
2639
+ if (singleCanonicalIgnoreName === void 0) {
2640
+ singleCanonicalIgnoreName = item;
2641
+ continue;
2642
+ }
2643
+ if (item === singleCanonicalIgnoreName) {
2644
+ continue;
2645
+ }
2646
+ if (!canonicalIgnoreNames) {
2647
+ canonicalIgnoreNames = /* @__PURE__ */ new Set([singleCanonicalIgnoreName, item]);
2648
+ continue;
2649
+ }
2650
+ canonicalIgnoreNames.add(item);
2651
+ }
2652
+ const hasCanonicalIgnoreNames = singleCanonicalIgnoreName !== void 0;
2653
+ const matchesIgnoreName = (value) => {
2654
+ if (hasCanonicalIgnoreNames) {
2655
+ if (canonicalIgnoreNames) {
2656
+ if (canonicalIgnoreNames.has(value)) {
2657
+ return true;
2658
+ }
2659
+ } else if (value === singleCanonicalIgnoreName) {
2660
+ return true;
2661
+ }
2662
+ }
2663
+ return matcher(value);
2664
+ };
2277
2665
  const propertyMatches = (propertyPath) => {
2278
2666
  if (!propertyPath) {
2279
2667
  return false;
2280
2668
  }
2281
2669
  if (propertyPath.isIdentifier()) {
2282
- const { name } = propertyPath.node;
2283
- return canonicalIgnoreNames.has(name) || matcher(name);
2670
+ return matchesIgnoreName(propertyPath.node.name);
2284
2671
  }
2285
2672
  if (propertyPath.isStringLiteral()) {
2286
- const { value } = propertyPath.node;
2287
- return canonicalIgnoreNames.has(value) || matcher(value);
2673
+ return matchesIgnoreName(propertyPath.node.value);
2288
2674
  }
2289
2675
  return false;
2290
2676
  };
@@ -2316,9 +2702,9 @@ function createTaggedTemplateIgnore({ matcher, names }) {
2316
2702
  const bindingPath = binding.path;
2317
2703
  if (bindingPath.isImportSpecifier()) {
2318
2704
  const imported = bindingPath.node.imported;
2319
- if (imported.type === "Identifier" && (canonicalIgnoreNames.has(imported.name) || matcher(imported.name))) {
2705
+ if (imported.type === "Identifier" && matchesIgnoreName(imported.name)) {
2320
2706
  result = true;
2321
- } else if (imported.type === "StringLiteral" && (canonicalIgnoreNames.has(imported.value) || matcher(imported.value))) {
2707
+ } else if (imported.type === "StringLiteral" && matchesIgnoreName(imported.value)) {
2322
2708
  result = true;
2323
2709
  }
2324
2710
  } else if (bindingPath.isVariableDeclarator()) {
@@ -2359,7 +2745,7 @@ function createTaggedTemplateIgnore({ matcher, names }) {
2359
2745
  }
2360
2746
  if (current.isSequenceExpression()) {
2361
2747
  const expressions = current.get("expressions");
2362
- const last = expressions[expressions.length - 1];
2748
+ const last = expressions.at(-1);
2363
2749
  if (last) {
2364
2750
  current = last;
2365
2751
  continue;
@@ -2374,23 +2760,23 @@ function createTaggedTemplateIgnore({ matcher, names }) {
2374
2760
  }
2375
2761
  return current;
2376
2762
  };
2377
- const evaluateTagPath = (tagPath) => {
2763
+ const evaluateTagPath = (tagPath, seen) => {
2378
2764
  if (tagPath.isCallExpression?.() || tagPath.node.type === "CallExpression") {
2379
2765
  const calleePath = tagPath.get("callee");
2380
- return evaluateTagPath(calleePath);
2766
+ return evaluateTagPath(calleePath, seen);
2381
2767
  }
2382
2768
  if (tagPath.isIdentifier()) {
2383
- if (matcher(tagPath.node.name)) {
2769
+ if (matchesIgnoreName(tagPath.node.name)) {
2384
2770
  return true;
2385
2771
  }
2386
2772
  const binding = tagPath?.scope?.getBinding?.(tagPath.node.name);
2387
2773
  if (binding) {
2388
- return resolvesToWeappTwIgnore(binding, /* @__PURE__ */ new Set());
2774
+ return resolvesToWeappTwIgnore(binding, seen);
2389
2775
  }
2390
2776
  return false;
2391
2777
  }
2392
2778
  if (tagPath.isMemberExpression()) {
2393
- return resolvesMemberExpressionToIgnore(tagPath, /* @__PURE__ */ new Set());
2779
+ return resolvesMemberExpressionToIgnore(tagPath, seen);
2394
2780
  }
2395
2781
  return false;
2396
2782
  };
@@ -2405,7 +2791,8 @@ function createTaggedTemplateIgnore({ matcher, names }) {
2405
2791
  taggedTemplateIgnoreCache.set(tagPath.node, effectiveCached);
2406
2792
  return effectiveCached;
2407
2793
  }
2408
- const result = evaluateTagPath(effectiveTagPath);
2794
+ seenBindings.clear();
2795
+ const result = evaluateTagPath(effectiveTagPath, seenBindings);
2409
2796
  taggedTemplateIgnoreCache.set(effectiveTagPath.node, result);
2410
2797
  taggedTemplateIgnoreCache.set(tagPath.node, result);
2411
2798
  return result;
@@ -2421,30 +2808,96 @@ function createTaggedTemplateIgnore({ matcher, names }) {
2421
2808
  // src/js/babel.ts
2422
2809
  var EXPRESSION_WRAPPER_PREFIX = "(\n";
2423
2810
  var EXPRESSION_WRAPPER_SUFFIX = "\n)";
2424
- function analyzeSource(ast, options, handler) {
2811
+ var EMPTY_IGNORED_PATHS = /* @__PURE__ */ new WeakSet();
2812
+ var EMPTY_IMPORT_DECLARATIONS = /* @__PURE__ */ new Set();
2813
+ var EMPTY_EXPORT_DECLARATIONS = /* @__PURE__ */ new Set();
2814
+ var EMPTY_REQUIRE_CALL_PATHS = [];
2815
+ var ignoredTaggedTemplateMatcherCache = /* @__PURE__ */ new WeakMap();
2816
+ function getIgnoredTaggedTemplateMatcher(options) {
2817
+ const cached = ignoredTaggedTemplateMatcherCache.get(options);
2818
+ if (cached) {
2819
+ return cached;
2820
+ }
2821
+ const created = createNameMatcher(options.ignoreTaggedTemplateExpressionIdentifiers, { exact: true });
2822
+ ignoredTaggedTemplateMatcherCache.set(options, created);
2823
+ return created;
2824
+ }
2825
+ function analyzeSource(ast, options, handler, collectModuleMetadata = true) {
2425
2826
  const jsTokenUpdater = new JsTokenUpdater();
2426
- const ignoredPaths = /* @__PURE__ */ new WeakSet();
2427
- const walker = new NodePathWalker(
2428
- {
2429
- ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
2430
- callback(path5) {
2431
- if (path5.isStringLiteral() || path5.isTemplateElement()) {
2432
- ignoredPaths.add(path5);
2433
- }
2434
- }
2435
- }
2436
- );
2437
- const isIgnoredTaggedTemplate = createNameMatcher(options.ignoreTaggedTemplateExpressionIdentifiers, { exact: true });
2438
- const taggedTemplateIgnore = createTaggedTemplateIgnore({
2439
- matcher: isIgnoredTaggedTemplate,
2440
- names: options.ignoreTaggedTemplateExpressionIdentifiers
2441
- });
2442
2827
  const needScope = Boolean(options.ignoreCallExpressionIdentifiers && options.ignoreCallExpressionIdentifiers.length > 0);
2828
+ const ignoredPaths = needScope ? /* @__PURE__ */ new WeakSet() : EMPTY_IGNORED_PATHS;
2829
+ const walker = needScope ? new NodePathWalker({
2830
+ ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
2831
+ callback(path5) {
2832
+ ignoredPaths.add(path5);
2833
+ }
2834
+ }) : new NodePathWalker();
2835
+ let taggedTemplateIgnore;
2836
+ const hasTaggedTemplateIgnoreIdentifiers = Boolean(
2837
+ options.ignoreTaggedTemplateExpressionIdentifiers && options.ignoreTaggedTemplateExpressionIdentifiers.length > 0
2838
+ );
2839
+ function getTaggedTemplateIgnore() {
2840
+ if (!taggedTemplateIgnore) {
2841
+ taggedTemplateIgnore = createTaggedTemplateIgnore({
2842
+ matcher: getIgnoredTaggedTemplateMatcher(options),
2843
+ names: options.ignoreTaggedTemplateExpressionIdentifiers
2844
+ });
2845
+ }
2846
+ return taggedTemplateIgnore;
2847
+ }
2443
2848
  const targetPaths = [];
2444
- const importDeclarations = /* @__PURE__ */ new Set();
2445
- const exportDeclarations = /* @__PURE__ */ new Set();
2446
- const requireCallPaths = [];
2849
+ const importDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_IMPORT_DECLARATIONS;
2850
+ const exportDeclarations = collectModuleMetadata ? /* @__PURE__ */ new Set() : EMPTY_EXPORT_DECLARATIONS;
2851
+ const requireCallPaths = collectModuleMetadata ? [] : EMPTY_REQUIRE_CALL_PATHS;
2447
2852
  const evalHandler = handler ?? jsHandler;
2853
+ const templateElementEnter = hasTaggedTemplateIgnoreIdentifiers ? (p) => {
2854
+ const pp = p.parentPath;
2855
+ if (pp.isTemplateLiteral()) {
2856
+ const ppp = pp.parentPath;
2857
+ if (isEvalPath(ppp)) {
2858
+ return;
2859
+ }
2860
+ if (ppp.isTaggedTemplateExpression()) {
2861
+ const tagPath = ppp.get("tag");
2862
+ if (getTaggedTemplateIgnore().shouldIgnore(tagPath)) {
2863
+ return;
2864
+ }
2865
+ }
2866
+ }
2867
+ targetPaths.push(p);
2868
+ } : (p) => {
2869
+ const pp = p.parentPath;
2870
+ if (pp.isTemplateLiteral()) {
2871
+ const ppp = pp.parentPath;
2872
+ if (isEvalPath(ppp)) {
2873
+ return;
2874
+ }
2875
+ }
2876
+ targetPaths.push(p);
2877
+ };
2878
+ const callExpressionEnter = !collectModuleMetadata && !needScope ? (p) => {
2879
+ if (isEvalPath(p)) {
2880
+ walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
2881
+ }
2882
+ } : (p) => {
2883
+ if (isEvalPath(p)) {
2884
+ walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
2885
+ return;
2886
+ }
2887
+ const calleePath = p.get("callee");
2888
+ if (collectModuleMetadata && calleePath.isIdentifier({ name: "require" }) && !p?.scope?.hasBinding?.("require")) {
2889
+ const args = p.get("arguments");
2890
+ if (Array.isArray(args) && args.length > 0) {
2891
+ const first = args[0];
2892
+ if (first?.isStringLiteral()) {
2893
+ requireCallPaths.push(first);
2894
+ }
2895
+ }
2896
+ }
2897
+ if (needScope) {
2898
+ walker.walkCallExpression(p);
2899
+ }
2900
+ };
2448
2901
  const traverseOptions = {
2449
2902
  StringLiteral: {
2450
2903
  enter(p) {
@@ -2455,54 +2908,23 @@ function analyzeSource(ast, options, handler) {
2455
2908
  }
2456
2909
  },
2457
2910
  TemplateElement: {
2458
- enter(p) {
2459
- const pp = p.parentPath;
2460
- if (pp.isTemplateLiteral()) {
2461
- const ppp = pp.parentPath;
2462
- if (isEvalPath(ppp)) {
2463
- return;
2464
- }
2465
- if (ppp.isTaggedTemplateExpression()) {
2466
- const tagPath = ppp.get("tag");
2467
- if (taggedTemplateIgnore.shouldIgnore(tagPath)) {
2468
- return;
2469
- }
2470
- }
2471
- }
2472
- targetPaths.push(p);
2473
- }
2911
+ enter: templateElementEnter
2474
2912
  },
2475
2913
  CallExpression: {
2476
- enter(p) {
2477
- if (isEvalPath(p)) {
2478
- walkEvalExpression(p, options, jsTokenUpdater, evalHandler);
2479
- return;
2480
- }
2481
- const calleePath = p.get("callee");
2482
- if (calleePath.isIdentifier({ name: "require" }) && !p?.scope?.hasBinding?.("require")) {
2483
- const args = p.get("arguments");
2484
- if (Array.isArray(args) && args.length > 0) {
2485
- const first = args[0];
2486
- if (first?.isStringLiteral()) {
2487
- requireCallPaths.push(first);
2488
- }
2489
- }
2914
+ enter: callExpressionEnter
2915
+ },
2916
+ ...collectModuleMetadata ? {
2917
+ ImportDeclaration: {
2918
+ enter(p) {
2919
+ importDeclarations.add(p);
2490
2920
  }
2491
- if (needScope) {
2492
- walker.walkCallExpression(p);
2921
+ },
2922
+ ExportDeclaration: {
2923
+ enter(p) {
2924
+ exportDeclarations.add(p);
2493
2925
  }
2494
2926
  }
2495
- },
2496
- ImportDeclaration: {
2497
- enter(p) {
2498
- importDeclarations.add(p);
2499
- }
2500
- },
2501
- ExportDeclaration: {
2502
- enter(p) {
2503
- exportDeclarations.add(p);
2504
- }
2505
- }
2927
+ } : {}
2506
2928
  };
2507
2929
  traverse(ast, { ...traverseOptions, noScope: !needScope });
2508
2930
  return {
@@ -2528,7 +2950,8 @@ function jsHandler(rawSource, options) {
2528
2950
  error
2529
2951
  };
2530
2952
  }
2531
- const analysis = analyzeSource(ast, options, jsHandler);
2953
+ const needsModuleMetadata = Boolean(options.moduleSpecifierReplacements || options.moduleGraph && options.filename);
2954
+ const analysis = analyzeSource(ast, options, jsHandler, needsModuleMetadata);
2532
2955
  const ms = processUpdatedSource(source, options, analysis);
2533
2956
  if (shouldWrapExpression) {
2534
2957
  const start = 0;
@@ -2539,11 +2962,17 @@ function jsHandler(rawSource, options) {
2539
2962
  ms.remove(end - suffixLength, end);
2540
2963
  }
2541
2964
  const result = {
2542
- code: ms.toString(),
2543
- get map() {
2544
- return ms.generateMap();
2545
- }
2965
+ code: ms.toString()
2546
2966
  };
2967
+ if (options.generateMap) {
2968
+ Object.defineProperty(result, "map", {
2969
+ configurable: true,
2970
+ enumerable: true,
2971
+ get() {
2972
+ return ms.generateMap();
2973
+ }
2974
+ });
2975
+ }
2547
2976
  if (options.moduleGraph && options.filename) {
2548
2977
  const graph = new JsModuleGraph(
2549
2978
  {
@@ -2555,7 +2984,7 @@ function jsHandler(rawSource, options) {
2555
2984
  options.moduleGraph
2556
2985
  );
2557
2986
  const linked = graph.build();
2558
- if (Object.keys(linked).length > 0) {
2987
+ if (linked) {
2559
2988
  result.linked = linked;
2560
2989
  }
2561
2990
  }
@@ -2563,51 +2992,142 @@ function jsHandler(rawSource, options) {
2563
2992
  }
2564
2993
 
2565
2994
  // src/js/index.ts
2995
+ function hasDefinedOverrides(options) {
2996
+ if (!options) {
2997
+ return false;
2998
+ }
2999
+ for (const key in options) {
3000
+ if (options[key] !== void 0) {
3001
+ return true;
3002
+ }
3003
+ }
3004
+ return false;
3005
+ }
3006
+ var CACHEABLE_SOURCE_MAX_LENGTH = 512;
3007
+ var RESULT_CACHE_LIMIT = 256;
3008
+ function shouldCacheJsResult(rawSource, options) {
3009
+ if (rawSource.length === 0 || rawSource.length > CACHEABLE_SOURCE_MAX_LENGTH) {
3010
+ return false;
3011
+ }
3012
+ if (options.moduleGraph || options.filename) {
3013
+ return false;
3014
+ }
3015
+ return true;
3016
+ }
2566
3017
  function createJsHandler(options) {
2567
- const {
2568
- arbitraryValues,
2569
- escapeMap,
2570
- staleClassNameFallback,
2571
- jsArbitraryValueFallback,
2572
- tailwindcssMajorVersion,
2573
- jsPreserveClass,
2574
- generateMap,
2575
- needEscaped,
2576
- alwaysEscape,
2577
- unescapeUnicode,
2578
- babelParserOptions,
2579
- ignoreCallExpressionIdentifiers,
2580
- ignoreTaggedTemplateExpressionIdentifiers,
2581
- uniAppX,
2582
- moduleSpecifierReplacements
2583
- } = options;
2584
- function handler(rawSource, classNameSet, options2) {
2585
- const overrideOptions = options2 ?? {};
2586
- const resolvedOptions = defuOverrideArray(
3018
+ const defaults = {
3019
+ escapeMap: options.escapeMap,
3020
+ staleClassNameFallback: options.staleClassNameFallback,
3021
+ jsArbitraryValueFallback: options.jsArbitraryValueFallback,
3022
+ tailwindcssMajorVersion: options.tailwindcssMajorVersion,
3023
+ arbitraryValues: options.arbitraryValues,
3024
+ jsPreserveClass: options.jsPreserveClass,
3025
+ generateMap: options.generateMap,
3026
+ needEscaped: options.needEscaped,
3027
+ alwaysEscape: options.alwaysEscape,
3028
+ unescapeUnicode: options.unescapeUnicode,
3029
+ babelParserOptions: options.babelParserOptions,
3030
+ ignoreCallExpressionIdentifiers: options.ignoreCallExpressionIdentifiers,
3031
+ ignoreTaggedTemplateExpressionIdentifiers: options.ignoreTaggedTemplateExpressionIdentifiers,
3032
+ uniAppX: options.uniAppX,
3033
+ moduleSpecifierReplacements: options.moduleSpecifierReplacements
3034
+ };
3035
+ const resolvedOptionsByClassNameSet = /* @__PURE__ */ new WeakMap();
3036
+ let resolvedOptionsWithoutClassNameSet;
3037
+ const resolvedOverrideOptions = /* @__PURE__ */ new WeakMap();
3038
+ const resolvedOverrideOptionsByClassNameSet = /* @__PURE__ */ new WeakMap();
3039
+ const resultCache = /* @__PURE__ */ new WeakMap();
3040
+ function resolveDefaultOptions(classNameSet) {
3041
+ if (!classNameSet) {
3042
+ if (!resolvedOptionsWithoutClassNameSet) {
3043
+ resolvedOptionsWithoutClassNameSet = {
3044
+ ...defaults,
3045
+ classNameSet
3046
+ };
3047
+ }
3048
+ return resolvedOptionsWithoutClassNameSet;
3049
+ }
3050
+ const cached = resolvedOptionsByClassNameSet.get(classNameSet);
3051
+ if (cached) {
3052
+ return cached;
3053
+ }
3054
+ const created = {
3055
+ ...defaults,
3056
+ classNameSet
3057
+ };
3058
+ resolvedOptionsByClassNameSet.set(classNameSet, created);
3059
+ return created;
3060
+ }
3061
+ function getCachedJsResult(rawSource, resolvedOptions) {
3062
+ if (!shouldCacheJsResult(rawSource, resolvedOptions)) {
3063
+ return void 0;
3064
+ }
3065
+ const cache = resultCache.get(resolvedOptions);
3066
+ return cache?.get(rawSource);
3067
+ }
3068
+ function setCachedJsResult(rawSource, resolvedOptions, result) {
3069
+ if (!shouldCacheJsResult(rawSource, resolvedOptions) || result.error || result.linked) {
3070
+ return result;
3071
+ }
3072
+ let cache = resultCache.get(resolvedOptions);
3073
+ if (!cache) {
3074
+ cache = /* @__PURE__ */ new Map();
3075
+ resultCache.set(resolvedOptions, cache);
3076
+ }
3077
+ cache.set(rawSource, result);
3078
+ if (cache.size > RESULT_CACHE_LIMIT) {
3079
+ const firstKey = cache.keys().next().value;
3080
+ if (typeof firstKey === "string") {
3081
+ cache.delete(firstKey);
3082
+ }
3083
+ }
3084
+ return result;
3085
+ }
3086
+ function resolveOptions(classNameSet, overrideOptions) {
3087
+ if (!hasDefinedOverrides(overrideOptions)) {
3088
+ return resolveDefaultOptions(classNameSet);
3089
+ }
3090
+ if (!classNameSet) {
3091
+ const cached2 = resolvedOverrideOptions.get(overrideOptions);
3092
+ if (cached2) {
3093
+ return cached2;
3094
+ }
3095
+ const created2 = defuOverrideArray(
3096
+ {
3097
+ ...overrideOptions,
3098
+ classNameSet
3099
+ },
3100
+ defaults
3101
+ );
3102
+ resolvedOverrideOptions.set(overrideOptions, created2);
3103
+ return created2;
3104
+ }
3105
+ let cache = resolvedOverrideOptionsByClassNameSet.get(overrideOptions);
3106
+ if (!cache) {
3107
+ cache = /* @__PURE__ */ new WeakMap();
3108
+ resolvedOverrideOptionsByClassNameSet.set(overrideOptions, cache);
3109
+ }
3110
+ const cached = cache.get(classNameSet);
3111
+ if (cached) {
3112
+ return cached;
3113
+ }
3114
+ const created = defuOverrideArray(
2587
3115
  {
2588
3116
  ...overrideOptions,
2589
3117
  classNameSet
2590
3118
  },
2591
- {
2592
- classNameSet,
2593
- escapeMap,
2594
- staleClassNameFallback,
2595
- jsArbitraryValueFallback,
2596
- tailwindcssMajorVersion,
2597
- arbitraryValues,
2598
- jsPreserveClass,
2599
- generateMap,
2600
- needEscaped,
2601
- alwaysEscape,
2602
- unescapeUnicode,
2603
- babelParserOptions,
2604
- ignoreCallExpressionIdentifiers,
2605
- ignoreTaggedTemplateExpressionIdentifiers,
2606
- uniAppX,
2607
- moduleSpecifierReplacements
2608
- }
3119
+ defaults
2609
3120
  );
2610
- return jsHandler(rawSource, resolvedOptions);
3121
+ cache.set(classNameSet, created);
3122
+ return created;
3123
+ }
3124
+ function handler(rawSource, classNameSet, options2) {
3125
+ const resolvedOptions = resolveOptions(classNameSet, options2);
3126
+ const cached = getCachedJsResult(rawSource, resolvedOptions);
3127
+ if (cached) {
3128
+ return cached;
3129
+ }
3130
+ return setCachedJsResult(rawSource, resolvedOptions, jsHandler(rawSource, resolvedOptions));
2611
3131
  }
2612
3132
  return handler;
2613
3133
  }
@@ -2695,6 +3215,12 @@ function shouldSkipLegacyStringLiteral(path5) {
2695
3215
  );
2696
3216
  }
2697
3217
  function createLegacyTraverseOptions(options, jsTokenUpdater) {
3218
+ const legacyReplaceOptions = {
3219
+ escapeMap: options.escapeMap,
3220
+ classNameSet: options.runtimeSet,
3221
+ needEscaped: true,
3222
+ alwaysEscape: true
3223
+ };
2698
3224
  return {
2699
3225
  StringLiteral(path5) {
2700
3226
  if (shouldSkipLegacyStringLiteral(path5)) {
@@ -2703,12 +3229,7 @@ function createLegacyTraverseOptions(options, jsTokenUpdater) {
2703
3229
  jsTokenUpdater.addToken(
2704
3230
  replaceHandleValue(
2705
3231
  path5,
2706
- {
2707
- escapeMap: options.escapeMap,
2708
- classNameSet: options.runtimeSet,
2709
- needEscaped: true,
2710
- alwaysEscape: true
2711
- }
3232
+ legacyReplaceOptions
2712
3233
  )
2713
3234
  );
2714
3235
  },
@@ -2718,25 +3239,34 @@ function createLegacyTraverseOptions(options, jsTokenUpdater) {
2718
3239
 
2719
3240
  // src/wxml/utils/codegen/legacy-rewriter.ts
2720
3241
  function rewriteLegacyExpression(match, options) {
2721
- const ms = new MagicString2(match);
2722
3242
  const ast = parseExpression(match);
2723
3243
  const jsTokenUpdater = new JsTokenUpdater();
2724
3244
  traverse(ast, createLegacyTraverseOptions(options, jsTokenUpdater));
3245
+ if (jsTokenUpdater.length === 0) {
3246
+ return match;
3247
+ }
3248
+ const ms = new MagicString2(match);
2725
3249
  jsTokenUpdater.updateMagicString(ms);
2726
3250
  return ms.toString();
2727
3251
  }
2728
3252
 
2729
3253
  // src/wxml/utils/codegen.ts
3254
+ var WRAP_EXPRESSION_HANDLER_OPTIONS = Object.freeze({
3255
+ wrapExpression: true
3256
+ });
2730
3257
  function generateCode(match, options = {}) {
2731
3258
  try {
2732
- const { jsHandler: jsHandler2, runtimeSet } = options;
3259
+ const { jsHandler: jsHandler2, runtimeSet, wrapExpression } = options;
2733
3260
  if (jsHandler2 && runtimeSet) {
2734
- const runHandler = (wrap) => jsHandler2(match, runtimeSet, wrap ? { wrapExpression: true } : void 0);
2735
- const initial = runHandler(options.wrapExpression);
2736
- if (!initial.error || options.wrapExpression) {
3261
+ const initial = jsHandler2(
3262
+ match,
3263
+ runtimeSet,
3264
+ wrapExpression ? WRAP_EXPRESSION_HANDLER_OPTIONS : void 0
3265
+ );
3266
+ if (!initial.error || wrapExpression) {
2737
3267
  return initial.code;
2738
3268
  }
2739
- const fallback = runHandler(true);
3269
+ const fallback = jsHandler2(match, runtimeSet, WRAP_EXPRESSION_HANDLER_OPTIONS);
2740
3270
  return fallback.code;
2741
3271
  } else {
2742
3272
  return rewriteLegacyExpression(match, options);
@@ -2952,7 +3482,7 @@ function handleEachClassFragment(ms, tokens, options = {}) {
2952
3482
  previousEnd = token.end;
2953
3483
  }
2954
3484
  if (tokens.length > 0) {
2955
- const lastToken = tokens[tokens.length - 1];
3485
+ const lastToken = tokens.at(-1);
2956
3486
  if (lastToken.end < ms.original.length) {
2957
3487
  updateWhitespaceGap(ms, lastToken.end, ms.original.length, options);
2958
3488
  }
@@ -2960,16 +3490,17 @@ function handleEachClassFragment(ms, tokens, options = {}) {
2960
3490
  }
2961
3491
 
2962
3492
  // src/wxml/utils/template-fragments.ts
2963
- function templateReplacer(original, options = {}) {
3493
+ var sharedTokenizer = new Tokenizer();
3494
+ function templateReplacer(original, options = {}, tokenizer) {
2964
3495
  const ms = new MagicString3(original);
2965
- const tokenizer = new Tokenizer();
2966
- const tokens = tokenizer.run(ms.original);
3496
+ const tok = tokenizer ?? sharedTokenizer;
3497
+ const tokens = tok.run(ms.original);
2967
3498
  handleEachClassFragment(ms, tokens, options);
2968
3499
  return ms.toString();
2969
3500
  }
2970
3501
 
2971
3502
  // src/wxml/utils/custom-template.ts
2972
- async function customTemplateHandler(rawSource, options) {
3503
+ async function customTemplateHandler(rawSource, options, cachedMatcher) {
2973
3504
  const {
2974
3505
  customAttributesEntities = [],
2975
3506
  disabledDefaultTemplateHandler,
@@ -2977,10 +3508,41 @@ async function customTemplateHandler(rawSource, options) {
2977
3508
  runtimeSet,
2978
3509
  jsHandler: jsHandler2
2979
3510
  } = options ?? {};
2980
- const matchCustomAttribute = createAttributeMatcher(customAttributesEntities);
2981
- const s = new MagicString4(rawSource);
3511
+ const matchCustomAttribute = cachedMatcher ?? createAttributeMatcher(customAttributesEntities);
3512
+ const defaultTemplateHandlerEnabled = !disabledDefaultTemplateHandler;
3513
+ let replaceOptions;
3514
+ let cachedQuote;
3515
+ let s;
2982
3516
  let tag = "";
2983
- const wxsArray = [];
3517
+ let wxsArray;
3518
+ function getMagicString() {
3519
+ if (!s) {
3520
+ s = new MagicString4(rawSource);
3521
+ }
3522
+ return s;
3523
+ }
3524
+ function getReplaceOptions(quote) {
3525
+ if (!replaceOptions) {
3526
+ replaceOptions = {
3527
+ ...options,
3528
+ quote
3529
+ };
3530
+ cachedQuote = quote;
3531
+ return replaceOptions;
3532
+ }
3533
+ if (cachedQuote !== quote) {
3534
+ replaceOptions.quote = quote;
3535
+ cachedQuote = quote;
3536
+ }
3537
+ return replaceOptions;
3538
+ }
3539
+ function isDefaultTemplateAttribute(name) {
3540
+ if (name === "class" || name === "hover-class" || name === "virtualhostclass") {
3541
+ return true;
3542
+ }
3543
+ const lowerName = name.toLowerCase();
3544
+ return lowerName === "class" || lowerName === "hover-class" || lowerName === "virtualhostclass";
3545
+ }
2984
3546
  const parser = new Parser(
2985
3547
  {
2986
3548
  onopentagname(name) {
@@ -2990,28 +3552,25 @@ async function customTemplateHandler(rawSource, options) {
2990
3552
  if (!value) {
2991
3553
  return;
2992
3554
  }
2993
- const lowerName = name.toLowerCase();
2994
- const shouldHandleDefault = !disabledDefaultTemplateHandler && (lowerName === "class" || lowerName === "hover-class" || lowerName === "virtualhostclass");
3555
+ const shouldHandleDefault = defaultTemplateHandlerEnabled && isDefaultTemplateAttribute(name);
2995
3556
  const shouldHandleCustom = matchCustomAttribute?.(tag, name) ?? false;
2996
3557
  if (!shouldHandleDefault && !shouldHandleCustom) {
2997
3558
  return;
2998
3559
  }
2999
- s.update(
3560
+ getMagicString().update(
3000
3561
  parser.startIndex + name.length + 2,
3001
3562
  // !important
3002
3563
  // htmlparser2 9.0.0: parser.endIndex
3003
3564
  // htmlparser2 9.1.0: parser.endIndex - 1
3004
3565
  // https://github.com/sonofmagic/weapp-tailwindcss/issues/269
3005
3566
  parser.endIndex - 1,
3006
- templateReplacer(value, {
3007
- ...options,
3008
- quote
3009
- })
3567
+ templateReplacer(value, getReplaceOptions(quote))
3010
3568
  );
3011
3569
  },
3012
3570
  ontext(data) {
3013
3571
  if (inlineWxs && tag === "wxs") {
3014
- wxsArray.push({
3572
+ ;
3573
+ (wxsArray ?? (wxsArray = [])).push({
3015
3574
  data,
3016
3575
  endIndex: parser.endIndex + 1,
3017
3576
  startIndex: parser.startIndex
@@ -3026,19 +3585,38 @@ async function customTemplateHandler(rawSource, options) {
3026
3585
  xmlMode: true
3027
3586
  }
3028
3587
  );
3029
- parser.write(s.original);
3588
+ parser.write(rawSource);
3030
3589
  parser.end();
3031
- for (const { data, endIndex, startIndex } of wxsArray) {
3590
+ for (const { data, endIndex, startIndex } of wxsArray ?? []) {
3032
3591
  const { code } = await jsHandler2(data, runtimeSet);
3033
- s.update(startIndex, endIndex, code);
3592
+ if (code !== data) {
3593
+ getMagicString().update(startIndex, endIndex, code);
3594
+ }
3034
3595
  }
3035
- return s.toString();
3596
+ return s?.toString() ?? rawSource;
3036
3597
  }
3037
3598
 
3038
3599
  // src/wxml/utils.ts
3039
3600
  function createTemplateHandler(options = {}) {
3040
- return (rawSource, opt = {}) => {
3041
- return customTemplateHandler(rawSource, defuOverrideArray(opt, options));
3601
+ const cachedMatcher = createAttributeMatcher(
3602
+ options.customAttributesEntities
3603
+ );
3604
+ const defaultOptions = options;
3605
+ let cachedRuntimeSet;
3606
+ let cachedOptionsWithRuntimeSet;
3607
+ return (rawSource, opt) => {
3608
+ const runtimeSet = opt?.runtimeSet;
3609
+ if (runtimeSet === void 0) {
3610
+ return customTemplateHandler(rawSource, defaultOptions, cachedMatcher);
3611
+ }
3612
+ if (cachedRuntimeSet !== runtimeSet || !cachedOptionsWithRuntimeSet) {
3613
+ cachedRuntimeSet = runtimeSet;
3614
+ cachedOptionsWithRuntimeSet = {
3615
+ ...defaultOptions,
3616
+ runtimeSet
3617
+ };
3618
+ }
3619
+ return customTemplateHandler(rawSource, cachedOptionsWithRuntimeSet, cachedMatcher);
3042
3620
  };
3043
3621
  }
3044
3622
 
@@ -3253,6 +3831,8 @@ export {
3253
3831
  createPatchTargetRecorder,
3254
3832
  logTailwindcssTarget,
3255
3833
  toCustomAttributesEntities,
3834
+ traverse,
3835
+ babelParse,
3256
3836
  replaceWxml,
3257
3837
  createAttributeMatcher,
3258
3838
  generateCode,