tailwindcss 0.0.0-insiders.8b152e7 → 0.0.0-insiders.8b1bf80

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 (94) hide show
  1. package/CHANGELOG.md +40 -3
  2. package/README.md +6 -3
  3. package/lib/cli-peer-dependencies.js +12 -4
  4. package/lib/cli.js +179 -75
  5. package/lib/constants.js +19 -12
  6. package/lib/corePluginList.js +5 -3
  7. package/lib/corePlugins.js +217 -203
  8. package/lib/css/preflight.css +5 -0
  9. package/lib/featureFlags.js +16 -8
  10. package/lib/index.js +9 -6
  11. package/lib/lib/cacheInvalidation.js +18 -15
  12. package/lib/lib/collapseAdjacentRules.js +14 -11
  13. package/lib/lib/collapseDuplicateDeclarations.js +11 -8
  14. package/lib/lib/defaultExtractor.js +38 -35
  15. package/lib/lib/detectNesting.js +4 -1
  16. package/lib/lib/evaluateTailwindFunctions.js +37 -34
  17. package/lib/lib/expandApplyAtRules.js +104 -62
  18. package/lib/lib/expandTailwindAtRules.js +150 -150
  19. package/lib/lib/generateRules.js +124 -110
  20. package/lib/lib/getModuleDependencies.js +21 -18
  21. package/lib/lib/normalizeTailwindDirectives.js +10 -7
  22. package/lib/lib/partitionApplyAtRules.js +14 -11
  23. package/lib/lib/regex.js +15 -7
  24. package/lib/lib/resolveDefaultsAtRules.js +92 -85
  25. package/lib/lib/setupContextUtils.js +110 -97
  26. package/lib/lib/setupTrackingContext.js +85 -76
  27. package/lib/lib/sharedState.js +15 -8
  28. package/lib/lib/substituteScreenAtRules.js +8 -5
  29. package/lib/postcss-plugins/nesting/index.js +7 -5
  30. package/lib/postcss-plugins/nesting/plugin.js +7 -4
  31. package/lib/processTailwindFeatures.js +34 -31
  32. package/lib/public/colors.js +6 -4
  33. package/lib/public/create-plugin.js +6 -4
  34. package/lib/public/default-config.js +7 -5
  35. package/lib/public/default-theme.js +7 -5
  36. package/lib/public/resolve-config.js +13 -10
  37. package/lib/util/bigSign.js +4 -1
  38. package/lib/util/buildMediaQuery.js +5 -2
  39. package/lib/util/cloneDeep.js +4 -1
  40. package/lib/util/cloneNodes.js +9 -2
  41. package/lib/util/color.js +11 -3
  42. package/lib/util/configurePlugins.js +4 -1
  43. package/lib/util/createPlugin.js +5 -3
  44. package/lib/util/createUtilityPlugin.js +13 -10
  45. package/lib/util/dataTypes.js +27 -19
  46. package/lib/util/defaults.js +4 -1
  47. package/lib/util/escapeClassName.js +12 -9
  48. package/lib/util/escapeCommas.js +4 -1
  49. package/lib/util/flattenColorPalette.js +5 -3
  50. package/lib/util/formatVariantSelector.js +21 -14
  51. package/lib/util/getAllConfigs.js +26 -12
  52. package/lib/util/hashConfig.js +10 -7
  53. package/lib/util/isKeyframeRule.js +4 -1
  54. package/lib/util/isPlainObject.js +4 -1
  55. package/lib/util/isValidArbitraryValue.js +33 -24
  56. package/lib/util/log.js +12 -5
  57. package/lib/util/nameClass.js +16 -8
  58. package/lib/util/negateValue.js +4 -1
  59. package/lib/util/normalizeConfig.js +26 -23
  60. package/lib/util/normalizeScreens.js +17 -2
  61. package/lib/util/parseAnimationValue.js +42 -39
  62. package/lib/util/parseBoxShadowValue.js +12 -4
  63. package/lib/util/parseDependency.js +35 -32
  64. package/lib/util/parseObjectStyles.js +14 -11
  65. package/lib/util/pluginUtils.js +28 -20
  66. package/lib/util/prefixSelector.js +6 -3
  67. package/lib/util/removeAlphaVariables.js +13 -2
  68. package/lib/util/resolveConfig.js +56 -53
  69. package/lib/util/resolveConfigPath.js +20 -17
  70. package/lib/util/responsive.js +12 -9
  71. package/lib/util/splitAtTopLevelOnly.js +16 -13
  72. package/lib/util/tap.js +4 -1
  73. package/lib/util/toColorValue.js +4 -1
  74. package/lib/util/toPath.js +18 -2
  75. package/lib/util/transformThemeValue.js +18 -8
  76. package/lib/util/validateConfig.js +5 -2
  77. package/lib/util/withAlphaVariable.js +30 -22
  78. package/package.json +12 -12
  79. package/peers/index.js +3519 -2031
  80. package/resolveConfig.d.ts +3 -0
  81. package/src/cli.js +112 -0
  82. package/src/corePlugins.js +23 -4
  83. package/src/css/preflight.css +5 -0
  84. package/src/featureFlags.js +5 -1
  85. package/src/lib/expandApplyAtRules.js +71 -18
  86. package/src/lib/expandTailwindAtRules.js +1 -5
  87. package/src/lib/generateRules.js +50 -40
  88. package/src/lib/setupContextUtils.js +5 -2
  89. package/src/lib/setupTrackingContext.js +1 -1
  90. package/src/util/cloneNodes.js +5 -1
  91. package/src/util/getAllConfigs.js +14 -2
  92. package/src/util/resolveConfig.js +1 -1
  93. package/src/util/transformThemeValue.js +9 -1
  94. package/types/config.d.ts +9 -2
