weapp-tailwindcss 5.0.0-next.11 → 5.0.0-next.14

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 (77) hide show
  1. package/dist/{bundle-state-BrtFgX-A.mjs → bundle-state-BOBbxYzQ.mjs} +3 -2
  2. package/dist/{bundle-state-BRkhpjio.js → bundle-state-CxtGmT4t.js} +3 -2
  3. package/dist/bundlers/shared/css-cleanup.d.ts +6 -1
  4. package/dist/bundlers/shared/generator-css/source-files.d.ts +9 -6
  5. package/dist/bundlers/shared/generator-css/source-resolver.d.ts +16 -2
  6. package/dist/bundlers/shared/generator-css.d.ts +4 -0
  7. package/dist/bundlers/shared/hmr-timing.d.ts +18 -1
  8. package/dist/bundlers/vite/bundle-state.d.ts +1 -0
  9. package/dist/bundlers/vite/css-finalizer.d.ts +2 -0
  10. package/dist/bundlers/vite/generate-bundle/css-handler-options.d.ts +5 -1
  11. package/dist/bundlers/vite/generate-bundle/css-share-scope.d.ts +1 -0
  12. package/dist/bundlers/vite/generate-bundle.d.ts +8 -1
  13. package/dist/bundlers/vite/incremental-runtime-class-set.d.ts +1 -0
  14. package/dist/bundlers/vite/runtime-class-set.d.ts +4 -1
  15. package/dist/bundlers/vite/source-candidates.d.ts +11 -0
  16. package/dist/bundlers/vite/source-scan.d.ts +18 -1
  17. package/dist/bundlers/vite/static-config-content.d.ts +5 -0
  18. package/dist/bundlers/webpack/BaseUnifiedPlugin/shared.d.ts +5 -0
  19. package/dist/cli.js +486 -18
  20. package/dist/cli.mjs +484 -17
  21. package/dist/core.js +1 -1
  22. package/dist/core.mjs +1 -1
  23. package/dist/defaults-B1igPF_e.mjs +150 -0
  24. package/dist/defaults-IHhYxNeU.js +193 -0
  25. package/dist/defaults.js +6 -150
  26. package/dist/defaults.mjs +1 -143
  27. package/dist/generator-C9H44wEF.mjs +32 -0
  28. package/dist/generator-CRORPkpW.js +55 -0
  29. package/dist/generator.js +12 -11
  30. package/dist/generator.mjs +2 -1
  31. package/dist/gulp.js +49 -13
  32. package/dist/gulp.mjs +46 -10
  33. package/dist/{incremental-runtime-class-set-CBMefNHQ.js → incremental-runtime-class-set-B4EXHHii.js} +512 -103
  34. package/dist/{incremental-runtime-class-set-DaS2yw5c.mjs → incremental-runtime-class-set-DoKrMrEh.mjs} +491 -88
  35. package/dist/index.js +4 -4
  36. package/dist/index.mjs +4 -4
  37. package/dist/js/babel/cache-options.d.ts +3 -0
  38. package/dist/js/babel/parse.d.ts +7 -4
  39. package/dist/{postcss-xZDiTRII.mjs → postcss-BFxu5_cs.mjs} +19 -8
  40. package/dist/{postcss-Bs-RbNzK.js → postcss-CZE8k8oP.js} +59 -53
  41. package/dist/{postcss-BdcRlSpp.js → postcss-Vqn4IlO3.js} +30 -19
  42. package/dist/postcss.js +1 -1
  43. package/dist/postcss.mjs +1 -1
  44. package/dist/{precheck-D5eEdqeH.js → precheck-CZHcFX8k.js} +65 -25
  45. package/dist/{precheck-DtBGFS-n.mjs → precheck-DCresEiu.mjs} +57 -17
  46. package/dist/presets.js +4 -4
  47. package/dist/presets.mjs +2 -2
  48. package/dist/source-candidates-BvbvkIPP.js +274 -0
  49. package/dist/source-candidates-CK70jGo7.mjs +259 -0
  50. package/dist/tailwindcss/runtime/cache.d.ts +1 -0
  51. package/dist/tailwindcss/v3-engine/types.d.ts +3 -0
  52. package/dist/tailwindcss/v4-engine/types.d.ts +8 -0
  53. package/dist/{tailwindcss-DGM8lHUj.mjs → tailwindcss-7k0LFa12.mjs} +8 -3
  54. package/dist/{tailwindcss-B78nj6n7.js → tailwindcss-CN0K7G-l.js} +20 -15
  55. package/dist/types/index.d.ts +7 -1
  56. package/dist/types/user-defined-options/general.d.ts +2 -0
  57. package/dist/v3-engine-D61eilBl.mjs +3208 -0
  58. package/dist/v3-engine-DwV1E6rX.js +3461 -0
  59. package/dist/{vite-C8S1wfyQ.mjs → vite-DCmKrTo0.mjs} +378 -540
  60. package/dist/{vite-BEj9JOOA.js → vite-DJ0P9Hrp.js} +383 -548
  61. package/dist/vite.js +1 -1
  62. package/dist/vite.mjs +1 -1
  63. package/dist/weapp-tw-css-import-rewrite-loader.js +29 -9
  64. package/dist/weapp-tw-runtime-classset-loader.js +1 -1
  65. package/dist/{webpack-Dm1IXTIh.js → webpack-8y4NOMnT.js} +39 -22
  66. package/dist/{webpack-ZGIKKpFf.mjs → webpack-CbO4jjkH.mjs} +35 -18
  67. package/dist/webpack.js +1 -1
  68. package/dist/webpack.mjs +1 -1
  69. package/package.json +3 -3
  70. package/dist/cache-B_9E7FxF.js +0 -517
  71. package/dist/cache-DEDxBMIw.mjs +0 -443
  72. package/dist/generator-CahkD2vq.mjs +0 -1469
  73. package/dist/generator-Ck1Dd1V0.js +0 -1568
  74. package/dist/runtime-patch-CqB-A4zA.js +0 -85
  75. package/dist/runtime-patch-DGKsVkiG.mjs +0 -71
  76. package/dist/source-scan-CIVTa3Cj.js +0 -297
  77. package/dist/source-scan-CJ0y0XBj.mjs +0 -258
@@ -1,9 +1,9 @@
1
1
  const require_chunk = require("./chunk-8l464Juk.js");
2
- const require_cache = require("./cache-B_9E7FxF.js");
3
- const require_runtime_patch = require("./runtime-patch-CqB-A4zA.js");
4
- const require_generator = require("./generator-Ck1Dd1V0.js");
5
- const require_precheck = require("./precheck-D5eEdqeH.js");
6
- const require_tailwindcss = require("./tailwindcss-B78nj6n7.js");
2
+ const require_v3_engine = require("./v3-engine-DwV1E6rX.js");
3
+ const require_generator = require("./generator-CRORPkpW.js");
4
+ const require_precheck = require("./precheck-CZHcFX8k.js");
5
+ const require_tailwindcss = require("./tailwindcss-CN0K7G-l.js");
6
+ let node_fs = require("node:fs");
7
7
  let postcss = require("postcss");
8
8
  postcss = require_chunk.__toESM(postcss);
9
9
  let node_path = require("node:path");
@@ -11,7 +11,6 @@ node_path = require_chunk.__toESM(node_path);
11
11
  let node_process = require("node:process");
12
12
  node_process = require_chunk.__toESM(node_process);
13
13
  let tailwindcss_patch = require("tailwindcss-patch");
14
- let node_fs = require("node:fs");
15
14
  //#region src/bundlers/shared/generator-css/markers.ts
16
15
  const TAILWIND_V4_BANNER_RE = /\/\*!\s*tailwindcss v4\./;
