weapp-tailwindcss 5.3.6 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +3 -3
  2. package/README.zh-CN.md +4 -4
  3. package/dist/bundlers/shared/framework-postcss.d.ts +3 -0
  4. package/dist/bundlers/shared/generator-css/result-helpers.d.ts +1 -1
  5. package/dist/bundlers/shared/generator-css/source-resolver/single-source.d.ts +1 -1
  6. package/dist/bundlers/shared/generator-css/types.d.ts +3 -1
  7. package/dist/bundlers/shared/source-candidates/snapshot.d.ts +19 -0
  8. package/dist/bundlers/shared/source-candidates/source-priority.d.ts +1 -0
  9. package/dist/bundlers/shared/source-candidates/types-and-cache.d.ts +1 -0
  10. package/dist/bundlers/shared/source-candidates/views.d.ts +12 -0
  11. package/dist/bundlers/shared/style-requests.d.ts +1 -0
  12. package/dist/bundlers/vite/bundle-state.d.ts +9 -1
  13. package/dist/bundlers/vite/capability-profile.d.ts +18 -0
  14. package/dist/bundlers/vite/generate-bundle/js-processing.d.ts +12 -0
  15. package/dist/bundlers/vite/hot-css-modules.d.ts +2 -2
  16. package/dist/bundlers/vite/shared/configured-css-entry-observer.d.ts +29 -0
  17. package/dist/bundlers/vite/shared/create-framework-plugins.d.ts +8 -0
  18. package/dist/bundlers/vite/shared/framework-css-generation-queue.d.ts +1 -0
  19. package/dist/bundlers/vite/shared/framework-hmr-module-version.d.ts +9 -0
  20. package/dist/bundlers/vite/shared/framework-runtime-utils.d.ts +5 -0
  21. package/dist/bundlers/vite/shared/framework-source-scan-session.d.ts +12 -2
  22. package/dist/compiler/compilation-session-pool.d.ts +1 -0
  23. package/dist/compiler/framework-compiler-session.d.ts +21 -0
  24. package/dist/compiler/index.d.ts +1 -0
  25. package/dist/{context-DTLRADfE.cjs → compiler-C93NfxSe.cjs} +859 -11
  26. package/dist/{context-4ittVpgt.js → compiler-qDa3phIv.js} +764 -5
  27. package/dist/context/handlers.d.ts +1 -1
  28. package/dist/core/compiler/compiler.d.ts +2 -0
  29. package/dist/core/compiler/generation-cache.d.ts +30 -0
  30. package/dist/core/compiler/generation-state.d.ts +17 -0
  31. package/dist/core/compiler/index.d.ts +2 -0
  32. package/dist/core/compiler/root-store.d.ts +38 -0
  33. package/dist/core/compiler/snapshot.d.ts +35 -0
  34. package/dist/core/compiler/source-fingerprint.d.ts +3 -0
  35. package/dist/core/compiler/transforms.d.ts +15 -0
  36. package/dist/core/compiler/types.d.ts +69 -0
  37. package/dist/core.cjs +9 -8
  38. package/dist/core.d.ts +2 -1
  39. package/dist/core.js +2 -2
  40. package/dist/framework/index.d.ts +3 -1
  41. package/dist/framework.cjs +6 -1
  42. package/dist/framework.js +6 -1
  43. package/dist/{generator-EnTXLBlK.js → generator-C0m2S4WI.js} +3 -2
  44. package/dist/{generator-DKiYbTFR.cjs → generator-CKJ6sj1f.cjs} +3 -2
  45. package/dist/generator.cjs +1 -1
  46. package/dist/generator.js +1 -1
  47. package/dist/{gulp-CUysZjW3.cjs → gulp-CW6JGqVn.cjs} +14 -16
  48. package/dist/{gulp-DwtrU4V1.js → gulp-e2iWsmEK.js} +7 -7
  49. package/dist/gulp.cjs +1 -1
  50. package/dist/gulp.js +1 -1
  51. package/dist/{hmr-timing-utmOgn6p.js → hmr-timing-DgMgwSce.js} +367 -289
  52. package/dist/{hmr-timing-Cvh5UgnM.cjs → hmr-timing-n7QQKFp7.cjs} +4 -4
  53. package/dist/index.cjs +4 -4
  54. package/dist/index.js +4 -4
  55. package/dist/{pipeline-helpers-CyVXL3h6.cjs → pipeline-helpers-DoLQy44Q.cjs} +6 -6
  56. package/dist/postcss.cjs +1 -1
  57. package/dist/postcss.js +1 -1
  58. package/dist/presets.cjs +2 -3
  59. package/dist/presets.js +1 -1
  60. package/dist/rspack.cjs +2 -2
  61. package/dist/rspack.js +2 -2
  62. package/dist/{source-candidate-scan-signature-CDrLxVKu.js → source-candidate-scan-signature-B0lOMiwB.js} +3 -3
  63. package/dist/{source-candidate-scan-signature-BNt7NrrI.cjs → source-candidate-scan-signature-Chb-Zrwt.cjs} +5 -5
  64. package/dist/{tailwindcss-CexDJBhx.cjs → tailwindcss-BGlJ1m1l.cjs} +763 -5
  65. package/dist/{tailwindcss-ChnpCv25.js → tailwindcss-BSKl0FTD.js} +1 -1
  66. package/dist/{transform-CL-UZW1U.cjs → transform-C6k9zTQR.cjs} +12 -4
  67. package/dist/{transform-Bfi1_VgN.js → transform-DQhgAarN.js} +12 -4
  68. package/dist/typedoc.export.d.ts +1 -0
  69. package/dist/types/index.d.ts +1 -0
  70. package/dist/uni-app-x/component-local-style.d.ts +2 -0
  71. package/dist/uni-app-x/transform.d.ts +1 -0
  72. package/dist/uni-app-x/vite/asset-task.d.ts +21 -0
  73. package/dist/uni-app-x/vite/plugin-options.d.ts +8 -0
  74. package/dist/uni-app-x/vite/web-local-style.d.ts +2 -1
  75. package/dist/uni-app-x/vite.d.ts +1 -21
  76. package/dist/{v4-generation-core-Dhsu9Deu.cjs → v4-generation-core-B2sUkkgq.cjs} +378 -300
  77. package/dist/{vite-DMX5zoID.cjs → vite-B0IPgrvM.cjs} +807 -200
  78. package/dist/{vite-DJkhb8n1.js → vite-CcEb2SOl.js} +774 -165
  79. package/dist/vite.cjs +1 -1
  80. package/dist/vite.js +1 -1
  81. package/dist/weapp-tw-css-generation-loader.cjs +1 -1
  82. package/dist/weapp-tw-css-import-rewrite-loader.cjs +7 -7
  83. package/dist/{webpack-Cpy_yggg.cjs → webpack-B5vc13U_.cjs} +33 -35
  84. package/dist/{webpack-CzhrD9p3.js → webpack-BPA5I79o.js} +7 -7
  85. package/dist/webpack.cjs +1 -1
  86. package/dist/webpack.js +1 -1
  87. package/dist/wxml/utils.d.ts +1 -1
  88. package/dist/{wxml-B7OAVpXJ.js → wxml-CvKyV69S.js} +10 -2
  89. package/dist/{wxml-PrK-8ARX.cjs → wxml-o-CUulAM.cjs} +40 -32
  90. package/package.json +12 -11
  91. package/dist/options-BJrtIQbH.cjs +0 -768
  92. package/dist/style-options-DW30H5PV.cjs +0 -82