package/CHANGELOG.md CHANGED
@@ -7,7 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- - Nothing yet!
10
+ ### Added
11
+
12
+ - Add support for configuring default `font-feature-settings` for a font family ([#9039](https://github.com/tailwindlabs/tailwindcss/pull/9039))
13
+ - Add a standalone CLI build for 32-bit Linux on ARM (`node16-linux-armv7`) ([#9084](https://github.com/tailwindlabs/tailwindcss/pull/9084))
14
+ - Add future flag to disable color opacity utility plugins ([#9088](https://github.com/tailwindlabs/tailwindcss/pull/9088))
15
+ - Add negative value support for `outline-offset` ([#9136](https://github.com/tailwindlabs/tailwindcss/pull/9136))
16
+
17
+ ### Fixed
18
+
19
+ - Use absolute paths when resolving changed files for resilience against working directory changes ([#9032](https://github.com/tailwindlabs/tailwindcss/pull/9032))
20
+ - Fix ring color utility generation when using `respectDefaultRingColorOpacity` ([#9070](https://github.com/tailwindlabs/tailwindcss/pull/9070))
21
+ - Sort tags before classes when `@applying` a selector with joined classes ([#9107](https://github.com/tailwindlabs/tailwindcss/pull/9107))
22
+ - Remove invalid `outline-hidden` utility ([#9147](https://github.com/tailwindlabs/tailwindcss/pull/9147))
23
+ - Honor the `hidden` attribute on elements in preflight ([#9174](https://github.com/tailwindlabs/tailwindcss/pull/9174))
24
+ - Don't stop watching atomically renamed files ([#9173](https://github.com/tailwindlabs/tailwindcss/pull/9173), [#9215](https://github.com/tailwindlabs/tailwindcss/pull/9215))
25
+ - Re-use existing entries in the rule cache ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208))
26
+ - Don't output duplicate utilities ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208))
27
+ - Fix `fontFamily` config TypeScript types ([#9214](https://github.com/tailwindlabs/tailwindcss/pull/9214))
28
+
29
+ ## [3.1.8] - 2022-08-05
30
+
31
+ ### Fixed
32
+
33
+ - Don’t prefix classes within reused arbitrary variants ([#8992](https://github.com/tailwindlabs/tailwindcss/pull/8992))
34
+ - Fix usage of alpha values inside single-named colors that are functions ([#9008](https://github.com/tailwindlabs/tailwindcss/pull/9008))
35
+ - Fix `@apply` of user utilities when negative and non-negative versions both exist ([#9027](https://github.com/tailwindlabs/tailwindcss/pull/9027))
36
+
37
+ ## [3.1.7] - 2022-07-29
38
+
39
+ ### Fixed
40
+
41
+ - Don't rewrite source maps for `@layer` rules ([#8971](https://github.com/tailwindlabs/tailwindcss/pull/8971))
42
+
43
+ ### Added
44
+
45
+ - Added types for `resolveConfig` ([#8924](https://github.com/tailwindlabs/tailwindcss/pull/8924))
11
46
 
12
47
  ## [3.1.6] - 2022-07-11
13
48
 
@@ -1645,7 +1680,7 @@ No release notes
1645
1680
 
1646
1681
  - Make it possible to disable all core plugins using `corePlugins: false`
1647
1682
  - Make it possible to configure a single list of variants that applies to all utility plugins
1648
- - Make it possible to whitelist which core plugins should be enabled
1683
+ - Make it possible to safelist which core plugins should be enabled
1649
1684
 
1650
1685
  ### Fixed
1651
1686
 
@@ -2011,7 +2046,9 @@ No release notes
2011
2046
 
2012
2047
  - Everything!
2013
2048
 
2014
- [unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.6...HEAD
2049
+ [unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.8...HEAD
2050
+ [3.1.8]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.7...v3.1.8
2051
+ [3.1.7]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.6...v3.1.7
2015
2052
  [3.1.6]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.5...v3.1.6
2016
2053
  [3.1.5]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.4...v3.1.5
2017
2054
  [3.1.4]: https://github.com/tailwindlabs/tailwindcss/compare/v3.1.3...v3.1.4
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <p>
1
+ <p align="center">
2
2
  <a href="https://tailwindcss.com/#gh-light-mode-only" target="_blank">
3
3
  <img src="./.github/logo-light.svg" alt="Tailwind CSS" width="350" height="70">
4
4
  </a>
@@ -7,9 +7,12 @@
7
7
  </a>
8
8
  </p>
9
9
 
10
- A utility-first CSS framework for rapidly building custom user interfaces.
10
+ <p align="center">
11
+ A utility-first CSS framework for rapidly building custom user interfaces.
12
+ </p>
13
+
11
14
 
12
- <p>
15
+ <p align="center">
13
16
  <a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/workflow/status/tailwindlabs/tailwindcss/Node.js%20CI" alt="Build Status"></a>
14
17
  <a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
15
18
  <a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
@@ -2,10 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- exports.lazyPostcss = lazyPostcss;
6
- exports.lazyPostcssImport = lazyPostcssImport;
7
- exports.lazyAutoprefixer = lazyAutoprefixer;
8
- exports.lazyCssnano = lazyCssnano;
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ lazyPostcss: ()=>lazyPostcss,
13
+ lazyPostcssImport: ()=>lazyPostcssImport,
14
+ lazyAutoprefixer: ()=>lazyAutoprefixer,
15
+ lazyCssnano: ()=>lazyCssnano
16
+ });
9
17
  function lazyPostcss() {
10
18
  return require("postcss");
11
19
  }
package/lib/cli.js CHANGED
@@ -1,24 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var _indexJs = require("../peers/index.js");
4
- var _chokidar = _interopRequireDefault(require("chokidar"));
5
- var _path = _interopRequireDefault(require("path"));
6
- var _arg = _interopRequireDefault(require("arg"));
7
- var _fs = _interopRequireDefault(require("fs"));
8
- var _postcssLoadConfig = _interopRequireDefault(require("postcss-load-config"));
9
- var _lilconfig = require("lilconfig");
10
- var _plugins // Little bit scary, looking at private/internal API
11
- = _interopRequireDefault(require("postcss-load-config/src/plugins"));
12
- var _options // Little bit scary, looking at private/internal API
13
- = _interopRequireDefault(require("postcss-load-config/src/options"));
14
- var _processTailwindFeatures = _interopRequireDefault(require("./processTailwindFeatures"));
15
- var _resolveConfig = _interopRequireDefault(require("../resolveConfig"));
16
- var _fastGlob = _interopRequireDefault(require("fast-glob"));
17
- var _getModuleDependencies = _interopRequireDefault(require("./lib/getModuleDependencies"));
18
- var _log = _interopRequireDefault(require("./util/log"));
19
- var _packageJson = _interopRequireDefault(require("../package.json"));
20
- var _normalizePath = _interopRequireDefault(require("normalize-path"));
21
- var _validateConfigJs = require("./util/validateConfig.js");
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ const _indexJs = require("../peers/index.js");
7
+ const _chokidar = /*#__PURE__*/ _interopRequireDefault(require("chokidar"));
8
+ const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
9
+ const _arg = /*#__PURE__*/ _interopRequireDefault(require("arg"));
10
+ const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
11
+ const _postcssLoadConfig = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-config"));
12
+ const _lilconfig = require("lilconfig");
13
+ const _plugins = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-config/src/plugins" // Little bit scary, looking at private/internal API
14
+ ));
15
+ const _options = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-config/src/options" // Little bit scary, looking at private/internal API
16
+ ));
17
+ const _processTailwindFeatures = /*#__PURE__*/ _interopRequireDefault(require("./processTailwindFeatures"));
18
+ const _resolveConfig = /*#__PURE__*/ _interopRequireDefault(require("../resolveConfig"));
19
+ const _fastGlob = /*#__PURE__*/ _interopRequireDefault(require("fast-glob"));
20
+ const _getModuleDependencies = /*#__PURE__*/ _interopRequireDefault(require("./lib/getModuleDependencies"));
21
+ const _log = /*#__PURE__*/ _interopRequireDefault(require("./util/log"));
22
+ const _packageJson = /*#__PURE__*/ _interopRequireDefault(require("../package.json"));
23
+ const _normalizePath = /*#__PURE__*/ _interopRequireDefault(require("normalize-path"));
24
+ const _micromatch = /*#__PURE__*/ _interopRequireDefault(require("micromatch"));
25
+ const _validateConfigJs = require("./util/validateConfig.js");
22
26
  function _interopRequireDefault(obj) {
23
27
  return obj && obj.__esModule ? obj : {
24
28
  default: obj
@@ -76,7 +80,7 @@ function drainStdin() {
76
80
  process.stdin.on("error", (err)=>reject(err));
77
81
  });
78
82
  }
79
- function help({ message , usage , commands: commands1 , options }) {
83
+ function help({ message , usage , commands , options }) {
80
84
  let indent = 2;
81
85
  // Render header
82
86
  console.log();
@@ -97,11 +101,11 @@ function help({ message , usage , commands: commands1 , options }) {
97
101
  }
98
102
  }
99
103
  // Render commands
100
- if (commands1 && commands1.length > 0) {
104
+ if (commands && commands.length > 0) {
101
105
  console.log();
102
106
  console.log("Commands:");
103
- for (let command1 of commands1){
104
- console.log(" ".repeat(indent), command1);
107
+ for (let command of commands){
108
+ console.log(" ".repeat(indent), command);
105
109
  }
106
110
  }
107
111
  // Render options
@@ -121,12 +125,12 @@ function help({ message , usage , commands: commands1 , options }) {
121
125
  }
122
126
  console.log();
123
127
  console.log("Options:");
124
- for (let { flags: flags1 , description , deprecated } of Object.values(groupedOptions)){
128
+ for (let { flags , description , deprecated } of Object.values(groupedOptions)){
125
129
  if (deprecated) continue;
126
- if (flags1.length === 1) {
127
- console.log(" ".repeat(indent + 4 /* 4 = "-i, ".length */ ), flags1.slice().reverse().join(", ").padEnd(20, " "), description);
130
+ if (flags.length === 1) {
131
+ console.log(" ".repeat(indent + 4 /* 4 = "-i, ".length */ ), flags.slice().reverse().join(", ").padEnd(20, " "), description);
128
132
  } else {
129
- console.log(" ".repeat(indent), flags1.slice().reverse().join(", ").padEnd(24, " "), description);
133
+ console.log(" ".repeat(indent), flags.slice().reverse().join(", ").padEnd(24, " "), description);
130
134
  }
131
135
  }
132
136
  }
@@ -150,7 +154,7 @@ function loadPostcss() {
150
154
  try {
151
155
  return require("postcss");
152
156
  } catch {}
153
- return (0, _indexJs).lazyPostcss();
157
+ return (0, _indexJs.lazyPostcss)();
154
158
  }
155
159
  let commands = {
156
160
  init: {
@@ -233,7 +237,7 @@ if (process.stdout.isTTY /* Detect redirecting output to a file */ && (process.
233
237
  "tailwindcss [--input input.css] [--output output.css] [--watch] [options...]",
234
238
  "tailwindcss init [--full] [--postcss] [options...]",
235
239
  ],
236
- commands: Object.keys(commands).filter((command2)=>command2 !== "build").map((command3)=>`${command3} [options]`),
240
+ commands: Object.keys(commands).filter((command)=>command !== "build").map((command)=>`${command} [options]`),
237
241
  options: {
238
242
  ...commands.build.args,
239
243
  ...sharedFlags
@@ -253,7 +257,7 @@ if (commands[command] === undefined) {
253
257
  usage: [
254
258
  "tailwindcss <command> [options]"
255
259
  ],
256
- commands: Object.keys(commands).filter((command4)=>command4 !== "build").map((command5)=>`${command5} [options]`),
260
+ commands: Object.keys(commands).filter((command)=>command !== "build").map((command)=>`${command} [options]`),
257
261
  options: sharedFlags
258
262
  });
259
263
  process.exit(1);
@@ -263,7 +267,7 @@ if (commands[command] === undefined) {
263
267
  let { args: flags , run } = commands[command];
264
268
  let args = (()=>{
265
269
  try {
266
- let result = (0, _arg).default(Object.fromEntries(Object.entries({
270
+ let result = (0, _arg.default)(Object.fromEntries(Object.entries({
267
271
  ...flags,
268
272
  ...sharedFlags
269
273
  }).filter(([_key, value])=>{
@@ -287,16 +291,16 @@ let args = (()=>{
287
291
  handler = flags[handler];
288
292
  }
289
293
  if (!handler) continue;
290
- let args1 = [];
294
+ let args = [];
291
295
  let offset = i + 1;
292
296
  // Parse args for current flag
293
297
  while(result["_"][offset] && !result["_"][offset].startsWith("-")){
294
- args1.push(result["_"][offset++]);
298
+ args.push(result["_"][offset++]);
295
299
  }
296
300
  // Cleanup manually parsed flags + args
297
- result["_"].splice(i, 1 + args1.length);
301
+ result["_"].splice(i, 1 + args.length);
298
302
  // Set the resolved value in the `result` object
299
- result[flagName] = handler.type(args1.length === 0 ? undefined : args1.length === 1 ? args1[0] : args1, flagName);
303
+ result[flagName] = handler.type(args.length === 0 ? undefined : args.length === 1 ? args[0] : args, flagName);
300
304
  }
301
305
  // Ensure that the `command` is always the first argument in the `args`.
302
306
  // This is important so that we don't have to check if a default command
@@ -354,8 +358,8 @@ function init() {
354
358
  if (_fs.default.existsSync(postcssConfigLocation)) {
355
359
  messages.push(`${_path.default.basename(postcssConfigLocation)} already exists.`);
356
360
  } else {
357
- let stubFile = _fs.default.readFileSync(_path.default.resolve(__dirname, "../stubs/defaultPostCssConfig.stub.js"), "utf8");
358
- _fs.default.writeFileSync(postcssConfigLocation, stubFile, "utf8");
361
+ let stubFile1 = _fs.default.readFileSync(_path.default.resolve(__dirname, "../stubs/defaultPostCssConfig.stub.js"), "utf8");
362
+ _fs.default.writeFileSync(postcssConfigLocation, stubFile1, "utf8");
359
363
  messages.push(`Created PostCSS config file: ${_path.default.basename(postcssConfigLocation)}`);
360
364
  }
361
365
  }
@@ -392,10 +396,10 @@ async function build() {
392
396
  let configPath = args["--config"] ? args["--config"] : ((defaultPath)=>_fs.default.existsSync(defaultPath) ? defaultPath : null)(_path.default.resolve(`./${configs.tailwind}`));
393
397
  async function loadPostCssPlugins() {
394
398
  let customPostCssPath = typeof args["--postcss"] === "string" ? args["--postcss"] : undefined;
395
- let config1 = customPostCssPath ? await (async ()=>{
399
+ let config = customPostCssPath ? await (async ()=>{
396
400
  let file = _path.default.resolve(customPostCssPath);
397
401
  // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.1.0/src/index.js
398
- let { config ={} } = await (0, _lilconfig).lilconfig("postcss").load(file);
402
+ let { config ={} } = await (0, _lilconfig.lilconfig)("postcss").load(file);
399
403
  if (typeof config === "function") {
400
404
  config = config();
401
405
  } else {
@@ -406,11 +410,11 @@ async function build() {
406
410
  }
407
411
  return {
408
412
  file,
409
- plugins: (0, _plugins).default(config, file),
410
- options: (0, _options).default(config, file)
413
+ plugins: (0, _plugins.default)(config, file),
414
+ options: (0, _options.default)(config, file)
411
415
  };
412
- })() : await (0, _postcssLoadConfig).default();
413
- let configPlugins = config1.plugins;
416
+ })() : await (0, _postcssLoadConfig.default)();
417
+ let configPlugins = config.plugins;
414
418
  let configPluginTailwindIdx = configPlugins.findIndex((plugin)=>{
415
419
  if (typeof plugin === "function" && plugin.name === "tailwindcss") {
416
420
  return true;
@@ -425,7 +429,7 @@ async function build() {
425
429
  return [
426
430
  beforePlugins,
427
431
  afterPlugins,
428
- config1.options
432
+ config.options
429
433
  ];
430
434
  }
431
435
  function loadBuiltinPostcssPlugins() {
@@ -447,7 +451,7 @@ async function build() {
447
451
  try {
448
452
  return require("postcss-import");
449
453
  } catch {}
450
- return (0, _indexJs).lazyPostcssImport();
454
+ return (0, _indexJs.lazyPostcssImport)();
451
455
  })(),
452
456
  (root)=>{
453
457
  root.walkComments((rule)=>{
@@ -478,18 +482,18 @@ async function build() {
478
482
  }
479
483
  if (args["--content"]) {
480
484
  let files = args["--content"].split(/(?<!{[^}]+),/);
481
- let resolvedConfig = (0, _resolveConfig).default(config, {
485
+ let resolvedConfig = (0, _resolveConfig.default)(config, {
482
486
  content: {
483
487
  files
484
488
  }
485
489
  });
486
490
  resolvedConfig.content.files = files;
487
- resolvedConfig = (0, _validateConfigJs).validateConfig(resolvedConfig);
491
+ resolvedConfig = (0, _validateConfigJs.validateConfig)(resolvedConfig);
488
492
  return resolvedConfig;
489
493
  }
490
- let resolvedConfig = (0, _resolveConfig).default(config);
491
- resolvedConfig = (0, _validateConfigJs).validateConfig(resolvedConfig);
492
- return resolvedConfig;
494
+ let resolvedConfig1 = (0, _resolveConfig.default)(config);
495
+ resolvedConfig1 = (0, _validateConfigJs.validateConfig)(resolvedConfig1);
496
+ return resolvedConfig1;
493
497
  }
494
498
  function extractFileGlobs(config) {
495
499
  return config.content.files.filter((file)=>{
@@ -497,7 +501,7 @@ async function build() {
497
501
  // like an object it's probably a raw content object. But this object
498
502
  // is not watchable, so let's remove it.
499
503
  return typeof file === "string";
500
- }).map((glob)=>(0, _normalizePath).default(glob));
504
+ }).map((glob)=>(0, _normalizePath.default)(glob));
501
505
  }
502
506
  function extractRawContent(config) {
503
507
  return config.content.files.filter((file)=>{
@@ -531,7 +535,7 @@ async function build() {
531
535
  return {
532
536
  postcssPlugin: "tailwindcss",
533
537
  Once (root, { result }) {
534
- (0, _processTailwindFeatures).default(({ createContext })=>{
538
+ (0, _processTailwindFeatures.default)(({ createContext })=>{
535
539
  return ()=>{
536
540
  return createContext(config, changedContent);
537
541
  };
@@ -551,7 +555,7 @@ async function build() {
551
555
  try {
552
556
  return require("autoprefixer");
553
557
  } catch {}
554
- return (0, _indexJs).lazyAutoprefixer();
558
+ return (0, _indexJs.lazyAutoprefixer)();
555
559
  })(),
556
560
  args["--minify"] && (()=>{
557
561
  let options = {
@@ -566,7 +570,7 @@ async function build() {
566
570
  try {
567
571
  return require("cssnano");
568
572
  } catch {}
569
- return (0, _indexJs).lazyCssnano()(options);
573
+ return (0, _indexJs.lazyCssnano)()(options);
570
574
  })(),
571
575
  ].filter(Boolean);
572
576
  let postcss = loadPostcss();
@@ -593,7 +597,7 @@ async function build() {
593
597
  console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
594
598
  });
595
599
  }
596
- let css1 = await (()=>{
600
+ let css = await (()=>{
597
601
  // Piping in data, let's drain the stdin
598
602
  if (input === "-") {
599
603
  return drainStdin();
@@ -605,7 +609,7 @@ async function build() {
605
609
  // No input file provided, fallback to default atrules
606
610
  return "@tailwind base; @tailwind components; @tailwind utilities";
607
611
  })();
608
- return processCSS(css1);
612
+ return processCSS(css);
609
613
  }
610
614
  let context = null;
611
615
  async function startWatcher() {
@@ -615,11 +619,11 @@ async function build() {
615
619
  let watcher = null;
616
620
  function refreshConfig() {
617
621
  env.DEBUG && console.time("Module dependencies");
618
- for (let file1 of configDependencies){
619
- delete require.cache[require.resolve(file1)];
622
+ for (let file of configDependencies){
623
+ delete require.cache[require.resolve(file)];
620
624
  }
621
625
  if (configPath) {
622
- configDependencies = (0, _getModuleDependencies).default(configPath).map(({ file })=>file);
626
+ configDependencies = (0, _getModuleDependencies.default)(configPath).map(({ file })=>file);
623
627
  for (let dependency of configDependencies){
624
628
  contextDependencies.add(dependency);
625
629
  }
@@ -638,7 +642,7 @@ async function build() {
638
642
  try {
639
643
  return require("autoprefixer");
640
644
  } catch {}
641
- return (0, _indexJs).lazyAutoprefixer();
645
+ return (0, _indexJs.lazyAutoprefixer)();
642
646
  })(),
643
647
  args["--minify"] && (()=>{
644
648
  let options = {
@@ -653,7 +657,7 @@ async function build() {
653
657
  try {
654
658
  return require("cssnano");
655
659
  } catch {}
656
- return (0, _indexJs).lazyCssnano()(options);
660
+ return (0, _indexJs.lazyCssnano)()(options);
657
661
  })(),
658
662
  ].filter(Boolean);
659
663
  async function rebuild(config) {
@@ -663,7 +667,7 @@ async function build() {
663
667
  postcssPlugin: "tailwindcss",
664
668
  Once (root, { result }) {
665
669
  env.DEBUG && console.time("Compiling CSS");
666
- (0, _processTailwindFeatures).default(({ createContext })=>{
670
+ (0, _processTailwindFeatures.default)(({ createContext })=>{
667
671
  console.error();
668
672
  console.error("Rebuilding...");
669
673
  return ()=>{
@@ -721,7 +725,7 @@ async function build() {
721
725
  }
722
726
  });
723
727
  }
724
- let css2 = await (()=>{
728
+ let css = await (()=>{
725
729
  // Piping in data, let's drain the stdin
726
730
  if (input === "-") {
727
731
  return drainStdin();
@@ -733,18 +737,41 @@ async function build() {
733
737
  // No input file provided, fallback to default atrules
734
738
  return "@tailwind base; @tailwind components; @tailwind utilities";
735
739
  })();
736
- let result1 = await processCSS(css2);
740
+ let result = await processCSS(css);
737
741
  env.DEBUG && console.timeEnd("Finished in");
738
- return result1;
742
+ return result;
743
+ }
744
+ let config = refreshConfig(configPath);
745
+ let contentPatterns = refreshContentPatterns(config);
746
+ /**
747
+ * @param {import('../types/config.js').RequiredConfig} config
748
+ * @return {{all: string[], dynamic: string[], static: string[]}}
749
+ **/ function refreshContentPatterns(config) {
750
+ let globs = extractFileGlobs(config);
751
+ let tasks = _fastGlob.default.generateTasks(globs, {
752
+ absolute: true
753
+ });
754
+ let dynamicPatterns = tasks.filter((task)=>task.dynamic).flatMap((task)=>task.patterns);
755
+ let staticPatterns = tasks.filter((task)=>!task.dynamic).flatMap((task)=>task.patterns);
756
+ return {
757
+ all: [
758
+ ...staticPatterns,
759
+ ...dynamicPatterns
760
+ ],
761
+ dynamic: dynamicPatterns
762
+ };
739
763
  }
740
- let config2 = refreshConfig(configPath);
741
764
  if (input) {
742
765
  contextDependencies.add(_path.default.resolve(input));
743
766
  }
744
767
  watcher = _chokidar.default.watch([
745
768
  ...contextDependencies,
746
- ...extractFileGlobs(config2)
769
+ ...extractFileGlobs(config)
747
770
  ], {
771
+ // Force checking for atomic writes in all situations
772
+ // This causes chokidar to wait up to 100ms for a file to re-added after it's been unlinked
773
+ // This only works when watching directories though
774
+ atomic: true,
748
775
  usePolling: shouldPoll,
749
776
  interval: shouldPoll ? pollInterval : undefined,
750
777
  ignoreInitial: true,
@@ -754,20 +781,22 @@ async function build() {
754
781
  } : false
755
782
  });
756
783
  let chain = Promise.resolve();
784
+ let pendingRebuilds = new Set();
757
785
  watcher.on("change", async (file)=>{
758
786
  if (contextDependencies.has(file)) {
759
787
  env.DEBUG && console.time("Resolve config");
760
788
  context = null;
761
- config2 = refreshConfig(configPath);
789
+ config = refreshConfig(configPath);
790
+ contentPatterns = refreshContentPatterns(config);
762
791
  env.DEBUG && console.timeEnd("Resolve config");
763
792
  env.DEBUG && console.time("Watch new files");
764
- let globs = extractFileGlobs(config2);
793
+ let globs = extractFileGlobs(config);
765
794
  watcher.add(configDependencies);
766
795
  watcher.add(globs);
767
796
  env.DEBUG && console.timeEnd("Watch new files");
768
797
  chain = chain.then(async ()=>{
769
- changedContent.push(...getChangedContent(config2));
770
- await rebuild(config2);
798
+ changedContent.push(...getChangedContent(config));
799
+ await rebuild(config);
771
800
  });
772
801
  } else {
773
802
  chain = chain.then(async ()=>{
@@ -775,22 +804,97 @@ async function build() {
775
804
  content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
776
805
  extension: _path.default.extname(file).slice(1)
777
806
  });
778
- await rebuild(config2);
807
+ await rebuild(config);
779
808
  });
780
809
  }
781
810
  });
811
+ /**
812
+ * When rapidly saving files atomically a couple of situations can happen:
813
+ * - The file is missing since the external program has deleted it by the time we've gotten around to reading it from the earlier save.
814
+ * - The file is being written to by the external program by the time we're going to read it and is thus treated as busy because a lock is held.
815
+ *
816
+ * To work around this we retry reading the file a handful of times with a delay between each attempt
817
+ *
818
+ * @param {string} path
819
+ * @param {number} tries
820
+ * @returns {string}
821
+ * @throws {Error} If the file is still missing or busy after the specified number of tries
822
+ */ async function readFileWithRetries(path, tries = 5) {
823
+ for(let n = 0; n <= tries; n++){
824
+ try {
825
+ return await _fs.default.promises.readFile(path, "utf8");
826
+ } catch (err) {
827
+ if (n !== tries) {
828
+ if (err.code === "ENOENT" || err.code === "EBUSY") {
829
+ await new Promise((resolve)=>setTimeout(resolve, 10));
830
+ continue;
831
+ }
832
+ }
833
+ throw err;
834
+ }
835
+ }
836
+ }
837
+ // Restore watching any files that are "removed"
838
+ // This can happen when a file is pseudo-atomically replaced (a copy is created, overwritten, the old one is unlinked, and the new one is renamed)
839
+ // TODO: An an optimization we should allow removal when the config changes
840
+ watcher.on("unlink", (file)=>{
841
+ file = (0, _normalizePath.default)(file);
842
+ // Only re-add the file if it's not covered by a dynamic pattern
843
+ if (!_micromatch.default.some([
844
+ file
845
+ ], contentPatterns.dynamic)) {
846
+ watcher.add(file);
847
+ }
848
+ });
849
+ // Some applications such as Visual Studio (but not VS Code)
850
+ // will only fire a rename event for atomic writes and not a change event
851
+ // This is very likely a chokidar bug but it's one we need to work around
852
+ // We treat this as a change event and rebuild the CSS
853
+ watcher.on("raw", (evt, filePath, meta)=>{
854
+ if (evt !== "rename") {
855
+ return;
856
+ }
857
+ let watchedPath = meta.watchedPath;
858
+ // Watched path might be the file itself
859
+ // Or the directory it is in
860
+ filePath = watchedPath.endsWith(filePath) ? watchedPath : _path.default.join(watchedPath, filePath);
861
+ // Skip this event since the files it is for does not match any of the registered content globs
862
+ if (!_micromatch.default.some([
863
+ filePath
864
+ ], contentPatterns.all)) {
865
+ return;
866
+ }
867
+ // Skip since we've already queued a rebuild for this file that hasn't happened yet
868
+ if (pendingRebuilds.has(filePath)) {
869
+ return;
870
+ }
871
+ pendingRebuilds.add(filePath);
872
+ chain = chain.then(async ()=>{
873
+ let content;
874
+ try {
875
+ content = await readFileWithRetries(_path.default.resolve(filePath));
876
+ } finally{
877
+ pendingRebuilds.delete(filePath);
878
+ }
879
+ changedContent.push({
880
+ content,
881
+ extension: _path.default.extname(filePath).slice(1)
882
+ });
883
+ await rebuild(config);
884
+ });
885
+ });
782
886
  watcher.on("add", async (file)=>{
783
887
  chain = chain.then(async ()=>{
784
888
  changedContent.push({
785
889
  content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
786
890
  extension: _path.default.extname(file).slice(1)
787
891
  });
788
- await rebuild(config2);
892
+ await rebuild(config);
789
893
  });
790
894
  });
791
895
  chain = chain.then(()=>{
792
- changedContent.push(...getChangedContent(config2));
793
- return rebuild(config2);
896
+ changedContent.push(...getChangedContent(config));
897
+ return rebuild(config);
794
898
  });
795
899
  }
796
900
  if (shouldWatch) {