17
16
  const TAILWIND_GENERATED_CSS_MARKER_RE = /\/\*!\s*tailwindcss v|@property\s+--tw-|--tw-|:not\(#\\#\)|\.[^,{]*(?:\\:|\\\[|\\#)|(?::host|page|\.tw-root|wx-root-portal-content)[^{]*\{[^}]*--(?:color|spacing|text|font-weight|radius)-/;
@@ -123,7 +122,7 @@ function normalizeTailwindImportAtRules(root, options = {}) {
123
122
  function normalizeTailwindDirectiveLine(line, options = {}) {
124
123
  if (!options.importFallback || !line.trimStart().startsWith("@import")) return line;
125
124
  const request = parseImportRequest(line.trimStart().replace(/^@import\b/, ""));
126
- if (!isWeappTailwindcssImportRequest(request)) return line;
125
+ if (!request || !isWeappTailwindcssImportRequest(request)) return line;
127
126
  return replaceImportRequest(line, request, request.replace(/^weapp-tailwindcss/, "tailwindcss"));
128
127
  }
129
128
  function extractTailwindDirectiveLines(rawSource, options = {}) {
@@ -570,6 +569,7 @@ const PREFLIGHT_RESET_PROPS = new Set([
570
569
  "margin",
571
570
  "padding"
572
571
  ]);
572
+ const CONTENT_VAR_RE = /var\(\s*--tw-content\b/;
573
573
  function isMiniProgramThemeScopeSelector$1(selectors) {
574
574
  return selectors.length > 0 && selectors.every((selector) => MINI_PROGRAM_THEME_SCOPE_SELECTORS$1.has(selector));
575
575
  }
@@ -602,6 +602,16 @@ function hasContentInitDeclaration(rule) {
602
602
  });
603
603
  return hasContentInit;
604
604
  }
605
+ function isEmptyContentInitDeclaration(decl) {
606
+ return decl.prop === "--tw-content" && (decl.value === "\"\"" || decl.value === "''");
607
+ }
608
+ function usesTwContentVariable(root) {
609
+ let used = false;
610
+ root.walkDecls((decl) => {
611
+ if (CONTENT_VAR_RE.test(decl.value)) used = true;
612
+ });
613
+ return used;
614
+ }
605
615
  function isTailwindPreflightRule(node) {
606
616
  if (node.type !== "rule" || node.parent?.type !== "root") return false;
607
617
  const rule = node;
@@ -620,7 +630,7 @@ function createPseudoContentInitRule() {
620
630
  });
621
631
  return rule;
622
632
  }
623
- function collectPreflightRules(root) {
633
+ function collectPreflightRules(root, options = {}) {
624
634
  const preflightNodes = [];
625
635
  let hasContentInit = false;
626
636
  for (const node of root.nodes ?? []) if (isTailwindPreflightRule(node)) {
@@ -629,20 +639,34 @@ function collectPreflightRules(root) {
629
639
  }
630
640
  if (preflightNodes.length === 0) return [];
631
641
  const clonedPreflightRules = preflightNodes.map((node) => node.clone());
632
- const contentInitRules = clonedPreflightRules.filter((rule) => hasContentInitDeclaration(rule));
642
+ const contentInitRules = options.preservePseudoContentInit ? clonedPreflightRules.filter((rule) => hasContentInitDeclaration(rule)) : [];
633
643
  const otherPreflightRules = clonedPreflightRules.filter((rule) => !hasContentInitDeclaration(rule));
634
- const preflightRules = hasContentInit ? [...contentInitRules, ...otherPreflightRules] : [createPseudoContentInitRule(), ...otherPreflightRules];
644
+ const preflightRules = hasContentInit ? [...contentInitRules, ...otherPreflightRules] : [...options.preservePseudoContentInit ? [createPseudoContentInitRule()] : [], ...otherPreflightRules];
635
645
  for (const node of preflightNodes) node.remove();
636
646
  return preflightRules;
637
647
  }
638
- function collectThemeVariableRule(root) {
648
+ function createPreflightResetRule(cssPreflight) {
649
+ if (!cssPreflight || typeof cssPreflight !== "object") return;
650
+ const rule = postcss.default.rule({ selector: "view,text,:after,:before" });
651
+ for (const [prop, value] of Object.entries(cssPreflight)) {
652
+ if (value === false) continue;
653
+ rule.append({
654
+ prop,
655
+ value: value.toString()
656
+ });
657
+ }
658
+ return rule.nodes?.length ? rule : void 0;
659
+ }
660
+ function collectThemeVariableRule(root, options = {}) {
639
661
  const themeRules = [];
640
662
  const declarations = /* @__PURE__ */ new Map();
663
+ const shouldPreserveContentInit = options.preservePseudoContentInit || usesTwContentVariable(root);
641
664
  for (const node of root.nodes ?? []) {
642
665
  if (!isMiniProgramThemeVariableRule(node)) continue;
643
666
  themeRules.push(node);
644
667
  node.walkDecls((decl) => {
645
668
  if (isDisplayP3Declaration(decl)) return;
669
+ if (!shouldPreserveContentInit && isEmptyContentInitDeclaration(decl)) return;
646
670
  declarations.set(decl.prop, decl.clone());
647
671
  });
648
672
  }
@@ -672,8 +696,8 @@ function insertHoistedRules(root, rules) {
672
696
  if (topDirectiveTail) topDirectiveTail.after(rules);
673
697
  else root.prepend(rules);
674
698
  }
675
- function finalizeMiniProgramCssRoot(root) {
676
- require_generator.removeUnsupportedCascadeLayers(root);
699
+ function finalizeMiniProgramCssRoot(root, options = {}) {
700
+ require_v3_engine.removeUnsupportedCascadeLayers(root);
677
701
  unwrapTailwindSourceMedia(root);
678
702
  root.walkAtRules("property", (atRule) => {
679
703
  atRule.remove();
@@ -681,8 +705,12 @@ function finalizeMiniProgramCssRoot(root) {
681
705
  removeSpecificityPlaceholders(root);
682
706
  removeUnsupportedBrowserSelectors(root);
683
707
  removeDisplayP3Declarations(root);
684
- const preflightRules = collectPreflightRules(root);
685
- const themeRule = collectThemeVariableRule(root);
708
+ const preflightRules = collectPreflightRules(root, options);
709
+ if (preflightRules.length === 0) {
710
+ const resetRule = createPreflightResetRule(options.cssPreflight);
711
+ if (resetRule) preflightRules.push(resetRule);
712
+ }
713
+ const themeRule = collectThemeVariableRule(root, options);
686
714
  insertHoistedRules(root, themeRule ? [...preflightRules, themeRule] : preflightRules);
687
715
  }
688
716
  function unwrapTailwindSourceMedia(root) {
@@ -690,11 +718,11 @@ function unwrapTailwindSourceMedia(root) {
690
718
  if (atRule.params.startsWith("source(") && atRule.nodes && atRule.nodes.length > 0) atRule.replaceWith(...atRule.nodes);
691
719
  });
692
720
  }
693
- function finalizeMiniProgramCss(css) {
721
+ function finalizeMiniProgramCss(css, options = {}) {
694
722
  const cleanedCss = removeUnsupportedMiniProgramAtRules(css);
695
723
  try {
696
724
  const root = postcss.default.parse(cleanedCss);
697
- finalizeMiniProgramCssRoot(root);
725
+ finalizeMiniProgramCssRoot(root, options);
698
726
  return root.toString();
699
727
  } catch {
700
728
  return cleanedCss;
@@ -710,6 +738,15 @@ const MINI_PROGRAM_THEME_SCOPE_SELECTORS = new Set([
710
738
  "wx-root-portal-content"
711
739
  ]);
712
740
  const SPECIFICITY_PLACEHOLDER_RE = /:not\(#(?:\\#|n)\)/g;
741
+ const SELECTOR_CACHE_LIMIT = 64;
742
+ const generatedSelectorCache = /* @__PURE__ */ new Map();
743
+ function setGeneratedSelectorCache(css, selectors) {
744
+ if (generatedSelectorCache.size >= SELECTOR_CACHE_LIMIT) {
745
+ const firstKey = generatedSelectorCache.keys().next().value;
746
+ if (firstKey !== void 0) generatedSelectorCache.delete(firstKey);
747
+ }
748
+ generatedSelectorCache.set(css, selectors);
749
+ }
713
750
  function normalizeCompatSelector(selector) {
714
751
  return selector.replace(SPECIFICITY_PLACEHOLDER_RE, "").replace(/\s+/g, " ").trim();
715
752
  }
@@ -805,6 +842,8 @@ function isPseudoContentInitRule(rule) {
805
842
  return hasDeclaration && onlyContentVariable;
806
843
  }
807
844
  function collectGeneratedSelectors(css) {
845
+ const cached = generatedSelectorCache.get(css);
846
+ if (cached) return cached;
808
847
  const selectors = /* @__PURE__ */ new Set();
809
848
  try {
810
849
  postcss.default.parse(css).walkRules((rule) => {
@@ -814,8 +853,30 @@ function collectGeneratedSelectors(css) {
814
853
  } catch {
815
854
  return selectors;
816
855
  }
856
+ setGeneratedSelectorCache(css, selectors);
817
857
  return selectors;
818
858
  }
859
+ function collectGeneratedDeclarationPropsBySelector(generatedCss, selectors) {
860
+ const propsBySelector = /* @__PURE__ */ new Map();
861
+ try {
862
+ postcss.default.parse(generatedCss).walkRules((rule) => {
863
+ const matchedSelectors = getRuleCompatSelectorKeys(rule).filter((selector) => selectors.has(selector));
864
+ if (matchedSelectors.length === 0) return;
865
+ const props = /* @__PURE__ */ new Set();
866
+ rule.walkDecls((decl) => {
867
+ props.add(decl.prop);
868
+ });
869
+ for (const selector of matchedSelectors) {
870
+ const existing = propsBySelector.get(selector);
871
+ if (existing) for (const prop of props) existing.add(prop);
872
+ else propsBySelector.set(selector, new Set(props));
873
+ }
874
+ });
875
+ } catch {
876
+ return propsBySelector;
877
+ }
878
+ return propsBySelector;
879
+ }
819
880
  function removeGeneratedSelectorCompatCss(css, generatedCss) {
820
881
  const generatedSelectors = collectGeneratedSelectors(generatedCss);
821
882
  if (generatedSelectors.size === 0) return css;
@@ -845,23 +906,27 @@ function removeGeneratedSelectorCompatCss(css, generatedCss) {
845
906
  function collectDedupedPostTransformCompatCss(css, generatedCss) {
846
907
  const generatedSelectors = collectGeneratedSelectors(generatedCss);
847
908
  if (generatedSelectors.size === 0) return css;
909
+ const generatedDeclarationPropsBySelector = collectGeneratedDeclarationPropsBySelector(generatedCss, generatedSelectors);
848
910
  const preservedNodes = [];
849
911
  try {
850
912
  const root = postcss.default.parse(css);
851
913
  root.each((node) => {
852
- if (node.type === "rule" && getRuleCompatSelectorKeys(node).some((selector) => generatedSelectors.has(selector))) {
914
+ if (node.type === "rule") {
915
+ const nodeSelectors = getRuleCompatSelectorKeys(node);
916
+ if (!nodeSelectors.some((selector) => generatedSelectors.has(selector))) {
917
+ preservedNodes.push(node.clone());
918
+ return;
919
+ }
853
920
  if (isCustomPropertyOnlyRule(node) && !isPseudoContentInitRule(node) && !hasUtilityClassSelector(node.selector)) {
854
921
  const declarationProps = /* @__PURE__ */ new Set();
855
922
  node.walkDecls((decl) => {
856
923
  declarationProps.add(decl.prop);
857
924
  });
858
- postcss.default.parse(generatedCss).walkRules((rule) => {
859
- const nodeSelectors = new Set(getRuleCompatSelectorKeys(node));
860
- if (!getRuleCompatSelectorKeys(rule).some((selector) => nodeSelectors.has(selector))) return;
861
- rule.walkDecls((decl) => {
862
- declarationProps.delete(decl.prop);
863
- });
864
- });
925
+ for (const selector of nodeSelectors) {
926
+ const generatedProps = generatedDeclarationPropsBySelector.get(selector);
927
+ if (!generatedProps) continue;
928
+ for (const prop of generatedProps) declarationProps.delete(prop);
929
+ }
865
930
  const nextRule = node.clone();
866
931
  nextRule.walkDecls((decl) => {
867
932
  if (!declarationProps.has(decl.prop)) decl.remove();
@@ -929,28 +994,24 @@ function createSourceStylePathCandidates(file, sourceOptions) {
929
994
  sourceOptions.cwd,
930
995
  node_process.default.cwd()
931
996
  ].filter((item) => typeof item === "string" && item.length > 0);
997
+ const outputRoots = [sourceOptions.outputRoot].filter((item) => typeof item === "string" && item.length > 0);
932
998
  const strippedFile = stripStyleExtension(file);
933
999
  const relativeFiles = /* @__PURE__ */ new Set();
934
- if (node_path.default.isAbsolute(strippedFile)) for (const base of bases) {
935
- const relative = node_path.default.relative(base, strippedFile);
936
- if (!relative || relative.startsWith("..") || node_path.default.isAbsolute(relative)) continue;
937
- relativeFiles.add(relative);
938
- const parts = relative.split(node_path.default.sep).filter(Boolean);
939
- if (parts.length > 1) {
940
- relativeFiles.add(parts.slice(1).join(node_path.default.sep));
941
- const distIndex = parts.lastIndexOf("dist");
942
- if (distIndex >= 0 && distIndex < parts.length - 1) relativeFiles.add([...parts.slice(0, distIndex), ...parts.slice(distIndex + 1)].join(node_path.default.sep));
1000
+ const addOutputRelativePath = (absoluteFile) => {
1001
+ for (const outputRoot of outputRoots) {
1002
+ const relative = node_path.default.relative(outputRoot, absoluteFile);
1003
+ if (!relative || relative.startsWith("..") || node_path.default.isAbsolute(relative)) continue;
1004
+ relativeFiles.add(relative);
943
1005
  }
944
- }
945
- else {
946
- relativeFiles.add(strippedFile);
947
- const parts = strippedFile.split(/[\\/]/).filter(Boolean);
948
- if (parts.length > 1) {
949
- relativeFiles.add(parts.slice(1).join(node_path.default.sep));
950
- const distIndex = parts.lastIndexOf("dist");
951
- if (distIndex >= 0 && distIndex < parts.length - 1) relativeFiles.add([...parts.slice(0, distIndex), ...parts.slice(distIndex + 1)].join(node_path.default.sep));
1006
+ };
1007
+ if (node_path.default.isAbsolute(strippedFile)) {
1008
+ addOutputRelativePath(strippedFile);
1009
+ for (const base of bases) {
1010
+ const relative = node_path.default.relative(base, strippedFile);
1011
+ if (!relative || relative.startsWith("..") || node_path.default.isAbsolute(relative)) continue;
1012
+ relativeFiles.add(relative);
952
1013
  }
953
- }
1014
+ } else relativeFiles.add(strippedFile);
954
1015
  const candidates = /* @__PURE__ */ new Set();
955
1016
  for (const relativeFile of relativeFiles) {
956
1017
  if (!relativeFile || node_path.default.isAbsolute(relativeFile)) continue;
@@ -980,7 +1041,10 @@ function resolveSourceSideCssEntrySource(file, sourceOptions, resolveOptions = {
980
1041
  const source = (0, node_fs.readFileSync)(sourceFile, "utf8");
981
1042
  for (const styleSource of extractStyleDirectiveSources(source)) {
982
1043
  const cssEntrySource = resolveCssEntrySource(styleSource, node_path.default.dirname(sourceFile), resolveOptions);
983
- if (cssEntrySource) return cssEntrySource;
1044
+ if (cssEntrySource) return {
1045
+ ...cssEntrySource,
1046
+ file: sourceFile
1047
+ };
984
1048
  }
985
1049
  } catch {
986
1050
  continue;
@@ -993,6 +1057,25 @@ function resolvePostcssFromOption(cssHandlerOptions) {
993
1057
  const from = cssHandlerOptions.postcssOptions?.options?.from;
994
1058
  return typeof from === "string" && from.length > 0 ? from : void 0;
995
1059
  }
1060
+ function resolvePostcssSourceFile(cssHandlerOptions) {
1061
+ const from = resolvePostcssFromOption(cssHandlerOptions);
1062
+ if (!from || !node_path.default.isAbsolute(from)) return;
1063
+ return from.replace(/[?#].*$/, "");
1064
+ }
1065
+ function resolveCssHandlerSourceOptions(cssHandlerOptions) {
1066
+ return cssHandlerOptions.sourceOptions;
1067
+ }
1068
+ function createSingleTailwindV4SourceOptions(sourceOptions, options) {
1069
+ return require_v3_engine.omitUndefined({
1070
+ projectRoot: sourceOptions.projectRoot,
1071
+ baseFallbacks: sourceOptions.baseFallbacks,
1072
+ sources: sourceOptions.sources,
1073
+ packageName: sourceOptions.packageName,
1074
+ outputRoot: sourceOptions.outputRoot,
1075
+ base: options.base,
1076
+ css: options.css
1077
+ });
1078
+ }
996
1079
  function resolveCssSourceBase(file, cssHandlerOptions) {
997
1080
  const normalized = (resolvePostcssFromOption(cssHandlerOptions) ?? file).replace(/[?#].*$/, "");
998
1081
  return node_path.default.dirname(node_path.default.resolve(normalized));
@@ -1023,7 +1106,10 @@ function canResolveSourceSideCssEntry(file, cssHandlerOptions) {
1023
1106
  return true;
1024
1107
  }
1025
1108
  function shouldResolveSourceSideCssEntry(rawSource) {
1026
- return rawSource.includes("@apply");
1109
+ return rawSource.includes("@apply") || hasTailwindGeneratedCss(rawSource) || hasTailwindGeneratedCssMarkers(rawSource);
1110
+ }
1111
+ function shouldPreferTailwindV3SourceSideEntry(rawSource, sourceSideEntrySource) {
1112
+ return Boolean(sourceSideEntrySource) && !hasTailwindSourceDirectives(rawSource, { importFallback: true });
1027
1113
  }
1028
1114
  function normalizeCssSourceForCompare(css) {
1029
1115
  return stripGeneratorPlaceholderMarkers(stripTailwindBanners(css)).trim();
@@ -1032,6 +1118,27 @@ function getOutputFileStem(file) {
1032
1118
  const normalized = file.replace(/[?#].*$/, "");
1033
1119
  return node_path.default.basename(normalized, node_path.default.extname(normalized));
1034
1120
  }
1121
+ function getOutputFileWithoutExtension(file) {
1122
+ const normalized = file.replace(/[?#].*$/, "");
1123
+ const ext = node_path.default.extname(normalized);
1124
+ return ext ? normalized.slice(0, -ext.length) : normalized;
1125
+ }
1126
+ function normalizeMatchPath(file) {
1127
+ return file.split(node_path.default.sep).join("/");
1128
+ }
1129
+ function stripKnownBuildRootPrefix(file) {
1130
+ const segments = normalizeMatchPath(file).split("/");
1131
+ const knownRoots = new Set(["dist", "src"]);
1132
+ for (let index = segments.length - 1; index >= 0; index--) if (knownRoots.has(segments[index])) return segments.slice(index + 1).join("/");
1133
+ return segments.join("/");
1134
+ }
1135
+ function isMatchingTailwindV4CssSourceFile(file, cssSourceFile) {
1136
+ const outputBase = normalizeMatchPath(getOutputFileWithoutExtension(node_path.default.resolve(file)));
1137
+ const sourceBase = normalizeMatchPath(getOutputFileWithoutExtension(node_path.default.resolve(cssSourceFile)));
1138
+ const outputRelativeBase = stripKnownBuildRootPrefix(outputBase);
1139
+ const sourceRelativeBase = stripKnownBuildRootPrefix(sourceBase);
1140
+ return outputBase === sourceBase || outputBase.endsWith(`/${sourceBase}`) || sourceBase.endsWith(`/${outputBase}`) || outputRelativeBase.length > 0 && outputRelativeBase === sourceRelativeBase;
1141
+ }
1035
1142
  function resolveMatchingTailwindV4CssEntry(rawSource, file, sourceOptions) {
1036
1143
  const cssEntries = sourceOptions.cssEntries;
1037
1144
  if (!cssEntries?.length) return;
@@ -1047,14 +1154,28 @@ function resolveMatchingTailwindV4CssEntry(rawSource, file, sourceOptions) {
1047
1154
  }
1048
1155
  });
1049
1156
  if (!matchingEntry) return;
1050
- return require_generator.resolveTailwindV4Source({
1051
- ...require_cache.omitUndefined(sourceOptions),
1157
+ return require_v3_engine.resolveTailwindV4Source({
1158
+ ...require_v3_engine.omitUndefined(sourceOptions),
1052
1159
  cssEntries: [matchingEntry]
1053
1160
  });
1054
1161
  }
1162
+ async function resolveMatchingTailwindV4CssSource(rawSource, file, cssHandlerOptions, sourceOptions) {
1163
+ const cssSources = sourceOptions.cssSources;
1164
+ if (!cssSources?.length) return;
1165
+ const normalizedRawSource = normalizeCssSourceForCompare(rawSource);
1166
+ const sourceFile = resolvePostcssSourceFile(cssHandlerOptions);
1167
+ const matchingSource = cssSources.find((cssSource) => {
1168
+ if (typeof cssSource.css !== "string" || cssSource.css.length === 0) return false;
1169
+ if (sourceFile && typeof cssSource.file === "string" && node_path.default.resolve(sourceFile) === node_path.default.resolve(cssSource.file)) return true;
1170
+ if (typeof cssSource.file === "string" && isMatchingTailwindV4CssSourceFile(file, cssSource.file)) return true;
1171
+ return normalizeCssSourceForCompare(cssSource.css) === normalizedRawSource;
1172
+ });
1173
+ if (!matchingSource) return;
1174
+ return resolveSingleTailwindV4CssSource(matchingSource, sourceOptions);
1175
+ }
1055
1176
  function tryResolveTailwindV4SourceOptions(runtimeState) {
1056
1177
  try {
1057
- return require_generator.resolveTailwindV4SourceOptionsFromPatcher(runtimeState.twPatcher);
1178
+ return require_v3_engine.resolveTailwindV4SourceOptionsFromPatcher(runtimeState.twPatcher);
1058
1179
  } catch {
1059
1180
  return;
1060
1181
  }
@@ -1062,26 +1183,119 @@ function tryResolveTailwindV4SourceOptions(runtimeState) {
1062
1183
  function hasConfiguredTailwindV4CssSource(sourceOptions) {
1063
1184
  return Boolean(sourceOptions?.css) || Boolean(sourceOptions?.cssSources?.length);
1064
1185
  }
1186
+ function resolveTailwindV4CssSourceBase(cssSource, fallbackBase) {
1187
+ if (typeof cssSource.base === "string" && cssSource.base.length > 0) return cssSource.base;
1188
+ if (typeof cssSource.file === "string" && cssSource.file.length > 0) return node_path.default.dirname(cssSource.file);
1189
+ return fallbackBase;
1190
+ }
1191
+ async function resolveSingleTailwindV4CssSource(cssSource, sourceOptions) {
1192
+ const source = await require_v3_engine.resolveTailwindV4Source({
1193
+ ...require_v3_engine.omitUndefined(sourceOptions),
1194
+ cssSources: [cssSource]
1195
+ });
1196
+ const sourceBaseFallback = sourceOptions.base ?? sourceOptions.projectRoot ?? node_process.default.cwd();
1197
+ return withGeneratorSourceMetadata(source, {
1198
+ matchedCssSourceFile: typeof cssSource.file === "string" ? cssSource.file : void 0,
1199
+ sourceBase: resolveTailwindV4CssSourceBase(cssSource, sourceBaseFallback),
1200
+ sourceCss: cssSource.css
1201
+ });
1202
+ }
1203
+ async function resolveTailwindV4CssSourceEntries(cssSource, sourceOptions) {
1204
+ if (typeof cssSource.css !== "string" || cssSource.css.length === 0) return;
1205
+ const sourceBase = resolveTailwindV4CssSourceBase(cssSource, sourceOptions.base ?? sourceOptions.projectRoot ?? node_process.default.cwd());
1206
+ return require_v3_engine.resolveTailwindV4EntriesFromCss(cssSource.css, sourceBase);
1207
+ }
1208
+ function countRuntimeCandidateHits(candidates, runtime) {
1209
+ if (!runtime?.size) return 0;
1210
+ let hits = 0;
1211
+ for (const candidate of candidates) if (runtime.has(candidate)) hits += 1;
1212
+ return hits;
1213
+ }
1214
+ async function resolveCandidateMatchedTailwindV4CssSource(_rawSource, cssHandlerOptions, sourceOptions, selectionOptions) {
1215
+ const cssSources = sourceOptions.cssSources;
1216
+ const getSourceCandidatesForEntries = selectionOptions?.getSourceCandidatesForEntries;
1217
+ if (!cssHandlerOptions.isMainChunk || !cssSources?.length || !getSourceCandidatesForEntries) return;
1218
+ const matches = [];
1219
+ await Promise.all(cssSources.map(async (cssSource, index) => {
1220
+ const resolved = await resolveTailwindV4CssSourceEntries(cssSource, sourceOptions);
1221
+ if (resolved?.entries === void 0) return;
1222
+ const scopedCandidates = getSourceCandidatesForEntries(resolved?.entries);
1223
+ const runtimeHits = countRuntimeCandidateHits(scopedCandidates, selectionOptions?.runtime);
1224
+ if (runtimeHits === 0) return;
1225
+ matches.push({
1226
+ cssSource,
1227
+ index,
1228
+ runtimeHits,
1229
+ totalCandidates: scopedCandidates.size
1230
+ });
1231
+ }));
1232
+ if (matches.length === 0) return;
1233
+ matches.sort((a, b) => b.runtimeHits - a.runtimeHits || b.totalCandidates - a.totalCandidates || a.index - b.index);
1234
+ const best = matches[0];
1235
+ const second = matches[1];
1236
+ if (!best) return;
1237
+ if (second && second.runtimeHits === best.runtimeHits && second.totalCandidates === best.totalCandidates) return;
1238
+ return resolveSingleTailwindV4CssSource(best.cssSource, sourceOptions);
1239
+ }
1240
+ function createTailwindV4CssSourceResolver(sourceOptions, generatorOptions) {
1241
+ return (cssSource) => require_v3_engine.resolveTailwindV4Source({
1242
+ ...require_v3_engine.omitUndefined(sourceOptions),
1243
+ cssSources: [cssSource]
1244
+ }).then((source) => generatorOptions?.config ? {
1245
+ ...source,
1246
+ css: prependConfigDirective(source.css, generatorOptions.config)
1247
+ } : source);
1248
+ }
1249
+ async function resolveTailwindV4SourceSideEntrySource(resolvedEntrySource, sourceOptions, generatorOptions, file) {
1250
+ if (!resolvedEntrySource) return;
1251
+ const resolvedSourceOptions = require_v3_engine.omitUndefined(sourceOptions);
1252
+ const config = resolveExistingConfigPath(resolvedEntrySource.config, resolvedEntrySource.configRequest, file, resolvedSourceOptions);
1253
+ const css = createTailwindV4ApplyReferenceSource(normalizeConfigDirective(prependConfigDirective(resolvedEntrySource.css, generatorOptions?.config), config), resolvedSourceOptions);
1254
+ return withMatchedSourceSideMetadata(await require_v3_engine.resolveTailwindV4Source(createSingleTailwindV4SourceOptions(resolvedSourceOptions, {
1255
+ base: resolvedEntrySource.base,
1256
+ css
1257
+ })), resolvedEntrySource);
1258
+ }
1259
+ function withGeneratorSourceMetadata(source, metadata) {
1260
+ return {
1261
+ ...source,
1262
+ __weappTailwindcssMeta: metadata
1263
+ };
1264
+ }
1265
+ function withMatchedSourceSideMetadata(source, resolvedEntrySource) {
1266
+ return resolvedEntrySource.file ? withGeneratorSourceMetadata(source, {
1267
+ matchedCssSourceFile: resolvedEntrySource.file,
1268
+ sourceBase: resolvedEntrySource.base,
1269
+ sourceCss: resolvedEntrySource.css
1270
+ }) : source;
1271
+ }
1065
1272
  function createTailwindV4ApplyReferenceSource(css, sourceOptions) {
1066
1273
  if (!hasTailwindApplyDirective(css) || hasTailwindRootDirectives(css)) return css;
1067
1274
  return `@reference "${sourceOptions.packageName ?? "tailwindcss"}";\n${css}`;
1068
1275
  }
1069
- async function resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions) {
1070
- const cssEntrySource = resolveCssEntrySource(rawSource, resolveCssSourceBase(file, cssHandlerOptions), {
1276
+ async function resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions, selectionOptions) {
1277
+ const base = resolveCssSourceBase(file, cssHandlerOptions);
1278
+ const cssEntrySource = resolveCssEntrySource(rawSource, base, {
1071
1279
  importFallback: generatorOptions?.importFallback ?? false,
1072
1280
  removeConfig: majorVersion === 3
1073
1281
  });
1074
1282
  if (majorVersion === 3) {
1075
- const sourceOptions = require_generator.resolveTailwindV3SourceOptionsFromPatcher(runtimeState.twPatcher);
1076
- const mergedSourceOptions = require_cache.omitUndefined({
1283
+ const sourceOptions = require_v3_engine.resolveTailwindV3SourceOptionsFromPatcher(runtimeState.twPatcher);
1284
+ const mergedSourceOptions = require_v3_engine.omitUndefined({
1077
1285
  ...sourceOptions,
1078
- config: generatorOptions?.config ?? sourceOptions.config
1286
+ config: generatorOptions?.config ?? sourceOptions.config,
1287
+ ...resolveCssHandlerSourceOptions(cssHandlerOptions)
1079
1288
  });
1289
+ const applyEntrySource = hasTailwindApplyDirective(rawSource) ? {
1290
+ base,
1291
+ css: rawSource
1292
+ } : void 0;
1080
1293
  const sourceSideEntrySource = canResolveSourceSideCssEntry(file, cssHandlerOptions) ? resolveSourceSideCssEntrySource(file, mergedSourceOptions, { removeConfig: true }) : void 0;
1081
- const resolvedEntrySource = cssEntrySource ?? sourceSideEntrySource;
1082
- if (!resolvedEntrySource) return generatorOptions?.config ? require_generator.resolveTailwindV3Source(mergedSourceOptions) : require_generator.resolveTailwindV3SourceFromPatcher(runtimeState.twPatcher);
1083
- const config = resolveExistingConfigPath(resolvedEntrySource.config, resolvedEntrySource.configRequest, file, require_cache.omitUndefined(mergedSourceOptions));
1084
- return require_generator.resolveTailwindV3Source({
1294
+ const resolvedEntrySource = shouldResolveSourceSideCssEntry(rawSource) ? applyEntrySource ?? cssEntrySource ?? sourceSideEntrySource : shouldPreferTailwindV3SourceSideEntry(rawSource, sourceSideEntrySource) ? sourceSideEntrySource ?? cssEntrySource : cssEntrySource ?? applyEntrySource ?? sourceSideEntrySource;
1295
+ if (!resolvedEntrySource) return generatorOptions?.config ? require_v3_engine.resolveTailwindV3Source(mergedSourceOptions) : require_v3_engine.resolveTailwindV3SourceFromPatcher(runtimeState.twPatcher);
1296
+ if (cssEntrySource && !sourceSideEntrySource && !applyEntrySource && !hasTailwindRootDirectives(rawSource, { importFallback: true })) return generatorOptions?.config ? require_v3_engine.resolveTailwindV3Source(mergedSourceOptions) : require_v3_engine.resolveTailwindV3SourceFromPatcher(runtimeState.twPatcher);
1297
+ const config = resolveExistingConfigPath(resolvedEntrySource.config, resolvedEntrySource.configRequest, file, require_v3_engine.omitUndefined(mergedSourceOptions));
1298
+ return require_v3_engine.resolveTailwindV3Source({
1085
1299
  ...mergedSourceOptions,
1086
1300
  base: resolvedEntrySource.base,
1087
1301
  css: resolvedEntrySource.css,
@@ -1089,60 +1303,104 @@ async function resolveGeneratorSource(majorVersion, runtimeState, rawSource, fil
1089
1303
  });
1090
1304
  }
1091
1305
  const sourceOptions = tryResolveTailwindV4SourceOptions(runtimeState);
1092
- const configuredCssSource = sourceOptions && hasConfiguredTailwindV4CssSource(sourceOptions) && hasTailwindGeneratedCssMarkers(rawSource) ? await require_generator.resolveTailwindV4Source(sourceOptions) : void 0;
1306
+ const resolvedSourceOptions = sourceOptions ? require_v3_engine.omitUndefined({
1307
+ ...sourceOptions,
1308
+ ...resolveCssHandlerSourceOptions(cssHandlerOptions)
1309
+ }) : void 0;
1310
+ const shouldPreferSourceSideEntry = shouldResolveSourceSideCssEntry(rawSource) || Boolean(cssEntrySource?.css.includes("weapp-tailwindcss generator-placeholder"));
1311
+ const sourceSideEntrySource = resolvedSourceOptions && shouldPreferSourceSideEntry ? resolveSourceSideCssEntrySource(file, resolvedSourceOptions, { removeConfig: false }) : void 0;
1312
+ const matchedCssSource = sourceOptions ? await resolveMatchingTailwindV4CssSource(rawSource, file, cssHandlerOptions, sourceOptions) : void 0;
1313
+ const candidateMatchedCssSource = sourceOptions ? await resolveCandidateMatchedTailwindV4CssSource(rawSource, cssHandlerOptions, sourceOptions, selectionOptions) : void 0;
1314
+ const configuredCssSource = sourceOptions && hasConfiguredTailwindV4CssSource(sourceOptions) && hasTailwindGeneratedCssMarkers(rawSource) ? matchedCssSource ?? candidateMatchedCssSource ?? await require_v3_engine.resolveTailwindV4Source(sourceOptions) : void 0;
1093
1315
  if (configuredCssSource) return generatorOptions?.config ? {
1094
1316
  ...configuredCssSource,
1095
1317
  css: prependConfigDirective(configuredCssSource.css, generatorOptions.config)
1096
1318
  } : configuredCssSource;
1097
- const shouldPreferSourceSideEntry = shouldResolveSourceSideCssEntry(rawSource) || Boolean(cssEntrySource?.css.includes("weapp-tailwindcss generator-placeholder"));
1098
- const sourceSideEntrySource = sourceOptions && shouldPreferSourceSideEntry ? resolveSourceSideCssEntrySource(file, sourceOptions, { removeConfig: false }) : void 0;
1099
1319
  const matchedCssEntrySource = sourceOptions && cssEntrySource ? await resolveMatchingTailwindV4CssEntry(rawSource, file, sourceOptions) : void 0;
1100
- const mainCssEntrySource = sourceOptions && cssHandlerOptions.isMainChunk && sourceOptions.cssEntries?.length === 1 ? await require_generator.resolveTailwindV4Source({
1101
- ...require_cache.omitUndefined(sourceOptions),
1320
+ const mainCssEntrySource = sourceOptions && cssHandlerOptions.isMainChunk && sourceOptions.cssEntries?.length === 1 ? await require_v3_engine.resolveTailwindV4Source({
1321
+ ...require_v3_engine.omitUndefined(sourceOptions),
1102
1322
  cssEntries: [sourceOptions.cssEntries[0]]
1103
1323
  }) : void 0;
1104
- const preferredCssEntrySource = matchedCssEntrySource ?? mainCssEntrySource;
1324
+ const preferredCssEntrySource = matchedCssEntrySource ?? matchedCssSource ?? candidateMatchedCssSource ?? mainCssEntrySource;
1105
1325
  if (preferredCssEntrySource) return generatorOptions?.config ? {
1106
1326
  ...preferredCssEntrySource,
1107
1327
  css: prependConfigDirective(preferredCssEntrySource.css, generatorOptions.config)
1108
1328
  } : preferredCssEntrySource;
1109
1329
  const resolvedEntrySource = sourceSideEntrySource ?? cssEntrySource;
1110
1330
  if (!resolvedEntrySource) {
1111
- const source = await require_generator.resolveTailwindV4SourceFromPatcher(runtimeState.twPatcher);
1331
+ const source = await require_v3_engine.resolveTailwindV4SourceFromPatcher(runtimeState.twPatcher);
1112
1332
  return generatorOptions?.config ? {
1113
1333
  ...source,
1114
1334
  css: prependConfigDirective(source.css, generatorOptions.config)
1115
1335
  } : source;
1116
1336
  }
1117
- const resolvedSourceOptions = require_cache.omitUndefined(sourceOptions ?? {});
1118
- const config = resolveExistingConfigPath(resolvedEntrySource.config, resolvedEntrySource.configRequest, file, resolvedSourceOptions);
1119
- const css = createTailwindV4ApplyReferenceSource(normalizeConfigDirective(prependConfigDirective(resolvedEntrySource.css, generatorOptions?.config), config), resolvedSourceOptions);
1120
- return require_generator.resolveTailwindV4Source({
1121
- ...resolvedSourceOptions,
1337
+ if (sourceSideEntrySource && resolvedSourceOptions) return resolveTailwindV4SourceSideEntrySource(sourceSideEntrySource, resolvedSourceOptions, generatorOptions, file);
1338
+ const config = resolveExistingConfigPath(resolvedEntrySource.config, resolvedEntrySource.configRequest, file, resolvedSourceOptions ?? {});
1339
+ const css = createTailwindV4ApplyReferenceSource(normalizeConfigDirective(prependConfigDirective(resolvedEntrySource.css, generatorOptions?.config), config), resolvedSourceOptions ?? {});
1340
+ return require_v3_engine.resolveTailwindV4Source(createSingleTailwindV4SourceOptions(resolvedSourceOptions ?? {}, {
1122
1341
  base: resolvedEntrySource.base,
1123
1342
  css
1124
- });
1343
+ }));
1125
1344
  }
1126
- async function resolveGeneratorSources(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions) {
1345
+ async function resolveGeneratorSources(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions, selectionOptions) {
1127
1346
  const cssEntrySource = resolveCssEntrySource(rawSource, resolveCssSourceBase(file, cssHandlerOptions), {
1128
1347
  importFallback: generatorOptions?.importFallback ?? false,
1129
1348
  removeConfig: majorVersion === 3
1130
1349
  });
1131
- if (majorVersion !== 4 || cssEntrySource && !cssHandlerOptions.isMainChunk) return [await resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions)];
1350
+ if (majorVersion !== 4 || cssEntrySource && !cssHandlerOptions.isMainChunk) return [await resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions, selectionOptions)];
1132
1351
  let sourceOptions;
1133
1352
  try {
1134
- sourceOptions = require_generator.resolveTailwindV4SourceOptionsFromPatcher(runtimeState.twPatcher);
1353
+ sourceOptions = require_v3_engine.omitUndefined({
1354
+ ...require_v3_engine.resolveTailwindV4SourceOptionsFromPatcher(runtimeState.twPatcher),
1355
+ ...resolveCssHandlerSourceOptions(cssHandlerOptions)
1356
+ });
1135
1357
  } catch {
1136
- return [await resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions)];
1358
+ return [await resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions, selectionOptions)];
1137
1359
  }
1138
- if (!sourceOptions.cssEntries || sourceOptions.cssEntries.length <= 1) return [await resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions)];
1139
- return await Promise.all(sourceOptions.cssEntries.map((cssEntry) => require_generator.resolveTailwindV4Source({
1140
- ...require_cache.omitUndefined(sourceOptions),
1360
+ const matchedCssEntrySource = cssEntrySource ? await resolveMatchingTailwindV4CssEntry(rawSource, file, sourceOptions) : void 0;
1361
+ const matchedCssSource = await resolveMatchingTailwindV4CssSource(rawSource, file, cssHandlerOptions, sourceOptions);
1362
+ const candidateMatchedCssSource = await resolveCandidateMatchedTailwindV4CssSource(rawSource, cssHandlerOptions, sourceOptions, selectionOptions);
1363
+ const sourceSideCssSource = await resolveTailwindV4SourceSideEntrySource(shouldResolveSourceSideCssEntry(rawSource) || Boolean(cssEntrySource?.css.includes("weapp-tailwindcss generator-placeholder")) ? resolveSourceSideCssEntrySource(file, sourceOptions, { removeConfig: false }) : void 0, sourceOptions, generatorOptions, file);
1364
+ const preferredCssEntrySource = matchedCssEntrySource ?? matchedCssSource ?? candidateMatchedCssSource;
1365
+ if (sourceSideCssSource) return [sourceSideCssSource];
1366
+ if (preferredCssEntrySource) return [generatorOptions?.config ? {
1367
+ ...preferredCssEntrySource,
1368
+ css: prependConfigDirective(preferredCssEntrySource.css, generatorOptions.config)
1369
+ } : preferredCssEntrySource];
1370
+ if (!sourceOptions.cssEntries || sourceOptions.cssEntries.length <= 1) {
1371
+ if (sourceOptions.cssSources?.length === 1) return [await createTailwindV4CssSourceResolver(sourceOptions, generatorOptions)(sourceOptions.cssSources[0])];
1372
+ return [await resolveGeneratorSource(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, generatorOptions, selectionOptions)];
1373
+ }
1374
+ const cssEntrySources = await Promise.all(sourceOptions.cssEntries.map((cssEntry) => require_v3_engine.resolveTailwindV4Source({
1375
+ ...require_v3_engine.omitUndefined(sourceOptions),
1141
1376
  cssEntries: [cssEntry]
1142
1377
  }).then((source) => generatorOptions?.config ? {
1143
1378
  ...source,
1144
1379
  css: prependConfigDirective(source.css, generatorOptions.config)
1145
1380
  } : source)));
1381
+ const cssSources = sourceOptions.cssSources?.length ? await Promise.all(sourceOptions.cssSources.map(createTailwindV4CssSourceResolver(sourceOptions, generatorOptions))) : [];
1382
+ return [...cssEntrySources, ...cssSources];
1383
+ }
1384
+ async function resolveGeneratorSourceEntries(source, runtimeState) {
1385
+ if (!("css" in source) || !("base" in source) || !("baseFallbacks" in source)) return;
1386
+ const sourceMetadata = source.__weappTailwindcssMeta;
1387
+ const resolved = await require_v3_engine.resolveTailwindV4EntriesFromCss(sourceMetadata?.sourceCss ?? source.css, sourceMetadata?.sourceBase ?? source.base);
1388
+ if (resolved?.entries.length || !resolved?.explicit && !sourceMetadata?.matchedCssSourceFile || !runtimeState) return resolved?.entries;
1389
+ const matchingCssSource = tryResolveTailwindV4SourceOptions(runtimeState)?.cssSources?.find((cssSource) => {
1390
+ if (sourceMetadata?.matchedCssSourceFile && typeof cssSource.file === "string" && node_path.default.resolve(cssSource.file) === node_path.default.resolve(sourceMetadata.matchedCssSourceFile)) return true;
1391
+ return cssSource.css === source.css;
1392
+ });
1393
+ if (!matchingCssSource) return resolved?.entries;
1394
+ const sourceResolved = await require_v3_engine.resolveTailwindV4EntriesFromCss(matchingCssSource.css, typeof matchingCssSource.base === "string" && matchingCssSource.base.length > 0 ? matchingCssSource.base : typeof matchingCssSource.file === "string" && matchingCssSource.file.length > 0 ? node_path.default.dirname(matchingCssSource.file) : source.base);
1395
+ if (sourceResolved?.entries.length) return sourceResolved.entries;
1396
+ for (const dependency of matchingCssSource.dependencies ?? []) {
1397
+ if (!(0, node_fs.existsSync)(dependency)) continue;
1398
+ try {
1399
+ const dependencyResolved = await require_v3_engine.resolveTailwindV4EntriesFromCss((0, node_fs.readFileSync)(dependency, "utf8"), node_path.default.dirname(dependency));
1400
+ if (dependencyResolved?.entries.length) return dependencyResolved.entries;
1401
+ } catch {}
1402
+ }
1403
+ return resolved.entries;
1146
1404
  }
1147
1405
  //#endregion
1148
1406
  //#region src/bundlers/shared/generator-css/legacy-compat.ts
@@ -1176,6 +1434,28 @@ const LEGACY_CONTAINER_COMPAT_CSS = [
1176
1434
  " }",
1177
1435
  "}"
1178
1436
  ].join("\n");
1437
+ const LEGACY_COMPAT_CACHE_LIMIT = 128;
1438
+ const legacyCompatSourceCache = /* @__PURE__ */ new Map();
1439
+ const legacyCompatTransformCache = /* @__PURE__ */ new Map();
1440
+ function setLimitedCacheValue(cache, key, value) {
1441
+ if (cache.size >= LEGACY_COMPAT_CACHE_LIMIT) {
1442
+ const firstKey = cache.keys().next().value;
1443
+ if (firstKey !== void 0) cache.delete(firstKey);
1444
+ }
1445
+ cache.set(key, value);
1446
+ }
1447
+ function createStableJson(value) {
1448
+ if (value === void 0) return "undefined";
1449
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
1450
+ if (Array.isArray(value)) return `[${value.map((item) => createStableJson(item)).join(",")}]`;
1451
+ return `{${Object.keys(value).sort().map((key) => {
1452
+ const record = value;
1453
+ return `${JSON.stringify(key)}:${createStableJson(record[key])}`;
1454
+ }).join(",")}}`;
1455
+ }
1456
+ function createLegacyCompatTransformCacheKey(source, options) {
1457
+ return `${createStableJson(options)}\0${source}`;
1458
+ }
1179
1459
  function removeTailwindApplyRules(rawSource) {
1180
1460
  try {
1181
1461
  const root = postcss.default.parse(rawSource);
@@ -1195,7 +1475,11 @@ function removeTailwindApplyRules(rawSource) {
1195
1475
  }
1196
1476
  }
1197
1477
  function resolveLegacyCompatCssSource(rawSource) {
1198
- return removeUnsupportedMiniProgramAtRules(removeTailwindApplyRules(removeTailwindSourceDirectives(stripTailwindBanners(rawSource))));
1478
+ const cached = legacyCompatSourceCache.get(rawSource);
1479
+ if (cached !== void 0) return cached;
1480
+ const resolved = removeUnsupportedMiniProgramAtRules(removeTailwindApplyRules(removeTailwindSourceDirectives(stripTailwindBanners(rawSource))));
1481
+ setLimitedCacheValue(legacyCompatSourceCache, rawSource, resolved);
1482
+ return resolved;
1199
1483
  }
1200
1484
  function hasContainerConfigToken(rawSource) {
1201
1485
  return rawSource.includes("@config") && /\bcontainer\b/.test(rawSource);
@@ -1228,10 +1512,16 @@ async function appendLegacyCompatCss(css, rawSource, generatorTarget, styleHandl
1228
1512
  const compatSource = removeGeneratedSelectorCompatCss(resolveLegacyCompatCssSource(rawSource), css);
1229
1513
  if (compatSource.trim().length === 0) return css;
1230
1514
  if (generatorTarget !== "weapp") return createCssAppend(css, compatSource);
1231
- const { css: compatCss } = await styleHandler(compatSource, {
1515
+ const styleOptions = {
1232
1516
  ...cssHandlerOptions,
1233
1517
  ...generatorStyleOptions
1234
- });
1518
+ };
1519
+ const compatCssCacheKey = createLegacyCompatTransformCacheKey(compatSource, styleOptions);
1520
+ let compatCss = legacyCompatTransformCache.get(compatCssCacheKey);
1521
+ if (compatCss === void 0) {
1522
+ compatCss = (await styleHandler(compatSource, styleOptions)).css;
1523
+ setLimitedCacheValue(legacyCompatTransformCache, compatCssCacheKey, compatCss);
1524
+ }
1235
1525
  const cleanedCompatCss = collectDedupedPostTransformCompatCss(removeDuplicatedViteMarkers(removeUnsupportedMiniProgramAtRules(compatCss), css), css);
1236
1526
  if (cleanedCompatCss.trim().length === 0) return css;
1237
1527
  return createCssAppend(css, cleanedCompatCss);
@@ -1240,10 +1530,16 @@ async function appendLegacyContainerCompatCss(css, rawSource, file, runtime, con
1240
1530
  const compatSource = resolveLegacyCompatCssSource(rawSource);
1241
1531
  const shouldAppendContainer = runtime.has("container") || hasConfiguredContainerCompat(rawSource, file, cssHandlerOptions) || configuredContainerCompat || collectGeneratedSelectors(compatSource).has(".container");
1242
1532
  if (generatorTarget !== "weapp" || !shouldAppendContainer || collectGeneratedSelectors(css).has(".container")) return css;
1243
- const { css: compatCss } = await styleHandler(LEGACY_CONTAINER_COMPAT_CSS, {
1533
+ const styleOptions = {
1244
1534
  ...cssHandlerOptions,
1245
1535
  ...generatorStyleOptions
1246
- });
1536
+ };
1537
+ const compatCssCacheKey = createLegacyCompatTransformCacheKey(LEGACY_CONTAINER_COMPAT_CSS, styleOptions);
1538
+ let compatCss = legacyCompatTransformCache.get(compatCssCacheKey);
1539
+ if (compatCss === void 0) {
1540
+ compatCss = (await styleHandler(LEGACY_CONTAINER_COMPAT_CSS, styleOptions)).css;
1541
+ setLimitedCacheValue(legacyCompatTransformCache, compatCssCacheKey, compatCss);
1542
+ }
1247
1543
  const cleanedCompatCss = collectDedupedPostTransformCompatCss(removeUnsupportedMiniProgramAtRules(compatCss), css);
1248
1544
  if (cleanedCompatCss.trim().length === 0) return css;
1249
1545
  return createCssAppend(css, cleanedCompatCss);
@@ -1296,15 +1592,25 @@ function inheritLegacyUnitConvertedDeclarations(css, legacyCss) {
1296
1592
  //#region src/bundlers/shared/generator-css.ts
1297
1593
  const SUPPORTED_GENERATOR_MAJOR_VERSIONS = new Set([3, 4]);
1298
1594
  const REMOTE_IMPORT_RE = /^(?:https?:)?\/\//i;
1299
- function finalizeMiniProgramGeneratorCss(css, target) {
1595
+ function finalizeMiniProgramGeneratorCss(css, target, majorVersion, cssPreflight) {
1300
1596
  if (target !== "weapp") return css;
1301
- return finalizeMiniProgramCss(css);
1597
+ return finalizeMiniProgramCss(css, {
1598
+ cssPreflight: majorVersion === 4 ? cssPreflight : void 0,
1599
+ preservePseudoContentInit: majorVersion === 3
1600
+ });
1601
+ }
1602
+ function mergeScopedRuntimeWithCurrentRuntime(scopedRuntime, runtime, options) {
1603
+ if (runtime.size === 0 || !options.cssHandlerOptions.isMainChunk || options.isolateCssSource) return scopedRuntime;
1604
+ return new Set([...scopedRuntime, ...runtime]);
1605
+ }
1606
+ function shouldIsolateMatchedCssSource(source, sourceEntries) {
1607
+ return Boolean(source.__weappTailwindcssMeta?.matchedCssSourceFile && sourceEntries !== void 0);
1302
1608
  }
1303
1609
  function resolveGeneratorStyleOptions(opts, cssHandlerOptions, generatorStyleOptions) {
1304
- const tailwindV3StyleOptions = cssHandlerOptions.majorVersion === 3 ? {
1610
+ const preflightStyleOptions = {
1305
1611
  cssPreflight: opts.cssPreflight,
1306
1612
  cssPreflightRange: opts.cssPreflightRange
1307
- } : {};
1613
+ };
1308
1614
  const resolvedUniAppXOptions = require_tailwindcss.resolveUniAppXOptions(opts.uniAppX);
1309
1615
  return {
1310
1616
  cssChildCombinatorReplaceValue: opts.cssChildCombinatorReplaceValue,
@@ -1322,7 +1628,7 @@ function resolveGeneratorStyleOptions(opts, cssHandlerOptions, generatorStyleOpt
1322
1628
  uniAppXCssTarget: opts.uniAppXCssTarget,
1323
1629
  uniAppXUnsupported: opts.uniAppXUnsupported,
1324
1630
  ...cssHandlerOptions,
1325
- ...tailwindV3StyleOptions,
1631
+ ...preflightStyleOptions,
1326
1632
  ...generatorStyleOptions
1327
1633
  };
1328
1634
  }
@@ -1382,7 +1688,7 @@ function prefixLocalCssImportsWithWebpackIgnore(css) {
1382
1688
  }
1383
1689
  }
1384
1690
  async function generateCssByGenerator(options) {
1385
- const { opts, runtimeState, runtime, rawSource, file, cssHandlerOptions, cssUserHandlerOptions, styleHandler, debug } = options;
1691
+ const { opts, runtimeState, runtime, rawSource, file, cssHandlerOptions, cssUserHandlerOptions, getSourceCandidatesForEntries, styleHandler, debug } = options;
1386
1692
  const generatorOptions = require_generator.normalizeWeappTailwindcssGeneratorOptions(opts.generator);
1387
1693
  const majorVersion = runtimeState.twPatcher.majorVersion;
1388
1694
  const effectiveRawSource = normalizeTailwindSourceDirectives(rawSource, { importFallback: generatorOptions.importFallback });
@@ -1401,13 +1707,25 @@ async function generateCssByGenerator(options) {
1401
1707
  if (!SUPPORTED_GENERATOR_MAJOR_VERSIONS.has(majorVersion ?? 0) || !shouldGenerateCurrentCss || majorVersion === 3 && !hasSourceDirectives && !hasGeneratedCss && !hasGeneratedMarkers) return;
1402
1708
  try {
1403
1709
  await runtimeState.readyPromise;
1404
- const sources = await resolveGeneratorSources(majorVersion, runtimeState, effectiveRawSource, file, cssHandlerOptions, generatorOptions);
1710
+ const sources = await resolveGeneratorSources(majorVersion, runtimeState, effectiveRawSource, file, cssHandlerOptions, generatorOptions, {
1711
+ getSourceCandidatesForEntries,
1712
+ runtime
1713
+ });
1405
1714
  const generatorStyleOptions = resolveGeneratorStyleOptions(opts, cssHandlerOptions, generatorOptions.styleOptions);
1406
1715
  const configuredContainerCompat = hasConfiguredContainerCompatSources(sources);
1407
1716
  const generatedResults = await Promise.all(sources.map(async (source) => {
1408
- return require_generator.createWeappTailwindcssGenerator(source).generate({
1409
- candidates: runtime,
1410
- scanSources: majorVersion === 4,
1717
+ const generator = require_generator.createWeappTailwindcssGenerator(source);
1718
+ const sourceEntries = getSourceCandidatesForEntries && majorVersion === 4 ? await resolveGeneratorSourceEntries(source, runtimeState) : void 0;
1719
+ const scopedRuntime = sourceEntries ? getSourceCandidatesForEntries?.(sourceEntries) : void 0;
1720
+ const isolateCssSource = shouldIsolateMatchedCssSource(source, sourceEntries);
1721
+ const sourceRuntime = scopedRuntime && (scopedRuntime.size > 0 || isolateCssSource) ? mergeScopedRuntimeWithCurrentRuntime(scopedRuntime, runtime, {
1722
+ cssHandlerOptions,
1723
+ isolateCssSource
1724
+ }) : runtime;
1725
+ return generator.generate({
1726
+ candidates: sourceRuntime,
1727
+ incrementalCache: majorVersion === 3 || majorVersion === 4,
1728
+ scanSources: majorVersion === 4 && sourceRuntime.size === 0 && !isolateCssSource,
1411
1729
  styleOptions: generatorStyleOptions,
1412
1730
  tailwindcssV3Compatibility: generatorOptions.tailwindcssV3Compatibility,
1413
1731
  target: generatorOptions.target
@@ -1415,15 +1733,29 @@ async function generateCssByGenerator(options) {
1415
1733
  }));
1416
1734
  const firstGenerated = generatedResults[0];
1417
1735
  if (!firstGenerated) return;
1736
+ const incrementalCssResults = generatedResults.map((item) => item.incrementalCss).filter((css) => typeof css === "string");
1737
+ const incrementalRawCssResults = generatedResults.map((item) => item.incrementalRawCss).filter((css) => typeof css === "string");
1418
1738
  const generated = generatedResults.length === 1 ? firstGenerated : {
1419
1739
  ...firstGenerated,
1420
1740
  css: generatedResults.map((item) => item.css).join("\n"),
1421
1741
  rawCss: generatedResults.map((item) => item.rawCss).join("\n"),
1742
+ incrementalCss: incrementalCssResults.length === generatedResults.length ? incrementalCssResults.filter(Boolean).join("\n") : void 0,
1743
+ incrementalRawCss: incrementalRawCssResults.length === generatedResults.length ? incrementalRawCssResults.filter(Boolean).join("\n") : void 0,
1422
1744
  classSet: new Set(generatedResults.flatMap((item) => [...item.classSet])),
1423
1745
  dependencies: [...new Set(generatedResults.flatMap((item) => item.dependencies))],
1424
1746
  sources: generatedResults.flatMap((item) => item.sources)
1425
1747
  };
1426
1748
  debug("tailwind generator result: %s rawBytes=%d cssBytes=%d candidates=%d", file, generated.rawCss.length, generated.css.length, generated.classSet.size);
1749
+ if (typeof options.previousCss === "string" && typeof generated.incrementalCss === "string") {
1750
+ const incrementalCss = stripTailwindBanner(generated.incrementalCss);
1751
+ return {
1752
+ css: incrementalCss.trim().length > 0 ? createCssAppend(options.previousCss, finalizeMiniProgramGeneratorCss(incrementalCss, generated.target, majorVersion, opts.cssPreflight)) : options.previousCss,
1753
+ target: generated.target,
1754
+ source: "generator",
1755
+ dependencies: generated.dependencies,
1756
+ incremental: true
1757
+ };
1758
+ }
1427
1759
  const extraCss = splitTailwindV4GeneratedCss(effectiveRawSource, generated.rawCss);
1428
1760
  if (typeof extraCss === "string") {
1429
1761
  let css = stripTailwindBanner(generated.css);
@@ -1433,7 +1765,7 @@ async function generateCssByGenerator(options) {
1433
1765
  if (cleanedExtraCss.trim().length > 0) {
1434
1766
  const extraSource = generated.target === "weapp" ? removeUnsupportedMiniProgramAtRules(cleanedExtraCss) : cleanedExtraCss;
1435
1767
  if (extraSource.trim().length === 0) return {
1436
- css: finalizeMiniProgramGeneratorCss(css, generated.target),
1768
+ css: finalizeMiniProgramGeneratorCss(css, generated.target, majorVersion, opts.cssPreflight),
1437
1769
  target: generated.target,
1438
1770
  source: "generator",
1439
1771
  dependencies: generated.dependencies
@@ -1452,7 +1784,7 @@ async function generateCssByGenerator(options) {
1452
1784
  css = await appendLegacyContainerCompatCss(css, effectiveRawSource, file, runtime, configuredContainerCompat, generated.target, styleHandler, cssHandlerOptions, generatorStyleOptions);
1453
1785
  }
1454
1786
  return {
1455
- css: finalizeMiniProgramGeneratorCss(css, generated.target),
1787
+ css: finalizeMiniProgramGeneratorCss(css, generated.target, majorVersion, opts.cssPreflight),
1456
1788
  target: generated.target,
1457
1789
  source: "generator",
1458
1790
  dependencies: generated.dependencies
@@ -1461,10 +1793,16 @@ async function generateCssByGenerator(options) {
1461
1793
  debug("tailwind direct css generation prefix mismatch, append transformed bundle css %s", file);
1462
1794
  let css = stripTailwindBanner(generated.css);
1463
1795
  if (generated.target === "weapp") css = inheritLegacyUnitConvertedDeclarations(css, effectiveRawSource);
1796
+ if (sources.some((source) => source.__weappTailwindcssMeta?.matchedCssSourceFile)) return {
1797
+ css: finalizeMiniProgramGeneratorCss(css, generated.target, majorVersion, opts.cssPreflight),
1798
+ target: generated.target,
1799
+ source: "generator",
1800
+ dependencies: generated.dependencies
1801
+ };
1464
1802
  css = await appendLegacyCompatCss(css, effectiveRawSource, generated.target, styleHandler, cssHandlerOptions, generatorStyleOptions);
1465
1803
  css = await appendLegacyContainerCompatCss(css, effectiveRawSource, file, runtime, configuredContainerCompat, generated.target, styleHandler, cssHandlerOptions, generatorStyleOptions);
1466
1804
  return {
1467
- css: finalizeMiniProgramGeneratorCss(css, generated.target),
1805
+ css: finalizeMiniProgramGeneratorCss(css, generated.target, majorVersion, opts.cssPreflight),
1468
1806
  target: generated.target,
1469
1807
  source: "generator",
1470
1808
  dependencies: generated.dependencies
@@ -1478,7 +1816,7 @@ async function validateCandidatesByGenerator(options) {
1478
1816
  const { candidates, cssHandlerOptions, debug, file, opts, rawSource, runtimeState } = options;
1479
1817
  const majorVersion = runtimeState.twPatcher.majorVersion;
1480
1818
  if (!SUPPORTED_GENERATOR_MAJOR_VERSIONS.has(majorVersion ?? 0) || candidates.size === 0) return /* @__PURE__ */ new Set();
1481
- const sources = await resolveGeneratorSources(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, require_generator.normalizeWeappTailwindcssGeneratorOptions(opts.generator));
1819
+ const sources = await resolveGeneratorSources(majorVersion, runtimeState, rawSource, file, cssHandlerOptions, require_generator.normalizeWeappTailwindcssGeneratorOptions(opts.generator), { runtime: candidates });
1482
1820
  const classSets = await Promise.all(sources.map(async (source) => {
1483
1821
  const generator = require_generator.createWeappTailwindcssGenerator(source);
1484
1822
  if (typeof generator.validateCandidates === "function") return generator.validateCandidates(candidates);
@@ -1496,19 +1834,82 @@ async function validateCandidatesByGenerator(options) {
1496
1834
  function shouldEmitHmrTiming() {
1497
1835
  return node_process.default.env["WEAPP_TW_WATCH_REGRESSION"] === "1" || node_process.default.env["WEAPP_TW_HMR_TIMING"] === "1";
1498
1836
  }
1837
+ function shouldEmitHumanReadableTiming() {
1838
+ return node_process.default.env["WEAPP_TW_HMR_TIMING"] === "1" && node_process.default.env["WEAPP_TW_HMR_TIMING_LOG"] !== "0";
1839
+ }
1499
1840
  function emitHmrTiming(bundler, phase, durationMs, details = {}) {
1500
1841
  if (!shouldEmitHmrTiming()) return;
1842
+ const serializableDetails = { ...details };
1843
+ delete serializableDetails.emit;
1501
1844
  const payload = {
1502
1845
  bundler,
1503
1846
  phase,
1504
1847
  durationMs: Math.max(0, Math.round(durationMs)),
1505
- ...details
1848
+ ...serializableDetails,
1849
+ ...typeof details.wallMs === "number" ? { wallMs: Math.max(0, Math.round(details.wallMs)) } : {}
1506
1850
  };
1507
1851
  node_process.default.stdout.write(`[weapp-tailwindcss:hmr] ${JSON.stringify(payload)}\n`);
1852
+ if (shouldEmitHumanReadableTiming()) {
1853
+ const fileSuffix = details.file ? ` file=${details.file}` : "";
1854
+ if (details.metric === "total") {
1855
+ const hooks = details.hooks ? Object.entries(details.hooks).map(([hook, summary]) => `${hook}=${Math.max(0, Math.round(summary.durationMs))}ms/${summary.count}`).join(", ") : "";
1856
+ const hookSuffix = hooks ? ` (${hooks})` : "";
1857
+ const wallSuffix = typeof payload.wallMs === "number" ? ` wall=${payload.wallMs}ms` : "";
1858
+ node_process.default.stdout.write(`[weapp-tailwindcss] ${bundler}:weapp-tailwindcss 总耗时 ${payload.durationMs}ms${wallSuffix}${hookSuffix}\n`);
1859
+ return;
1860
+ }
1861
+ node_process.default.stdout.write(`[weapp-tailwindcss] ${bundler}:${phase} 耗时 ${payload.durationMs}ms${fileSuffix}\n`);
1862
+ }
1863
+ }
1864
+ function createHmrTimingRecorder(bundler) {
1865
+ const session = {
1866
+ hooks: {},
1867
+ totalMs: 0
1868
+ };
1869
+ const record = (phase, durationMs, details = {}) => {
1870
+ const roundedDuration = Math.max(0, Math.round(durationMs));
1871
+ if (session.startedAt === void 0) session.startedAt = performance.now() - Math.max(0, durationMs);
1872
+ session.totalMs += Math.max(0, durationMs);
1873
+ const current = session.hooks[phase] ?? {
1874
+ count: 0,
1875
+ durationMs: 0,
1876
+ maxMs: 0
1877
+ };
1878
+ current.count += 1;
1879
+ current.durationMs += roundedDuration;
1880
+ current.maxMs = Math.max(current.maxMs, roundedDuration);
1881
+ session.hooks[phase] = current;
1882
+ if (details.emit !== false) emitHmrTiming(bundler, phase, durationMs, details);
1883
+ };
1884
+ const measure = async (phase, task, details = {}) => {
1885
+ const startedAt = performance.now();
1886
+ try {
1887
+ return await task();
1888
+ } finally {
1889
+ record(phase, performance.now() - startedAt, details);
1890
+ }
1891
+ };
1892
+ const emitTotal = (phase = "total") => {
1893
+ if (session.totalMs <= 0) return;
1894
+ const wallMs = session.startedAt === void 0 ? session.totalMs : performance.now() - session.startedAt;
1895
+ emitHmrTiming(bundler, phase, session.totalMs, {
1896
+ hooks: session.hooks,
1897
+ metric: "total",
1898
+ wallMs
1899
+ });
1900
+ session.hooks = {};
1901
+ delete session.startedAt;
1902
+ session.totalMs = 0;
1903
+ };
1904
+ return {
1905
+ emitTotal,
1906
+ measure,
1907
+ record
1908
+ };
1508
1909
  }
1509
1910
  //#endregion
1510
1911
  //#region src/bundlers/vite/incremental-runtime-class-set.ts
1511
- const debug = require_runtime_patch.createDebug("[vite:runtime-set] ");
1912
+ const debug = require_v3_engine.createDebug("[vite:runtime-set] ");
1512
1913
  const EXTENSION_DOT_PREFIX_RE = /^\./;
1513
1914
  function createExtractOptions(context, source) {
1514
1915
  return {
@@ -1581,7 +1982,7 @@ function createBundleRuntimeClassSetManager(options = {}) {
1581
1982
  designSystemPromise = void 0;
1582
1983
  }
1583
1984
  async function resolveValidationContextCached(patcher) {
1584
- if (!validationContext) validationContext = await require_generator.resolveTailwindV4SourceFromPatcher(patcher);
1985
+ if (!validationContext) validationContext = await require_v3_engine.resolveTailwindV4SourceFromPatcher(patcher);
1585
1986
  return validationContext;
1586
1987
  }
1587
1988
  async function loadDesignSystem(context) {
@@ -1628,10 +2029,11 @@ function createBundleRuntimeClassSetManager(options = {}) {
1628
2029
  return candidates;
1629
2030
  }
1630
2031
  async function sync(patcher, snapshot, options = {}) {
1631
- const nextSignature = require_cache.getRuntimeClassSetSignature(patcher) ?? "runtime:missing";
2032
+ const nextSignature = require_v3_engine.getRuntimeClassSetSignature(patcher) ?? "runtime:missing";
1632
2033
  const runtimeEntries = createRuntimeEntries(snapshot);
1633
2034
  const runtimeEntriesByFile = new Map(runtimeEntries.map((entry) => [entry.file, entry]));
1634
2035
  const currentRuntimeFiles = new Set(runtimeEntriesByFile.keys());
2036
+ const hadTrackedRuntimeFiles = candidatesByFile.size > 0;
1635
2037
  const fullRebuild = runtimeSignature !== nextSignature || candidatesByFile.size === 0;
1636
2038
  if (runtimeSignature !== nextSignature) {
1637
2039
  debug("runtime signature changed, reset incremental runtime set: %s", nextSignature);
@@ -1639,14 +2041,15 @@ function createBundleRuntimeClassSetManager(options = {}) {
1639
2041
  }
1640
2042
  runtimeSignature = nextSignature;
1641
2043
  const nextBaseClassSet = options.baseClassSet;
2044
+ const canUseBaseWithoutInitialFullScan = Boolean(fullRebuild && !hadTrackedRuntimeFiles && options.skipInitialFullScanWithBase === true && nextBaseClassSet && nextBaseClassSet.size > 0);
1642
2045
  for (const [file, previousCandidates] of candidatesByFile) {
1643
2046
  if (currentRuntimeFiles.has(file)) continue;
1644
2047
  removeCandidateSet(candidateCountByClass, previousCandidates);
1645
2048
  candidatesByFile.delete(file);
1646
2049
  }
1647
- const changedRuntimeFiles = fullRebuild ? [...runtimeEntriesByFile.keys()] : [...collectChangedRuntimeFiles(snapshot)];
2050
+ const changedRuntimeFiles = canUseBaseWithoutInitialFullScan ? [...collectChangedRuntimeFiles(snapshot)] : fullRebuild ? [...runtimeEntriesByFile.keys()] : [...collectChangedRuntimeFiles(snapshot)];
1648
2051
  if (changedRuntimeFiles.length === 0) {
1649
- if (nextBaseClassSet) baseClassSet = createNonSourceBaseClassSet(nextBaseClassSet, candidateCountByClass);
2052
+ if (nextBaseClassSet) baseClassSet = canUseBaseWithoutInitialFullScan ? new Set(nextBaseClassSet) : createNonSourceBaseClassSet(nextBaseClassSet, candidateCountByClass);
1650
2053
  return createRuntimeClassSet(baseClassSet, candidateCountByClass);
1651
2054
  }
1652
2055
  const rawCandidatesByFile = /* @__PURE__ */ new Map();
@@ -1677,7 +2080,7 @@ function createBundleRuntimeClassSetManager(options = {}) {
1677
2080
  addCandidateSet(candidateCountByClass, nextCandidates);
1678
2081
  candidatesByFile.set(file, nextCandidates);
1679
2082
  }
1680
- if (nextBaseClassSet) baseClassSet = createNonSourceBaseClassSet(nextBaseClassSet, candidateCountByClass);
2083
+ if (nextBaseClassSet) baseClassSet = canUseBaseWithoutInitialFullScan ? new Set(nextBaseClassSet) : createNonSourceBaseClassSet(nextBaseClassSet, candidateCountByClass);
1681
2084
  const runtimeSet = createRuntimeClassSet(baseClassSet, candidateCountByClass);
1682
2085
  debug("incremental runtime set synced, changedFiles=%d rawCandidates=%d validateMisses=%d runtimeSize=%d trackedFiles=%d", changedRuntimeFiles.length, rawCandidateCount, unknownCandidates.size, runtimeSet.size, candidatesByFile.size);
1683
2086
  return new Set(runtimeSet);
@@ -1694,6 +2097,12 @@ Object.defineProperty(exports, "createBundleRuntimeClassSetManager", {
1694
2097
  return createBundleRuntimeClassSetManager;
1695
2098
  }
1696
2099
  });
2100
+ Object.defineProperty(exports, "createHmrTimingRecorder", {
2101
+ enumerable: true,
2102
+ get: function() {
2103
+ return createHmrTimingRecorder;
2104
+ }
2105
+ });
1697
2106
  Object.defineProperty(exports, "emitHmrTiming", {
1698
2107
  enumerable: true,
1699
2108
  get: function() {