@@ -1,9 +1,9 @@
1
- import { $ as hasTailwindSourceDirectives, A as transformGeneratorUserCss, At as toPosixPath, Ct as isFileExcludedByTailwindSourceEntries, F as stripUnmatchedTailwindSourceMediaCloseFragments, Ft as filterUnsupportedMiniProgramTailwindV4Candidates, G as extractGeneratedCssForUserLayerSelectors, H as filterApplyOnlyGeneratedCss, I as finalizeMiniProgramCss, J as preferScopedGeneratedCssRules, K as hasUserCssLayerBlocks, Lt as loadTailwindV4DesignSystem, N as removeTailwindV4GeneratorAtRules, Ot as resolveSourceScanPath, P as stripTailwindSourceMediaFragments, Q as hasTailwindRootDirectives, U as normalizeEmptyTailwindCustomVariants, V as removeTailwindV4GeneratedUserCssArtifacts, W as shouldFilterApplyOnlyGeneratedCss, X as hasTailwindApplyDirective, _t as normalizeConfigDirective, a as resolveGeneratorRuntimeBranch, at as resolveCssEntrySource, bt as FULL_SOURCE_SCAN_EXTENSION_RE, ct as createCssAppend, d as resolveTailwindV4SourceFromRuntime, dt as splitGeneratorPlaceholderCssBySourceOrder, ft as splitTailwindGeneratedCssByBanner, gt as stripTailwindBanners, ht as stripTailwindBanner, i as normalizeWeappTailwindcssGeneratorOptions, it as removeTailwindSourceDirectives, j as isCommentOnlyCss, kt as resolveTailwindV4CssSourceBase, lt as hasTailwindGeneratedCss, mt as stripGeneratorPlaceholderMarkers, ot as GENERATOR_PLACEHOLDER_MARKER_RE, p as resolveTailwindV4SourceOptionsFromRuntime, pt as splitTailwindV4GeneratedCssBySourceOrder, q as splitUserCssLayerBlocks, rt as parseImportRequest, s as shouldUseMiniProgramCssBranch, st as VITE_MARKER_RE, t as createWeappTailwindcssGenerator, tt as normalizeTailwindSourceDirectives, u as resolveTailwindV4Source$1, ut as hasTailwindGeneratedCssMarkers, vt as prependConfigDirective, wt as isFileMatchedByTailwindSourceEntries, z as removeUnsupportedMiniProgramAtRules } from "./generator-EnTXLBlK.js";
1
+ import { $ as hasTailwindSourceDirectives, A as transformGeneratorUserCss, At as toPosixPath, Ct as isFileExcludedByTailwindSourceEntries, F as stripUnmatchedTailwindSourceMediaCloseFragments, Ft as filterUnsupportedMiniProgramTailwindV4Candidates, G as extractGeneratedCssForUserLayerSelectors, H as filterApplyOnlyGeneratedCss, I as finalizeMiniProgramCss, J as preferScopedGeneratedCssRules, K as hasUserCssLayerBlocks, Lt as loadTailwindV4DesignSystem, N as removeTailwindV4GeneratorAtRules, Ot as resolveSourceScanPath, P as stripTailwindSourceMediaFragments, Q as hasTailwindRootDirectives, U as normalizeEmptyTailwindCustomVariants, V as removeTailwindV4GeneratedUserCssArtifacts, W as shouldFilterApplyOnlyGeneratedCss, X as hasTailwindApplyDirective, _t as normalizeConfigDirective, a as resolveGeneratorRuntimeBranch, at as resolveCssEntrySource, bt as FULL_SOURCE_SCAN_EXTENSION_RE, ct as createCssAppend, d as resolveTailwindV4SourceFromRuntime, dt as splitGeneratorPlaceholderCssBySourceOrder, ft as splitTailwindGeneratedCssByBanner, gt as stripTailwindBanners, ht as stripTailwindBanner, i as normalizeWeappTailwindcssGeneratorOptions, it as removeTailwindSourceDirectives, j as isCommentOnlyCss, kt as resolveTailwindV4CssSourceBase, lt as hasTailwindGeneratedCss, mt as stripGeneratorPlaceholderMarkers, ot as GENERATOR_PLACEHOLDER_MARKER_RE, p as resolveTailwindV4SourceOptionsFromRuntime, pt as splitTailwindV4GeneratedCssBySourceOrder, q as splitUserCssLayerBlocks, rt as parseImportRequest, s as shouldUseMiniProgramCssBranch, st as VITE_MARKER_RE, t as createWeappTailwindcssGenerator, tt as normalizeTailwindSourceDirectives, u as resolveTailwindV4Source$1, ut as hasTailwindGeneratedCssMarkers, vt as prependConfigDirective, wt as isFileMatchedByTailwindSourceEntries, z as removeUnsupportedMiniProgramAtRules } from "./generator-C0m2S4WI.js";
2
2
  import { o as transformCssMacroCss, r as hasCssMacroTailwindV4InternalAtRules, t as hasCssMacroStyleOptions } from "./auto-2dg_uhEJ.js";
3
3
  import { n as _defineProperty, t as omitUndefined } from "./object-B-8IHefx.js";
4
- import { _ as includesTailwindV4PreflightDirective, h as resolveTailwindV4EntriesFromCss, l as getRuntimeClassSetSignature, r as isUniAppXEnabled, v as collectCssInlineSourceCandidates } from "./tailwindcss-ChnpCv25.js";
5
- import { _ as md5Hash, g as traverse, h as babelParse, m as createDebug, p as replaceWxml, r as createAttributeMatcher } from "./wxml-B7OAVpXJ.js";
6
- import { r as resolveStyleOptionsFromContext } from "./context-4ittVpgt.js";
4
+ import { _ as includesTailwindV4PreflightDirective, h as resolveTailwindV4EntriesFromCss, l as getRuntimeClassSetSignature, r as isUniAppXEnabled, v as collectCssInlineSourceCandidates } from "./tailwindcss-BSKl0FTD.js";
5
+ import { _ as md5Hash, g as traverse, h as babelParse, m as createDebug, p as replaceWxml, r as createAttributeMatcher } from "./wxml-CvKyV69S.js";
6
+ import { i as resolveStyleOptionsFromContext, m as DefaultCompilationSession, t as createCompiler } from "./compiler-qDa3phIv.js";
7
7
  import { existsSync, readFileSync } from "node:fs";
8
8
  import path from "node:path";
9
9
  import process from "node:process";
@@ -13,6 +13,7 @@ import { LRUCache } from "lru-cache";
13
13
  import { readFile } from "node:fs/promises";
14
14
  import { Parser } from "htmlparser2";
15
15
  import { MappingChars2String, unescape } from "@weapp-core/escape";
16
+ import { Buffer } from "node:buffer";
16
17
  //#region src/bundlers/shared/source-candidates/scan-root.ts
17
18
  const TAILWIND_V4_IGNORED_CONTENT_DIRS = [
18
19
  ".git",
@@ -143,6 +144,62 @@ function resolveSourceCandidateScanFiles(options) {
143
144
  });
144
145
  }
145
146
  //#endregion
147
+ //#region src/bundlers/shared/source-candidates/source-priority.ts
148
+ function mergeSourcesByPriority(moduleSourceById, transformSourceById, cssSourceById, scanSourceById) {
149
+ const sources = /* @__PURE__ */ new Map();
150
+ for (const [id, source] of moduleSourceById) sources.set(id, source);
151
+ for (const [id, source] of transformSourceById) sources.set(id, source);
152
+ for (const [id, source] of cssSourceById) sources.set(id, source);
153
+ for (const [id, source] of scanSourceById) sources.set(id, source);
154
+ return sources;
155
+ }
156
+ //#endregion
157
+ //#region src/bundlers/shared/source-candidates/snapshot.ts
158
+ function createCandidateSnapshot(maps) {
159
+ return {
160
+ candidatesById: [...maps.candidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
161
+ cssCandidatesById: [...maps.cssCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
162
+ cssSourceById: [...maps.cssSourceById.entries()],
163
+ moduleCandidatesById: [...maps.moduleCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
164
+ moduleSourceById: [...maps.moduleSourceById.entries()],
165
+ scanCandidatesById: [...maps.scanCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
166
+ scanSourceById: [...maps.scanSourceById.entries()],
167
+ sourceById: [...mergeSourcesByPriority(maps.moduleSourceById, maps.transformSourceById, maps.cssSourceById, maps.scanSourceById).entries()],
168
+ transformCandidatesById: [...maps.transformCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
169
+ transformSourceById: [...maps.transformSourceById.entries()],
170
+ inlineExcludedCandidates: [...maps.inlineExcludedCandidates],
171
+ inlineIncludedCandidates: [...maps.inlineIncludedCandidates]
172
+ };
173
+ }
174
+ function restoreCandidateSnapshot(maps, snapshot, clear, recompute, setInlineCandidates) {
175
+ clear();
176
+ setInlineCandidates(new Set(snapshot.inlineIncludedCandidates), new Set(snapshot.inlineExcludedCandidates));
177
+ const restoreCandidates = (target, entries) => {
178
+ for (const [id, candidates] of entries ?? []) {
179
+ const candidateSet = new Set(candidates);
180
+ if (candidateSet.size > 0) target.set(id, candidateSet);
181
+ }
182
+ };
183
+ restoreCandidates(maps.scanCandidatesById, snapshot.scanCandidatesById ?? snapshot.candidatesById);
184
+ restoreCandidates(maps.transformCandidatesById, snapshot.transformCandidatesById);
185
+ restoreCandidates(maps.cssCandidatesById, snapshot.cssCandidatesById);
186
+ restoreCandidates(maps.moduleCandidatesById, snapshot.moduleCandidatesById);
187
+ const restoreSources = (target, entries) => {
188
+ for (const [id, source] of entries ?? []) target.set(id, source);
189
+ };
190
+ restoreSources(maps.scanSourceById, snapshot.scanSourceById ?? snapshot.sourceById);
191
+ restoreSources(maps.transformSourceById, snapshot.transformSourceById);
192
+ restoreSources(maps.cssSourceById, snapshot.cssSourceById);
193
+ restoreSources(maps.moduleSourceById, snapshot.moduleSourceById);
194
+ const ids = /* @__PURE__ */ new Set([
195
+ ...maps.scanCandidatesById.keys(),
196
+ ...maps.transformCandidatesById.keys(),
197
+ ...maps.cssCandidatesById.keys(),
198
+ ...maps.moduleCandidatesById.keys()
199
+ ]);
200
+ for (const id of ids) recompute(id);
201
+ }
202
+ //#endregion
146
203
  //#region src/tailwindcss/candidates.ts
147
204
  const SCRIPT_SOURCE_CANDIDATE_EXTENSIONS = /* @__PURE__ */ new Set([
148
205
  "js",
@@ -303,7 +360,53 @@ function diffCandidateSets(previous, next) {
303
360
  };
304
361
  }
305
362
  //#endregion
363
+ //#region src/bundlers/shared/source-candidates/views.ts
364
+ function isIncludedFile(id, isActiveModule, entries, excludeEntries) {
365
+ if (entries !== void 0 && (isActiveModule ? isFileExcludedByTailwindSourceEntries(id, entries) : entries.length === 0 || !isFileMatchedByTailwindSourceEntries(id, entries))) return false;
366
+ return !(excludeEntries?.length && isFileMatchedByTailwindSourceEntries(id, excludeEntries));
367
+ }
368
+ function collectCandidateValues(view, entries, excludeEntries) {
369
+ if (entries === void 0 && !excludeEntries?.length) {
370
+ const values = new Set(view.candidateCount.keys());
371
+ for (const candidate of view.inlineIncludedCandidates) values.add(candidate);
372
+ for (const candidate of view.inlineExcludedCandidates) values.delete(candidate);
373
+ return values;
374
+ }
375
+ const filtered = /* @__PURE__ */ new Set();
376
+ for (const [id, candidates] of view.candidatesById) {
377
+ if (!isIncludedFile(id, view.moduleCandidatesById.has(id), entries, excludeEntries)) continue;
378
+ for (const candidate of candidates) filtered.add(candidate);
379
+ }
380
+ for (const candidate of view.inlineIncludedCandidates) filtered.add(candidate);
381
+ for (const candidate of view.inlineExcludedCandidates) filtered.delete(candidate);
382
+ return filtered;
383
+ }
384
+ function collectCandidateSources(view, entries, excludeEntries) {
385
+ const sources = /* @__PURE__ */ new Map();
386
+ const addCandidateSource = (candidate, id) => {
387
+ let candidateSources = sources.get(candidate);
388
+ if (!candidateSources) {
389
+ candidateSources = /* @__PURE__ */ new Set();
390
+ sources.set(candidate, candidateSources);
391
+ }
392
+ if (id) candidateSources.add(id);
393
+ };
394
+ for (const [id, candidates] of view.candidatesById) {
395
+ if (!isIncludedFile(id, view.moduleCandidatesById.has(id), entries, excludeEntries)) continue;
396
+ for (const candidate of candidates) addCandidateSource(candidate, id);
397
+ }
398
+ for (const candidate of view.inlineIncludedCandidates) addCandidateSource(candidate);
399
+ for (const candidate of view.inlineExcludedCandidates) sources.delete(candidate);
400
+ return sources;
401
+ }
402
+ //#endregion
306
403
  //#region src/bundlers/shared/source-candidates/store.ts
404
+ const SOURCE_CANDIDATE_FILE_MEMO_MAX = 4096;
405
+ function areSetsEqual(left, right) {
406
+ if (!left || left.size !== right.size) return false;
407
+ for (const value of right) if (!left.has(value)) return false;
408
+ return true;
409
+ }
307
410
  function createSourceCandidateStore(options = {}) {
308
411
  const candidatesById = /* @__PURE__ */ new Map();
309
412
  const scanCandidatesById = /* @__PURE__ */ new Map();
@@ -315,15 +418,30 @@ function createSourceCandidateStore(options = {}) {
315
418
  const cssSourceById = /* @__PURE__ */ new Map();
316
419
  const moduleSourceById = /* @__PURE__ */ new Map();
317
420
  const candidateCount = /* @__PURE__ */ new Map();
421
+ const fileCandidateMemo = /* @__PURE__ */ new Map();
318
422
  let inlineIncludedCandidates = /* @__PURE__ */ new Set();
319
423
  let inlineExcludedCandidates = /* @__PURE__ */ new Set();
320
- async function resolveCandidates(source, extension) {
424
+ let revision = 0;
425
+ async function resolveCandidates(id, source, extension) {
426
+ const memoKey = `${cleanUrl(id)}\0${extension}`;
427
+ const memo = fileCandidateMemo.get(memoKey);
428
+ if (memo?.source === source) return new Set(memo.candidates);
321
429
  const contentCacheKey = createSourceCandidateContentCacheKey(extension, source, options.bareArbitraryValues, options.customAttributesEntities, options.disabledDefaultTemplateHandler, options.extractor);
322
430
  const cachedCandidates = sourceCandidateContentCache.get(contentCacheKey);
323
- if (cachedCandidates) return new Set(cachedCandidates);
324
- const nextCandidates = await extractCandidates(source, extension, options);
325
- sourceCandidateContentCache.set(contentCacheKey, [...nextCandidates]);
326
- return nextCandidates;
431
+ const nextCandidates = cachedCandidates ? new Set(cachedCandidates) : await extractCandidates(source, extension, options);
432
+ if (!cachedCandidates) sourceCandidateContentCache.set(contentCacheKey, [...nextCandidates]);
433
+ fileCandidateMemo.delete(memoKey);
434
+ fileCandidateMemo.set(memoKey, {
435
+ candidates: new Set(nextCandidates),
436
+ extension,
437
+ source
438
+ });
439
+ while (fileCandidateMemo.size > SOURCE_CANDIDATE_FILE_MEMO_MAX) {
440
+ const oldest = fileCandidateMemo.keys().next().value;
441
+ if (oldest === void 0) break;
442
+ fileCandidateMemo.delete(oldest);
443
+ }
444
+ return new Set(nextCandidates);
327
445
  }
328
446
  function isCandidateVisible(candidate) {
329
447
  if (inlineExcludedCandidates.has(candidate)) return false;
@@ -336,25 +454,29 @@ function createSourceCandidateStore(options = {}) {
336
454
  }
337
455
  async function sync(id, source) {
338
456
  const normalizedId = cleanUrl(id);
457
+ if (scanSourceById.get(normalizedId) !== source) revision++;
339
458
  scanSourceById.set(normalizedId, source);
340
- replaceScanLayer(normalizedId, await resolveCandidates(source, resolveSourceCandidateExtension(normalizedId)));
459
+ replaceScanLayer(normalizedId, await resolveCandidates(normalizedId, source, resolveSourceCandidateExtension(normalizedId)));
341
460
  }
342
461
  async function syncCss(id, source) {
343
462
  const normalizedId = cleanUrl(id);
463
+ if (cssSourceById.get(normalizedId) !== source) revision++;
344
464
  cssSourceById.set(normalizedId, source);
345
- replaceCssLayer(normalizedId, await resolveCandidates(source, "css"));
465
+ replaceCssLayer(normalizedId, await resolveCandidates(normalizedId, source, "css"));
346
466
  }
347
467
  async function syncModuleSource(id, source) {
348
468
  const normalizedId = cleanUrl(id);
469
+ if (moduleSourceById.get(normalizedId) !== source) revision++;
349
470
  moduleSourceById.set(normalizedId, source);
350
- const candidates = await resolveCandidates(source, resolveSourceCandidateExtension(normalizedId));
471
+ const candidates = await resolveCandidates(normalizedId, source, resolveSourceCandidateExtension(normalizedId));
351
472
  replaceModuleLayer(normalizedId, candidates);
352
473
  return new Set(candidates);
353
474
  }
354
475
  async function merge(id, source) {
355
476
  const normalizedId = cleanUrl(id);
477
+ if (transformSourceById.get(normalizedId) !== source) revision++;
356
478
  transformSourceById.set(normalizedId, source);
357
- replaceTransformLayer(normalizedId, await resolveCandidates(source, resolveSourceCandidateExtension(normalizedId)));
479
+ replaceTransformLayer(normalizedId, await resolveCandidates(normalizedId, source, resolveSourceCandidateExtension(normalizedId)));
358
480
  }
359
481
  async function syncFile(id) {
360
482
  const normalizedId = cleanUrl(id);
@@ -372,7 +494,8 @@ function createSourceCandidateStore(options = {}) {
372
494
  const normalizedId = cleanUrl(id);
373
495
  const previousFileCandidates = new Set(candidatesById.get(normalizedId) ?? []);
374
496
  const extension = resolveSourceCandidateExtension(normalizedId);
375
- const nextCandidates = await resolveCandidates(source, extension);
497
+ if (scanSourceById.get(normalizedId) !== source || extension !== "css" && (transformSourceById.has(normalizedId) || cssSourceById.has(normalizedId) || moduleSourceById.has(normalizedId))) revision++;
498
+ const nextCandidates = await resolveCandidates(normalizedId, source, extension);
376
499
  const affectedCandidates = /* @__PURE__ */ new Set([...previousFileCandidates, ...nextCandidates]);
377
500
  const previousVisibleCandidates = collectVisibleCandidates(affectedCandidates);
378
501
  if (extension !== "css") {
@@ -413,6 +536,8 @@ function createSourceCandidateStore(options = {}) {
413
536
  function replaceFinal(id, nextCandidates) {
414
537
  const normalizedId = cleanUrl(id);
415
538
  const previousCandidates = candidatesById.get(normalizedId);
539
+ if (areSetsEqual(previousCandidates, nextCandidates)) return;
540
+ revision++;
416
541
  if (previousCandidates) {
417
542
  removeCandidateSet$1(candidateCount, previousCandidates);
418
543
  candidatesById.delete(normalizedId);
@@ -455,11 +580,15 @@ function createSourceCandidateStore(options = {}) {
455
580
  ]));
456
581
  }
457
582
  function syncInline(inlineCandidates) {
458
- inlineIncludedCandidates = new Set(inlineCandidates?.included ?? []);
459
- inlineExcludedCandidates = new Set(inlineCandidates?.excluded ?? []);
583
+ const nextIncluded = new Set(inlineCandidates?.included ?? []);
584
+ const nextExcluded = new Set(inlineCandidates?.excluded ?? []);
585
+ if (!areSetsEqual(inlineIncludedCandidates, nextIncluded) || !areSetsEqual(inlineExcludedCandidates, nextExcluded)) revision++;
586
+ inlineIncludedCandidates = nextIncluded;
587
+ inlineExcludedCandidates = nextExcluded;
460
588
  }
461
589
  function remove(id) {
462
590
  const normalizedId = cleanUrl(id);
591
+ const hadState = candidatesById.has(normalizedId) || scanCandidatesById.has(normalizedId) || transformCandidatesById.has(normalizedId) || cssCandidatesById.has(normalizedId) || moduleCandidatesById.has(normalizedId) || scanSourceById.has(normalizedId) || transformSourceById.has(normalizedId) || cssSourceById.has(normalizedId) || moduleSourceById.has(normalizedId);
463
592
  const affectedCandidates = new Set(candidatesById.get(normalizedId) ?? []);
464
593
  const previousVisibleCandidates = collectVisibleCandidates(affectedCandidates);
465
594
  scanCandidatesById.delete(normalizedId);
@@ -470,10 +599,15 @@ function createSourceCandidateStore(options = {}) {
470
599
  transformSourceById.delete(normalizedId);
471
600
  cssSourceById.delete(normalizedId);
472
601
  moduleSourceById.delete(normalizedId);
602
+ for (const key of fileCandidateMemo.keys()) if (key.startsWith(`${normalizedId}\0`)) fileCandidateMemo.delete(key);
473
603
  const previousCandidates = candidatesById.get(normalizedId);
474
- if (!previousCandidates) return diffCandidateSets(previousVisibleCandidates, /* @__PURE__ */ new Set());
604
+ if (!previousCandidates) {
605
+ if (hadState) revision++;
606
+ return diffCandidateSets(previousVisibleCandidates, /* @__PURE__ */ new Set());
607
+ }
475
608
  removeCandidateSet$1(candidateCount, previousCandidates);
476
609
  candidatesById.delete(normalizedId);
610
+ revision++;
477
611
  return diffCandidateSets(previousVisibleCandidates, collectVisibleCandidates(affectedCandidates));
478
612
  }
479
613
  function source(id) {
@@ -481,49 +615,37 @@ function createSourceCandidateStore(options = {}) {
481
615
  return scanSourceById.get(normalizedId) ?? cssSourceById.get(normalizedId) ?? transformSourceById.get(normalizedId) ?? moduleSourceById.get(normalizedId);
482
616
  }
483
617
  function sources() {
484
- return mergeSourcesByPriority().entries();
618
+ return mergeSourcesByPriority(moduleSourceById, transformSourceById, cssSourceById, scanSourceById).entries();
485
619
  }
486
620
  function values() {
487
- const values = /* @__PURE__ */ new Set([...candidateCount.keys(), ...inlineIncludedCandidates]);
488
- for (const candidate of inlineExcludedCandidates) values.delete(candidate);
489
- return values;
621
+ return collectCandidateValues({
622
+ candidatesById,
623
+ moduleCandidatesById,
624
+ candidateCount,
625
+ inlineIncludedCandidates,
626
+ inlineExcludedCandidates
627
+ });
490
628
  }
491
629
  function valuesForEntries(entries, options = {}) {
492
- if (entries === void 0) {
493
- if (!options.excludeEntries?.length) return values();
494
- }
495
- const filtered = /* @__PURE__ */ new Set();
496
- for (const [id, candidates] of candidatesById) {
497
- const isActiveModule = moduleCandidatesById.has(id);
498
- if (entries !== void 0 && (isActiveModule ? isFileExcludedByTailwindSourceEntries(id, entries) : entries.length === 0 || !isFileMatchedByTailwindSourceEntries(id, entries))) continue;
499
- if (options.excludeEntries?.length && isFileMatchedByTailwindSourceEntries(id, options.excludeEntries)) continue;
500
- for (const candidate of candidates) filtered.add(candidate);
501
- }
502
- for (const candidate of inlineIncludedCandidates) filtered.add(candidate);
503
- for (const candidate of inlineExcludedCandidates) filtered.delete(candidate);
504
- return filtered;
630
+ return collectCandidateValues({
631
+ candidatesById,
632
+ moduleCandidatesById,
633
+ candidateCount,
634
+ inlineIncludedCandidates,
635
+ inlineExcludedCandidates
636
+ }, entries, options.excludeEntries);
505
637
  }
506
638
  function sourcesForEntries(entries, options = {}) {
507
- const sources = /* @__PURE__ */ new Map();
508
- const addCandidateSource = (candidate, id) => {
509
- let candidateSources = sources.get(candidate);
510
- if (!candidateSources) {
511
- candidateSources = /* @__PURE__ */ new Set();
512
- sources.set(candidate, candidateSources);
513
- }
514
- if (id) candidateSources.add(id);
515
- };
516
- for (const [id, candidates] of candidatesById) {
517
- const isActiveModule = moduleCandidatesById.has(id);
518
- if (entries !== void 0 && (isActiveModule ? isFileExcludedByTailwindSourceEntries(id, entries) : entries.length === 0 || !isFileMatchedByTailwindSourceEntries(id, entries))) continue;
519
- if (options.excludeEntries?.length && isFileMatchedByTailwindSourceEntries(id, options.excludeEntries)) continue;
520
- for (const candidate of candidates) addCandidateSource(candidate, id);
521
- }
522
- for (const candidate of inlineIncludedCandidates) addCandidateSource(candidate, void 0);
523
- for (const candidate of inlineExcludedCandidates) sources.delete(candidate);
524
- return sources;
639
+ return collectCandidateSources({
640
+ candidatesById,
641
+ moduleCandidatesById,
642
+ candidateCount,
643
+ inlineIncludedCandidates,
644
+ inlineExcludedCandidates
645
+ }, entries, options.excludeEntries);
525
646
  }
526
647
  function clear() {
648
+ if (candidateCount.size > 0 || fileCandidateMemo.size > 0 || inlineIncludedCandidates.size > 0 || inlineExcludedCandidates.size > 0) revision++;
527
649
  candidatesById.clear();
528
650
  scanCandidatesById.clear();
529
651
  transformCandidatesById.clear();
@@ -536,71 +658,56 @@ function createSourceCandidateStore(options = {}) {
536
658
  candidateCount.clear();
537
659
  inlineIncludedCandidates.clear();
538
660
  inlineExcludedCandidates.clear();
661
+ fileCandidateMemo.clear();
539
662
  }
540
663
  function clearScan() {
664
+ const hadState = scanCandidatesById.size > 0 || inlineIncludedCandidates.size > 0 || inlineExcludedCandidates.size > 0;
541
665
  for (const id of scanCandidatesById.keys()) {
542
666
  scanCandidatesById.delete(id);
543
667
  recompute(id);
544
668
  }
545
669
  inlineIncludedCandidates.clear();
546
670
  inlineExcludedCandidates.clear();
671
+ if (hadState) revision++;
547
672
  }
548
673
  function resetScan() {
674
+ const hadState = inlineIncludedCandidates.size > 0 || inlineExcludedCandidates.size > 0;
549
675
  inlineIncludedCandidates.clear();
550
676
  inlineExcludedCandidates.clear();
677
+ if (hadState) revision++;
551
678
  }
552
679
  function snapshot() {
553
- return {
554
- candidatesById: [...candidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
555
- cssCandidatesById: [...cssCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
556
- cssSourceById: [...cssSourceById.entries()],
557
- moduleCandidatesById: [...moduleCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
558
- moduleSourceById: [...moduleSourceById.entries()],
559
- scanCandidatesById: [...scanCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
560
- scanSourceById: [...scanSourceById.entries()],
561
- sourceById: [...mergeSourcesByPriority().entries()],
562
- transformCandidatesById: [...transformCandidatesById.entries()].map(([id, candidates]) => [id, [...candidates]]),
563
- transformSourceById: [...transformSourceById.entries()],
564
- inlineExcludedCandidates: [...inlineExcludedCandidates],
565
- inlineIncludedCandidates: [...inlineIncludedCandidates]
566
- };
680
+ return createCandidateSnapshot({
681
+ candidatesById,
682
+ scanCandidatesById,
683
+ transformCandidatesById,
684
+ cssCandidatesById,
685
+ moduleCandidatesById,
686
+ scanSourceById,
687
+ transformSourceById,
688
+ cssSourceById,
689
+ moduleSourceById,
690
+ inlineIncludedCandidates,
691
+ inlineExcludedCandidates
692
+ });
567
693
  }
568
694
  function restore(snapshot) {
569
- clear();
570
- inlineExcludedCandidates = new Set(snapshot.inlineExcludedCandidates);
571
- inlineIncludedCandidates = new Set(snapshot.inlineIncludedCandidates);
572
- const scanEntries = snapshot.scanCandidatesById ?? snapshot.candidatesById;
573
- for (const [id, candidates] of scanEntries) {
574
- const candidateSet = new Set(candidates);
575
- if (candidateSet.size === 0) continue;
576
- scanCandidatesById.set(id, candidateSet);
577
- }
578
- for (const [id, candidates] of snapshot.transformCandidatesById ?? []) {
579
- const candidateSet = new Set(candidates);
580
- if (candidateSet.size === 0) continue;
581
- transformCandidatesById.set(id, candidateSet);
582
- }
583
- for (const [id, candidates] of snapshot.cssCandidatesById ?? []) {
584
- const candidateSet = new Set(candidates);
585
- if (candidateSet.size === 0) continue;
586
- cssCandidatesById.set(id, candidateSet);
587
- }
588
- for (const [id, candidates] of snapshot.moduleCandidatesById ?? []) {
589
- const candidateSet = new Set(candidates);
590
- if (candidateSet.size === 0) continue;
591
- moduleCandidatesById.set(id, candidateSet);
592
- }
593
- for (const [id, source] of snapshot.scanSourceById ?? snapshot.sourceById ?? []) scanSourceById.set(id, source);
594
- for (const [id, source] of snapshot.transformSourceById ?? []) transformSourceById.set(id, source);
595
- for (const [id, source] of snapshot.cssSourceById ?? []) cssSourceById.set(id, source);
596
- for (const [id, source] of snapshot.moduleSourceById ?? []) moduleSourceById.set(id, source);
597
- const ids = /* @__PURE__ */ new Set([
598
- ...scanCandidatesById.keys(),
599
- ...transformCandidatesById.keys(),
600
- ...cssCandidatesById.keys(),
601
- ...moduleCandidatesById.keys()
602
- ]);
603
- for (const id of ids) recompute(id);
695
+ restoreCandidateSnapshot({
696
+ candidatesById,
697
+ scanCandidatesById,
698
+ transformCandidatesById,
699
+ cssCandidatesById,
700
+ moduleCandidatesById,
701
+ scanSourceById,
702
+ transformSourceById,
703
+ cssSourceById,
704
+ moduleSourceById,
705
+ inlineIncludedCandidates,
706
+ inlineExcludedCandidates
707
+ }, snapshot, clear, recompute, (included, excluded) => {
708
+ inlineIncludedCandidates = included;
709
+ inlineExcludedCandidates = excluded;
710
+ });
604
711
  }
605
712
  return {
606
713
  syncSource: sync,
@@ -624,16 +731,9 @@ function createSourceCandidateStore(options = {}) {
624
731
  restore,
625
732
  clearScan,
626
733
  resetScan,
627
- clear
734
+ clear,
735
+ getRevision: () => revision
628
736
  };
629
- function mergeSourcesByPriority() {
630
- const sources = /* @__PURE__ */ new Map();
631
- for (const [id, source] of moduleSourceById) sources.set(id, source);
632
- for (const [id, source] of transformSourceById) sources.set(id, source);
633
- for (const [id, source] of cssSourceById) sources.set(id, source);
634
- for (const [id, source] of scanSourceById) sources.set(id, source);
635
- return sources;
636
- }
637
737
  }
638
738
  //#endregion
639
739
  //#region src/bundlers/shared/source-candidates/collector.ts
@@ -677,48 +777,6 @@ function createGenerationArtifact(fragments, options) {
677
777
  });
678
778
  }
679
779
  //#endregion
680
- //#region src/compiler/candidate-index.ts
681
- var CandidateIndex = class {
682
- constructor() {
683
- _defineProperty(this, "candidatesBySource", /* @__PURE__ */ new Map());
684
- }
685
- sync(sourceId, candidates) {
686
- const previous = this.candidatesBySource.get(sourceId) ?? /* @__PURE__ */ new Set();
687
- const next = new Set(candidates);
688
- const addedCandidates = new Set([...next].filter((candidate) => !previous.has(candidate)));
689
- const removedCandidates = new Set([...previous].filter((candidate) => !next.has(candidate)));
690
- this.candidatesBySource.set(sourceId, next);
691
- return {
692
- sourceId,
693
- addedCandidates,
694
- removedCandidates
695
- };
696
- }
697
- remove(sourceId) {
698
- const previous = this.candidatesBySource.get(sourceId) ?? /* @__PURE__ */ new Set();
699
- this.candidatesBySource.delete(sourceId);
700
- return {
701
- sourceId,
702
- addedCandidates: /* @__PURE__ */ new Set(),
703
- removedCandidates: new Set(previous)
704
- };
705
- }
706
- values() {
707
- const values = /* @__PURE__ */ new Set();
708
- for (const candidates of this.candidatesBySource.values()) for (const candidate of candidates) values.add(candidate);
709
- return values;
710
- }
711
- get(sourceId) {
712
- return new Set(this.candidatesBySource.get(sourceId) ?? []);
713
- }
714
- entries() {
715
- return new Map([...this.candidatesBySource].map(([sourceId, candidates]) => [sourceId, new Set(candidates)]));
716
- }
717
- clear() {
718
- this.candidatesBySource.clear();
719
- }
720
- };
721
- //#endregion
722
780
  //#region src/compiler/compilation-scope-graph.ts
723
781
  function sourceNodeId(sourceId) {
724
782
  return `source:${sourceId}`;
@@ -901,124 +959,6 @@ function runCompilerOwnerDisposal(owner, dispose) {
901
959
  return disposal;
902
960
  }
903
961
  //#endregion
904
- //#region src/compiler/invalidation.ts
905
- function resolveInvalidatedScopes(graph, changes) {
906
- const invalidatedScopes = /* @__PURE__ */ new Set();
907
- const visit = (sourceId, visited) => {
908
- if (visited.has(sourceId)) return;
909
- visited.add(sourceId);
910
- const node = graph.getNode(sourceId);
911
- if (node) invalidatedScopes.add(node.scope.id);
912
- for (const dependent of graph.getDependents(sourceId)) visit(dependent, visited);
913
- };
914
- for (const change of changes) visit(change.sourceId, /* @__PURE__ */ new Set());
915
- return invalidatedScopes;
916
- }
917
- //#endregion
918
- //#region src/compiler/source-graph.ts
919
- var SourceGraph = class {
920
- constructor() {
921
- _defineProperty(this, "edges", /* @__PURE__ */ new Map());
922
- _defineProperty(this, "nodes", /* @__PURE__ */ new Map());
923
- }
924
- replace(nodes, edges) {
925
- this.clear();
926
- for (const node of nodes) this.nodes.set(node.id, {
927
- ...node,
928
- scope: { ...node.scope }
929
- });
930
- for (const edge of edges) {
931
- if (!this.nodes.has(edge.from) || !this.nodes.has(edge.to)) throw new Error(`编译图边引用了不存在的节点:${edge.from} -> ${edge.to}`);
932
- this.edges.set(this.edgeKey(edge), { ...edge });
933
- }
934
- }
935
- getNode(id) {
936
- const node = this.nodes.get(id);
937
- return node ? {
938
- ...node,
939
- scope: { ...node.scope }
940
- } : void 0;
941
- }
942
- getNodes() {
943
- return [...this.nodes.values()].map((node) => ({
944
- ...node,
945
- scope: { ...node.scope }
946
- }));
947
- }
948
- getEdges() {
949
- return [...this.edges.values()].map((edge) => ({ ...edge }));
950
- }
951
- getDependents(id) {
952
- return this.getEdges().filter((edge) => edge.to === id).map((edge) => edge.from);
953
- }
954
- clear() {
955
- this.edges.clear();
956
- this.nodes.clear();
957
- }
958
- edgeKey(edge) {
959
- return `${edge.kind}\0${edge.from}\0${edge.to}`;
960
- }
961
- };
962
- //#endregion
963
- //#region src/compiler/session.ts
964
- var DefaultCompilationSession = class {
965
- constructor() {
966
- _defineProperty(this, "candidateIndex", new CandidateIndex());
967
- _defineProperty(this, "graph", new SourceGraph());
968
- _defineProperty(this, "retainedCandidates", /* @__PURE__ */ new Set());
969
- _defineProperty(this, "validatedClassSet", /* @__PURE__ */ new Set());
970
- _defineProperty(this, "invalidatedScopes", /* @__PURE__ */ new Set());
971
- _defineProperty(this, "revision", 0);
972
- }
973
- update(snapshot) {
974
- const changes = [...snapshot.changes ?? []];
975
- const invalidatedScopes = resolveInvalidatedScopes(this.graph, changes);
976
- this.graph.replace(snapshot.nodes, snapshot.edges);
977
- for (const [sourceId, candidates] of snapshot.candidatesBySource ?? []) {
978
- const change = this.candidateIndex.sync(sourceId, candidates);
979
- if (change.addedCandidates.size > 0 || change.removedCandidates.size > 0) changes.push(change);
980
- }
981
- for (const change of changes) if ("type" in change && change.type === "source-removed") this.candidateIndex.remove(change.sourceId);
982
- const currentCandidates = this.candidateIndex.values();
983
- if (snapshot.preserveDeletedCss) for (const candidate of currentCandidates) this.retainedCandidates.add(candidate);
984
- else {
985
- this.retainedCandidates.clear();
986
- for (const candidate of currentCandidates) this.retainedCandidates.add(candidate);
987
- }
988
- if (snapshot.validatedClassSet !== void 0) this.validatedClassSet = new Set(snapshot.validatedClassSet);
989
- else if (!snapshot.preserveDeletedCss) this.validatedClassSet = new Set([...this.validatedClassSet].filter((candidate) => this.retainedCandidates.has(candidate)));
990
- this.revision += 1;
991
- for (const scopeId of resolveInvalidatedScopes(this.graph, changes)) invalidatedScopes.add(scopeId);
992
- this.invalidatedScopes = invalidatedScopes;
993
- return this.createResult();
994
- }
995
- commitValidation(revision, validatedClassSet, graph) {
996
- if (revision !== this.revision) throw new Error(`不能向编译 revision ${this.revision} 提交 revision ${revision} 的 classSet。`);
997
- if (graph) this.graph.replace(graph.nodes, graph.edges);
998
- this.validatedClassSet = new Set(validatedClassSet);
999
- return this.createResult();
1000
- }
1001
- createResult() {
1002
- return {
1003
- revision: this.revision,
1004
- candidates: new Set(this.retainedCandidates),
1005
- candidatesBySource: this.candidateIndex.entries(),
1006
- validatedClassSet: new Set(this.validatedClassSet),
1007
- invalidatedScopes: new Set(this.invalidatedScopes),
1008
- graphEdges: this.graph.getEdges(),
1009
- graphNodes: this.graph.getNodes()
1010
- };
1011
- }
1012
- dispose() {
1013
- this.candidateIndex.clear();
1014
- this.graph.clear();
1015
- this.retainedCandidates.clear();
1016
- this.validatedClassSet.clear();
1017
- this.invalidatedScopes.clear();
1018
- this.revision = 0;
1019
- }
1020
- };
1021
- //#endregion
1022
962
  //#region src/compiler/compilation-session-pool.ts
1023
963
  const COMPILATION_SCOPE_CACHE_MAX = 128;
1024
964
  function cloneScopeSource(source) {
@@ -1433,6 +1373,98 @@ var AssetEmissionPlan = class {
1433
1373
  }
1434
1374
  };
1435
1375
  //#endregion
1376
+ //#region src/compiler/framework-compiler-session.ts
1377
+ /**
1378
+ * 官方 bundler 共享的 compiler 生命周期边界。
1379
+ *
1380
+ * bundler 继续拥有模块图和 scope 投影;本层只负责把逻辑 source root
1381
+ * 映射到一个长期复用的 compiler,并保证 root 删除与 owner 释放可等待。
1382
+ */
1383
+ var FrameworkCompilerSession = class {
1384
+ constructor(options) {
1385
+ _defineProperty(this, "compiler", void 0);
1386
+ _defineProperty(this, "scopeRoots", /* @__PURE__ */ new Map());
1387
+ _defineProperty(this, "activeRoots", /* @__PURE__ */ new Set());
1388
+ _defineProperty(this, "transactionId", 0);
1389
+ _defineProperty(this, "disposed", false);
1390
+ this.compiler = createCompiler(options);
1391
+ }
1392
+ rootId(scopeId, sourceId) {
1393
+ return `framework:${this.encode(scopeId)}:${this.encode(sourceId)}`;
1394
+ }
1395
+ async generate(scopeId, sourceId, source, request) {
1396
+ if (this.disposed) throw new Error("FrameworkCompilerSession 已释放。");
1397
+ const stableId = this.rootId(scopeId, sourceId);
1398
+ const id = this.activeRoots.has(stableId) ? `${stableId}:transaction-${++this.transactionId}` : stableId;
1399
+ let roots = this.scopeRoots.get(scopeId);
1400
+ if (!roots) {
1401
+ roots = /* @__PURE__ */ new Set();
1402
+ this.scopeRoots.set(scopeId, roots);
1403
+ }
1404
+ roots.add(stableId);
1405
+ this.activeRoots.add(stableId);
1406
+ try {
1407
+ return await this.compiler.generate({
1408
+ ...request,
1409
+ id,
1410
+ source: {
1411
+ ...source,
1412
+ dependencies: source.dependencies ?? []
1413
+ }
1414
+ });
1415
+ } finally {
1416
+ this.activeRoots.delete(stableId);
1417
+ if (id !== stableId) await this.compiler.remove(id);
1418
+ }
1419
+ }
1420
+ async syncScope(scopeId, sourceIds) {
1421
+ if (this.disposed) return;
1422
+ const roots = this.scopeRoots.get(scopeId);
1423
+ if (!roots) return;
1424
+ const active = new Set([...sourceIds].map((sourceId) => this.rootId(scopeId, sourceId)));
1425
+ const removed = [...roots].filter((rootId) => !active.has(rootId));
1426
+ await Promise.all(removed.map((rootId) => this.compiler.remove(rootId)));
1427
+ for (const rootId of removed) roots.delete(rootId);
1428
+ if (roots.size === 0) this.scopeRoots.delete(scopeId);
1429
+ }
1430
+ async removeScope(scopeId) {
1431
+ const roots = this.scopeRoots.get(scopeId);
1432
+ if (!roots) return;
1433
+ this.scopeRoots.delete(scopeId);
1434
+ await Promise.all([...roots].map((rootId) => this.compiler.remove(rootId)));
1435
+ }
1436
+ invalidate(ids) {
1437
+ return this.compiler.invalidate(ids);
1438
+ }
1439
+ mergeSnapshots(snapshots) {
1440
+ return this.compiler.mergeSnapshots(snapshots);
1441
+ }
1442
+ dispose() {
1443
+ if (this.disposed) return Promise.resolve();
1444
+ this.disposed = true;
1445
+ this.scopeRoots.clear();
1446
+ return this.compiler.dispose();
1447
+ }
1448
+ encode(value) {
1449
+ return Buffer.from(value, "utf8").toString("base64url");
1450
+ }
1451
+ };
1452
+ const frameworkCompilerSessions = /* @__PURE__ */ new WeakMap();
1453
+ function getFrameworkCompilerSession(owner, options) {
1454
+ let session = frameworkCompilerSessions.get(owner);
1455
+ if (!session) {
1456
+ session = new FrameworkCompilerSession(options);
1457
+ frameworkCompilerSessions.set(owner, session);
1458
+ }
1459
+ return session;
1460
+ }
1461
+ function disposeFrameworkCompilerSession(owner) {
1462
+ const session = frameworkCompilerSessions.get(owner);
1463
+ if (!session) return Promise.resolve();
1464
+ frameworkCompilerSessions.delete(owner);
1465
+ return session.dispose();
1466
+ }
1467
+ //#endregion
1436
1468
  //#region src/compiler/mode.ts
1437
1469
  const COMPILER_MODE_ENV = "WEAPP_TAILWINDCSS_COMPILER";
1438
1470
  function resolveCompilerMode(env = process.env) {
@@ -1567,6 +1599,7 @@ function disposeCompilerShadowReportSession(owner) {
1567
1599
  async function disposeCompilerOwnerResources(owner) {
1568
1600
  disposeCompilationChangeCoordinator(owner);
1569
1601
  await disposeCompilationSessionPool(owner);
1602
+ await disposeFrameworkCompilerSession(owner);
1570
1603
  disposeTailwindGenerationSessionPool(owner);
1571
1604
  disposeCompilerShadowReportSession(owner);
1572
1605
  }
@@ -2633,6 +2666,7 @@ function parseBundlerGeneratedCssMarkerBlocks(source) {
2633
2666
  //#region src/bundlers/shared/style-requests.ts
2634
2667
  const SOURCE_STYLE_EXT_RE = /\.(?:css|scss|sass|less|styl|stylus|pcss|postcss)$/i;
2635
2668
  const SOURCE_PREPROCESSOR_EXT_RE = /\.(?:scss|sass|less|styl|stylus)$/i;
2669
+ const SFC_SOURCE_EXT_RE = /\.(?:vue|uvue|nvue|svelte|mpx)$/i;
2636
2670
  const INLINE_PREPROCESSOR_LANG_RE = /(?:^|[.?&])lang\.(?:scss|sass|less|styl|stylus)(?:[.&]|$)/i;
2637
2671
  const STYLE_QUERY_RE = /(?:^|&)type=styles?(?:&|$)/;
2638
2672
  const VUE_STYLE_QUERY_RE = /(?:^|&)type=style(?:&|$)/;
@@ -2658,6 +2692,10 @@ function isSourceStyleRequest(request) {
2658
2692
  const query = normalized.slice(queryIndex + 1);
2659
2693
  return STYLE_QUERY_RE.test(query) || STYLE_LANG_QUERY_RE.test(query);
2660
2694
  }
2695
+ function isSfcStyleSourceRequest(request) {
2696
+ if (typeof request !== "string" || request.length === 0) return false;
2697
+ return SFC_SOURCE_EXT_RE.test(stripRequestQuery(request));
2698
+ }
2661
2699
  function isSourcePreprocessorRequest(request, lang) {
2662
2700
  if (typeof lang === "string" && SOURCE_PREPROCESSOR_EXT_RE.test(`.${lang}`)) return true;
2663
2701
  if (typeof request !== "string" || request.length === 0) return false;
@@ -3098,11 +3136,18 @@ async function adaptGeneratedCssWithFrameworkPipeline(owner, generated, options)
3098
3136
  }
3099
3137
  async function adaptGeneratedCssWithFrameworkRootPipeline(owner, generated, options) {
3100
3138
  const handlerOptions = createGeneratedCssHandlerOptions(owner, options.cssHandlerOptions, options.file);
3101
- const handled = typeof options.styleHandler.transformRoot === "function" ? composeGenerationArtifact(await createStylePlatformAdapter({
3139
+ const replayArtifact = createFrameworkReplayArtifact(generated, options);
3140
+ const handled = options.compiler && options.snapshot ? composeGenerationArtifact(await (async () => {
3141
+ for (const fragment of replayArtifact.fragments) {
3142
+ fragment.root = (await options.compiler.transformCssRoot(fragment.root, options.snapshot, handlerOptions)).root.clone();
3143
+ fragment.stage = "framework-processed";
3144
+ }
3145
+ return replayArtifact;
3146
+ })()) : typeof options.styleHandler.transformRoot === "function" ? composeGenerationArtifact(await createStylePlatformAdapter({
3102
3147
  id: generated.target === "web" ? "web" : "mini-program",
3103
3148
  styleHandler: options.styleHandler,
3104
3149
  styleOptions: handlerOptions
3105
- }).transform(createFrameworkReplayArtifact(generated, options), { stage: "framework-processed" })) : await options.styleHandler(generated.css, handlerOptions);
3150
+ }).transform(replayArtifact, { stage: "framework-processed" })) : await options.styleHandler(generated.css, handlerOptions);
3106
3151
  const preflightMode = generated.metadata?.preflightMode;
3107
3152
  const injectPreflight = preflightMode?.inject ?? options.cssHandlerOptions.isMainChunk;
3108
3153
  const preservePreflight = preflightMode?.preserve ?? options.cssHandlerOptions.isMainChunk;
@@ -3603,7 +3648,7 @@ function collectLocalStyleImportFiles(source, base) {
3603
3648
  }
3604
3649
  function extractStyleDirectiveSourcesDeep(source, sourceFile, seen) {
3605
3650
  const ownSources = extractStyleDirectiveSources(source);
3606
- if (ownSources.length > 0) return ownSources.map((styleSource) => ({
3651
+ if (ownSources.some((styleSource) => hasTailwindRootDirectives(styleSource, { importFallback: true }))) return ownSources.map((styleSource) => ({
3607
3652
  source: styleSource,
3608
3653
  file: sourceFile
3609
3654
  }));
@@ -3618,7 +3663,10 @@ function extractStyleDirectiveSourcesDeep(source, sourceFile, seen) {
3618
3663
  sources.push(...extractStyleDirectiveSourcesDeep(importedSource, normalizedImportedFile, seen));
3619
3664
  } catch {}
3620
3665
  }
3621
- return sources;
3666
+ return sources.length > 0 ? sources : ownSources.map((styleSource) => ({
3667
+ source: styleSource,
3668
+ file: sourceFile
3669
+ }));
3622
3670
  }
3623
3671
  function resolveSourceSideCssEntrySource(file, sourceOptions, resolveOptions = {}) {
3624
3672
  for (const sourceFile of createSourceStylePathCandidates(file, sourceOptions)) try {
@@ -4087,16 +4135,16 @@ function createTailwindV4CssSourceResolver(sourceOptions, generatorOptions) {
4087
4135
  css: prependConfigDirective(source.css, generatorOptions.config)
4088
4136
  } : source);
4089
4137
  }
4090
- async function resolveTailwindV4SourceSideEntrySource(resolvedEntrySource, sourceOptions, generatorOptions, file) {
4138
+ async function resolveTailwindV4SourceSideEntrySource(resolvedEntrySource, sourceOptions, generatorOptions, file, currentCss) {
4091
4139
  if (!resolvedEntrySource) return;
4092
4140
  const resolvedSourceOptions = omitUndefined(sourceOptions);
4093
4141
  const config = resolveExistingConfigPath(resolvedEntrySource.config, resolvedEntrySource.configRequest, file, {
4094
4142
  ...resolvedSourceOptions,
4095
4143
  sourceFile: resolvedEntrySource.file
4096
4144
  });
4097
- const css = createTailwindV4SourceReferenceSource(normalizeConfigDirective(prependConfigDirective(resolvedEntrySource.css, generatorOptions?.config), config), resolvedSourceOptions);
4145
+ const css = createTailwindV4SourceReferenceSource(normalizeConfigDirective(prependConfigDirective(currentCss ?? resolvedEntrySource.css, generatorOptions?.config), config), resolvedSourceOptions);
4098
4146
  const source = await resolveTailwindV4Source$1(createSingleTailwindV4SourceOptions(resolvedSourceOptions, {
4099
- base: resolvedEntrySource.base,
4147
+ base: currentCss && config ? path.dirname(config) : resolvedEntrySource.base,
4100
4148
  css,
4101
4149
  cssEntries: [resolvedEntrySource.file]
4102
4150
  }));
@@ -4203,7 +4251,7 @@ async function resolveGeneratorSource(_majorVersion, runtimeState, rawSource, fi
4203
4251
  }
4204
4252
  const shouldPreferSourceSideEntry = shouldResolveSourceSideCssEntry(rawSource) || Boolean(cssEntrySource?.css.includes("weapp-tailwindcss generator-placeholder")) && (sourceOptions?.cssEntries?.length ?? 0) <= 1;
4205
4253
  const sourceSideEntrySource = normalizedSourceOptions && (shouldPreferSourceSideEntry || normalizedSourceOptions.sourceFile !== void 0) && canResolveSourceSideCssEntry(file, cssHandlerOptions, normalizedSourceOptions) ? resolveSourceSideCssEntrySource(file, normalizedSourceOptions, { removeConfig: false }) : void 0;
4206
- const sourceSideCssSource = sourceSideEntrySource?.file && normalizedSourceOptions.cssEntries?.some((cssEntry) => path.resolve(cssEntry.replace(/[?#].*$/, "")) === path.resolve(sourceSideEntrySource.file)) ? await resolveTailwindV4SourceSideEntrySource(sourceSideEntrySource, normalizedSourceOptions, generatorOptions, file) : void 0;
4254
+ const sourceSideCssSource = sourceSideEntrySource?.file && (sourceOptions?.cssEntries?.some((cssEntry) => path.resolve(cssEntry.replace(/[?#].*$/, "")) === path.resolve(sourceSideEntrySource.file)) || isSfcStyleSourceRequest(file) && sourceOptions?.cssSources?.some((cssSource) => typeof cssSource.file === "string" && path.resolve(cssSource.file.replace(/[?#].*$/, "")) === path.resolve(sourceSideEntrySource.file))) ? await resolveTailwindV4SourceSideEntrySource(sourceSideEntrySource, normalizedSourceOptions, generatorOptions, file, rawSource) : void 0;
4207
4255
  if (sourceSideCssSource) return sourceSideCssSource;
4208
4256
  const matchedCssEntrySource = normalizedSourceOptions ? await resolveMatchingTailwindV4CssEntry(rawSource, file, normalizedSourceOptions) : void 0;
4209
4257
  const matchedCssSource = normalizedSourceOptions && !matchedCssEntrySource ? await resolveMatchingTailwindV4CssSource(rawSource, file, cssHandlerOptions, normalizedSourceOptions, selectionOptions) : void 0;
@@ -5295,6 +5343,7 @@ async function executeGeneratorPipeline(context) {
5295
5343
  async function executeGeneratorPipelineWithOwner(context, compilationPool, generationSession) {
5296
5344
  const { cssHandlerOptions, debug, file, generatorBranch, generatorOptions, generatorRawSource, getSourceCandidatesForEntries, hasGeneratedCss, hasGeneratedMarkers, localImports, majorVersion, normalizeGeneratorSource, normalizedCssSources, options, opts, runtime, runtimeState, useMiniProgramCssBranch } = context;
5297
5345
  await runtimeState.readyPromise;
5346
+ const compilerSession = options.compilation?.enabled ? getFrameworkCompilerSession(runtimeState, opts) : void 0;
5298
5347
  const currentCssCandidates = collectGeneratorCssCandidates(generatorRawSource);
5299
5348
  const isolateCurrentCssCandidates = shouldIsolateCurrentTailwindV4CssCandidates(majorVersion, cssHandlerOptions, {
5300
5349
  hasGeneratedCss,
@@ -5357,16 +5406,26 @@ async function executeGeneratorPipelineWithOwner(context, compilationPool, gener
5357
5406
  }), sourceConcurrency)).filter((item) => Boolean(item));
5358
5407
  const generatePreparedInputs = async (candidateSets) => {
5359
5408
  return runWithConcurrency(preparedGenerationInputs.map((input) => async () => {
5360
- const currentCandidates = candidateSets?.get(input.sourceId) ?? input.generatorRuntime;
5409
+ const projectedCandidates = candidateSets?.get(input.sourceId);
5410
+ const currentCandidates = projectedCandidates ? /* @__PURE__ */ new Set([...input.generatorRuntime, ...projectedCandidates]) : input.generatorRuntime;
5411
+ const generateOptions = {
5412
+ bareArbitraryValues: generatorOptions.bareArbitraryValues,
5413
+ candidates: currentCandidates,
5414
+ incrementalCache: options.incrementalCache ?? true,
5415
+ scanSources: options.disableSourceScan === true ? false : shouldScanTailwindV4Sources(majorVersion, generatorOptions.target, currentCandidates, input.isolateCssSource),
5416
+ styleOptions: generatorStyleOptions,
5417
+ target: generatorOptions.target
5418
+ };
5419
+ let generated;
5420
+ if (compilerSession && input.generatorSource) try {
5421
+ generated = await compilerSession.generate(options.compilation?.scope.id ?? options.outputFile ?? file, input.sourceId, input.generatorSource, generateOptions);
5422
+ } catch (error) {
5423
+ if (!(error instanceof TypeError) || !String(error.message).includes("dependencies")) throw error;
5424
+ generated = await generationSession.generate(input.generatorSource, generateOptions);
5425
+ }
5426
+ else generated = await generationSession.generate(input.generatorSource, generateOptions);
5361
5427
  return {
5362
- generated: await generationSession.generate(input.generatorSource, {
5363
- bareArbitraryValues: generatorOptions.bareArbitraryValues,
5364
- candidates: currentCandidates,
5365
- incrementalCache: options.incrementalCache ?? true,
5366
- scanSources: options.disableSourceScan === true ? false : shouldScanTailwindV4Sources(majorVersion, generatorOptions.target, currentCandidates, input.isolateCssSource),
5367
- styleOptions: generatorStyleOptions,
5368
- target: generatorOptions.target
5369
- }),
5428
+ generated,
5370
5429
  sourceId: input.sourceId
5371
5430
  };
5372
5431
  }), sourceConcurrency);
@@ -5387,12 +5446,18 @@ async function executeGeneratorPipelineWithOwner(context, compilationPool, gener
5387
5446
  })),
5388
5447
  preserveDeletedCss: options.compilation.preserveDeletedCss
5389
5448
  }, async (compilation) => {
5449
+ if (compilerSession && options.compilation?.changes) compilerSession.invalidate(options.compilation.changes.map((change) => change.id));
5450
+ await compilerSession?.syncScope(options.compilation?.scope.id ?? options.outputFile ?? file, preparedGenerationInputs.map((input) => input.sourceId));
5390
5451
  const results = await generatePreparedInputs(compilation.candidatesBySource);
5391
5452
  const merged = mergeGeneratorResults(results.map((result) => result.generated));
5392
5453
  return merged ? {
5393
5454
  classSet: merged.classSet,
5394
5455
  dependenciesBySource: results.map((result) => [result.sourceId, resolveCompilationDependencies(result.generated.dependencies)]),
5395
- generated: merged
5456
+ generated: merged,
5457
+ ...compilerSession ? (() => {
5458
+ const snapshots = results.map((result) => result.generated.snapshot).filter((snapshot) => snapshot !== void 0);
5459
+ return snapshots.length > 0 ? { snapshot: compilerSession.mergeSnapshots(snapshots) } : {};
5460
+ })() : {}
5396
5461
  } : void 0;
5397
5462
  });
5398
5463
  if (!execution.committed) {
@@ -5400,6 +5465,10 @@ async function executeGeneratorPipelineWithOwner(context, compilationPool, gener
5400
5465
  return;
5401
5466
  }
5402
5467
  generated = execution.value?.generated;
5468
+ if (generated && execution.value?.snapshot) generated = {
5469
+ ...generated,
5470
+ snapshot: execution.value.snapshot
5471
+ };
5403
5472
  compilationRevision = execution.compilation.revision;
5404
5473
  } else generated = mergeGeneratorResults((await generatePreparedInputs()).map((result) => result.generated));
5405
5474
  if (!generated) return;
@@ -5433,6 +5502,11 @@ async function executeGeneratorPipelineWithOwner(context, compilationPool, gener
5433
5502
  });
5434
5503
  const outputContext = {
5435
5504
  ...context,
5505
+ ...compilerSession && options.compilation?.preserveDeletedCss !== true ? { options: {
5506
+ ...context.options,
5507
+ previousClassSet: void 0,
5508
+ previousCss: void 0
5509
+ } } : {},
5436
5510
  configuredContainerCompat,
5437
5511
  filterGeneratedApplyOnlyCss,
5438
5512
  generated,
@@ -5739,7 +5813,11 @@ async function generateTailwindV4CssWithImplementation(options, implementation)
5739
5813
  file: options.file,
5740
5814
  majorVersion,
5741
5815
  rawCandidates: options.runtime,
5742
- styleHandler: options.styleHandler
5816
+ styleHandler: options.styleHandler,
5817
+ ...implementation.frameworkAdapter === "graph" && generated.snapshot ? {
5818
+ compiler: getFrameworkCompilerSession(options.runtimeState, options.opts).compiler,
5819
+ snapshot: generated.snapshot
5820
+ } : {}
5743
5821
  }) : generated.css;
5744
5822
  const css = isVueScopedStyleRequest(resolvePostcssRequestOption(options.cssHandlerOptions)) ? preferScopedGeneratedCssRules(adaptedCss) : adaptedCss;
5745
5823
  const artifact = implementation.emitArtifact ? createCoreArtifact(generated, css, options) : void 0;