@tenphi/tasty 2.0.2 → 2.0.4

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 (321) hide show
  1. package/dist/{ssr/async-storage.js → async-storage-B7_o6FKt.js} +2 -2
  2. package/dist/async-storage-B7_o6FKt.js.map +1 -0
  3. package/dist/{ssr/collector.d.ts → collector-CkZ517g4.d.ts} +3 -3
  4. package/dist/{ssr/collector.js → collector-DXqvGOb1.js} +5 -10
  5. package/dist/collector-DXqvGOb1.js.map +1 -0
  6. package/dist/config-5jzS6k6B.js +10005 -0
  7. package/dist/config-5jzS6k6B.js.map +1 -0
  8. package/dist/config-DknGsfMo.d.ts +857 -0
  9. package/dist/{ssr/context.js → context-CkSg-kDT.js} +11 -3
  10. package/dist/context-CkSg-kDT.js.map +1 -0
  11. package/dist/core/index.d.ts +5 -34
  12. package/dist/core/index.js +5 -26
  13. package/dist/core-CtU6-9OC.js +1507 -0
  14. package/dist/core-CtU6-9OC.js.map +1 -0
  15. package/dist/{zero/extractor.js → css-writer-DHkX0JuE.js} +74 -11
  16. package/dist/css-writer-DHkX0JuE.js.map +1 -0
  17. package/dist/{ssr/format-global-rules.js → format-global-rules-Dbc_1tc3.js} +2 -2
  18. package/dist/format-global-rules-Dbc_1tc3.js.map +1 -0
  19. package/dist/format-rules-DH13ewDu.js +143 -0
  20. package/dist/format-rules-DH13ewDu.js.map +1 -0
  21. package/dist/{ssr/hydrate.js → hydrate-C1Gv-DoS.js} +3 -3
  22. package/dist/hydrate-C1Gv-DoS.js.map +1 -0
  23. package/dist/{styles/types.d.ts → index-PzENbpAq.d.ts} +701 -5
  24. package/dist/index-o7zV2yCr.d.ts +1561 -0
  25. package/dist/index.d.ts +5 -51
  26. package/dist/index.js +728 -35
  27. package/dist/index.js.map +1 -0
  28. package/dist/keyframes-b7X3UxDV.js +587 -0
  29. package/dist/keyframes-b7X3UxDV.js.map +1 -0
  30. package/dist/{utils/merge-styles.d.ts → merge-styles-C7KTy7MY.d.ts} +3 -3
  31. package/dist/{utils/merge-styles.js → merge-styles-Tgo3BbL2.js} +3 -4
  32. package/dist/merge-styles-Tgo3BbL2.js.map +1 -0
  33. package/dist/{utils/resolve-recipes.js → resolve-recipes-Ca2-5CxM.js} +4 -6
  34. package/dist/resolve-recipes-Ca2-5CxM.js.map +1 -0
  35. package/dist/ssr/astro-client.js +1 -1
  36. package/dist/ssr/astro.js +4 -4
  37. package/dist/ssr/index.d.ts +44 -4
  38. package/dist/ssr/index.js +4 -4
  39. package/dist/ssr/next.d.ts +1 -1
  40. package/dist/ssr/next.js +6 -6
  41. package/dist/ssr/next.js.map +1 -1
  42. package/dist/static/index.d.ts +91 -5
  43. package/dist/static/index.js +49 -3
  44. package/dist/static/index.js.map +1 -0
  45. package/dist/zero/babel.d.ts +1 -1
  46. package/dist/zero/babel.js +10 -6
  47. package/dist/zero/babel.js.map +1 -1
  48. package/dist/zero/index.d.ts +67 -3
  49. package/dist/zero/index.js +1 -2
  50. package/docs/pipeline.md +204 -50
  51. package/package.json +3 -3
  52. package/dist/_virtual/_rolldown/runtime.js +0 -7
  53. package/dist/chunks/cacheKey.d.ts +0 -1
  54. package/dist/chunks/cacheKey.js +0 -77
  55. package/dist/chunks/cacheKey.js.map +0 -1
  56. package/dist/chunks/definitions.d.ts +0 -37
  57. package/dist/chunks/definitions.js +0 -258
  58. package/dist/chunks/definitions.js.map +0 -1
  59. package/dist/chunks/index.d.ts +0 -1
  60. package/dist/chunks/renderChunk.d.ts +0 -1
  61. package/dist/chunks/renderChunk.js +0 -59
  62. package/dist/chunks/renderChunk.js.map +0 -1
  63. package/dist/compute-styles.d.ts +0 -31
  64. package/dist/compute-styles.js +0 -322
  65. package/dist/compute-styles.js.map +0 -1
  66. package/dist/config.d.ts +0 -407
  67. package/dist/config.js +0 -591
  68. package/dist/config.js.map +0 -1
  69. package/dist/counter-style/index.js +0 -51
  70. package/dist/counter-style/index.js.map +0 -1
  71. package/dist/debug.d.ts +0 -89
  72. package/dist/debug.js +0 -453
  73. package/dist/debug.js.map +0 -1
  74. package/dist/font-face/index.js +0 -63
  75. package/dist/font-face/index.js.map +0 -1
  76. package/dist/hooks/index.d.ts +0 -7
  77. package/dist/hooks/useCounterStyle.d.ts +0 -36
  78. package/dist/hooks/useCounterStyle.js +0 -65
  79. package/dist/hooks/useCounterStyle.js.map +0 -1
  80. package/dist/hooks/useFontFace.d.ts +0 -45
  81. package/dist/hooks/useFontFace.js +0 -66
  82. package/dist/hooks/useFontFace.js.map +0 -1
  83. package/dist/hooks/useGlobalStyles.d.ts +0 -46
  84. package/dist/hooks/useGlobalStyles.js +0 -88
  85. package/dist/hooks/useGlobalStyles.js.map +0 -1
  86. package/dist/hooks/useKeyframes.d.ts +0 -58
  87. package/dist/hooks/useKeyframes.js +0 -55
  88. package/dist/hooks/useKeyframes.js.map +0 -1
  89. package/dist/hooks/useProperty.d.ts +0 -81
  90. package/dist/hooks/useProperty.js +0 -96
  91. package/dist/hooks/useProperty.js.map +0 -1
  92. package/dist/hooks/useRawCSS.d.ts +0 -22
  93. package/dist/hooks/useRawCSS.js +0 -103
  94. package/dist/hooks/useRawCSS.js.map +0 -1
  95. package/dist/hooks/useStyles.d.ts +0 -40
  96. package/dist/hooks/useStyles.js +0 -31
  97. package/dist/hooks/useStyles.js.map +0 -1
  98. package/dist/injector/index.d.ts +0 -182
  99. package/dist/injector/index.js +0 -185
  100. package/dist/injector/index.js.map +0 -1
  101. package/dist/injector/injector.d.ts +0 -198
  102. package/dist/injector/injector.js +0 -651
  103. package/dist/injector/injector.js.map +0 -1
  104. package/dist/injector/sheet-manager.d.ts +0 -132
  105. package/dist/injector/sheet-manager.js +0 -699
  106. package/dist/injector/sheet-manager.js.map +0 -1
  107. package/dist/injector/types.d.ts +0 -235
  108. package/dist/keyframes/index.js +0 -206
  109. package/dist/keyframes/index.js.map +0 -1
  110. package/dist/parser/classify.js +0 -319
  111. package/dist/parser/classify.js.map +0 -1
  112. package/dist/parser/const.js +0 -60
  113. package/dist/parser/const.js.map +0 -1
  114. package/dist/parser/lru.js +0 -109
  115. package/dist/parser/lru.js.map +0 -1
  116. package/dist/parser/parser.d.ts +0 -25
  117. package/dist/parser/parser.js +0 -115
  118. package/dist/parser/parser.js.map +0 -1
  119. package/dist/parser/tokenizer.js +0 -69
  120. package/dist/parser/tokenizer.js.map +0 -1
  121. package/dist/parser/types.d.ts +0 -51
  122. package/dist/parser/types.js +0 -46
  123. package/dist/parser/types.js.map +0 -1
  124. package/dist/pipeline/conditions.d.ts +0 -134
  125. package/dist/pipeline/conditions.js +0 -406
  126. package/dist/pipeline/conditions.js.map +0 -1
  127. package/dist/pipeline/exclusive.js +0 -382
  128. package/dist/pipeline/exclusive.js.map +0 -1
  129. package/dist/pipeline/index.d.ts +0 -55
  130. package/dist/pipeline/index.js +0 -708
  131. package/dist/pipeline/index.js.map +0 -1
  132. package/dist/pipeline/materialize.js +0 -1157
  133. package/dist/pipeline/materialize.js.map +0 -1
  134. package/dist/pipeline/parseStateKey.d.ts +0 -15
  135. package/dist/pipeline/parseStateKey.js +0 -446
  136. package/dist/pipeline/parseStateKey.js.map +0 -1
  137. package/dist/pipeline/simplify.js +0 -690
  138. package/dist/pipeline/simplify.js.map +0 -1
  139. package/dist/pipeline/warnings.js +0 -18
  140. package/dist/pipeline/warnings.js.map +0 -1
  141. package/dist/plugins/index.d.ts +0 -2
  142. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  143. package/dist/plugins/okhsl-plugin.js +0 -97
  144. package/dist/plugins/okhsl-plugin.js.map +0 -1
  145. package/dist/plugins/types.d.ts +0 -87
  146. package/dist/properties/index.js +0 -222
  147. package/dist/properties/index.js.map +0 -1
  148. package/dist/properties/property-type-resolver.d.ts +0 -24
  149. package/dist/properties/property-type-resolver.js +0 -90
  150. package/dist/properties/property-type-resolver.js.map +0 -1
  151. package/dist/rsc-cache.js +0 -79
  152. package/dist/rsc-cache.js.map +0 -1
  153. package/dist/ssr/async-storage.d.ts +0 -17
  154. package/dist/ssr/async-storage.js.map +0 -1
  155. package/dist/ssr/collect-auto-properties.js +0 -58
  156. package/dist/ssr/collect-auto-properties.js.map +0 -1
  157. package/dist/ssr/collector.js.map +0 -1
  158. package/dist/ssr/context.js.map +0 -1
  159. package/dist/ssr/format-global-rules.js.map +0 -1
  160. package/dist/ssr/format-keyframes.js +0 -69
  161. package/dist/ssr/format-keyframes.js.map +0 -1
  162. package/dist/ssr/format-property.js +0 -49
  163. package/dist/ssr/format-property.js.map +0 -1
  164. package/dist/ssr/format-rules.js +0 -73
  165. package/dist/ssr/format-rules.js.map +0 -1
  166. package/dist/ssr/hydrate.d.ts +0 -29
  167. package/dist/ssr/hydrate.js.map +0 -1
  168. package/dist/ssr/ssr-collector-ref.js +0 -29
  169. package/dist/ssr/ssr-collector-ref.js.map +0 -1
  170. package/dist/states/index.d.ts +0 -49
  171. package/dist/states/index.js +0 -170
  172. package/dist/states/index.js.map +0 -1
  173. package/dist/static/tastyStatic.d.ts +0 -46
  174. package/dist/static/tastyStatic.js +0 -30
  175. package/dist/static/tastyStatic.js.map +0 -1
  176. package/dist/static/types.d.ts +0 -49
  177. package/dist/static/types.js +0 -24
  178. package/dist/static/types.js.map +0 -1
  179. package/dist/styles/border.d.ts +0 -25
  180. package/dist/styles/border.js +0 -120
  181. package/dist/styles/border.js.map +0 -1
  182. package/dist/styles/color.d.ts +0 -14
  183. package/dist/styles/color.js +0 -26
  184. package/dist/styles/color.js.map +0 -1
  185. package/dist/styles/const.js +0 -17
  186. package/dist/styles/const.js.map +0 -1
  187. package/dist/styles/createStyle.js +0 -79
  188. package/dist/styles/createStyle.js.map +0 -1
  189. package/dist/styles/dimension.js +0 -109
  190. package/dist/styles/dimension.js.map +0 -1
  191. package/dist/styles/directional.js +0 -133
  192. package/dist/styles/directional.js.map +0 -1
  193. package/dist/styles/display.d.ts +0 -30
  194. package/dist/styles/display.js +0 -73
  195. package/dist/styles/display.js.map +0 -1
  196. package/dist/styles/fade.d.ts +0 -15
  197. package/dist/styles/fade.js +0 -62
  198. package/dist/styles/fade.js.map +0 -1
  199. package/dist/styles/fill.d.ts +0 -42
  200. package/dist/styles/fill.js +0 -51
  201. package/dist/styles/fill.js.map +0 -1
  202. package/dist/styles/flow.d.ts +0 -16
  203. package/dist/styles/flow.js +0 -12
  204. package/dist/styles/flow.js.map +0 -1
  205. package/dist/styles/gap.d.ts +0 -31
  206. package/dist/styles/gap.js +0 -38
  207. package/dist/styles/gap.js.map +0 -1
  208. package/dist/styles/height.d.ts +0 -17
  209. package/dist/styles/height.js +0 -19
  210. package/dist/styles/height.js.map +0 -1
  211. package/dist/styles/index.d.ts +0 -1
  212. package/dist/styles/index.js +0 -8
  213. package/dist/styles/index.js.map +0 -1
  214. package/dist/styles/inset.d.ts +0 -24
  215. package/dist/styles/inset.js +0 -34
  216. package/dist/styles/inset.js.map +0 -1
  217. package/dist/styles/list.d.ts +0 -16
  218. package/dist/styles/list.js +0 -100
  219. package/dist/styles/list.js.map +0 -1
  220. package/dist/styles/margin.d.ts +0 -24
  221. package/dist/styles/margin.js +0 -32
  222. package/dist/styles/margin.js.map +0 -1
  223. package/dist/styles/outline.d.ts +0 -29
  224. package/dist/styles/outline.js +0 -55
  225. package/dist/styles/outline.js.map +0 -1
  226. package/dist/styles/padding.d.ts +0 -24
  227. package/dist/styles/padding.js +0 -32
  228. package/dist/styles/padding.js.map +0 -1
  229. package/dist/styles/placement.d.ts +0 -37
  230. package/dist/styles/placement.js +0 -74
  231. package/dist/styles/placement.js.map +0 -1
  232. package/dist/styles/predefined.d.ts +0 -71
  233. package/dist/styles/predefined.js +0 -237
  234. package/dist/styles/predefined.js.map +0 -1
  235. package/dist/styles/preset.d.ts +0 -52
  236. package/dist/styles/preset.js +0 -127
  237. package/dist/styles/preset.js.map +0 -1
  238. package/dist/styles/radius.d.ts +0 -12
  239. package/dist/styles/radius.js +0 -83
  240. package/dist/styles/radius.js.map +0 -1
  241. package/dist/styles/scrollMargin.d.ts +0 -24
  242. package/dist/styles/scrollMargin.js +0 -32
  243. package/dist/styles/scrollMargin.js.map +0 -1
  244. package/dist/styles/scrollbar.d.ts +0 -25
  245. package/dist/styles/scrollbar.js +0 -51
  246. package/dist/styles/scrollbar.js.map +0 -1
  247. package/dist/styles/shadow.d.ts +0 -14
  248. package/dist/styles/shadow.js +0 -25
  249. package/dist/styles/shadow.js.map +0 -1
  250. package/dist/styles/shared.js +0 -17
  251. package/dist/styles/shared.js.map +0 -1
  252. package/dist/styles/transition.d.ts +0 -14
  253. package/dist/styles/transition.js +0 -159
  254. package/dist/styles/transition.js.map +0 -1
  255. package/dist/styles/width.d.ts +0 -17
  256. package/dist/styles/width.js +0 -19
  257. package/dist/styles/width.js.map +0 -1
  258. package/dist/tasty.d.ts +0 -134
  259. package/dist/tasty.js +0 -248
  260. package/dist/tasty.js.map +0 -1
  261. package/dist/types.d.ts +0 -184
  262. package/dist/utils/cache-wrapper.js +0 -21
  263. package/dist/utils/cache-wrapper.js.map +0 -1
  264. package/dist/utils/case-converter.js +0 -8
  265. package/dist/utils/case-converter.js.map +0 -1
  266. package/dist/utils/color-math.d.ts +0 -46
  267. package/dist/utils/color-math.js +0 -749
  268. package/dist/utils/color-math.js.map +0 -1
  269. package/dist/utils/color-space.d.ts +0 -5
  270. package/dist/utils/color-space.js +0 -228
  271. package/dist/utils/color-space.js.map +0 -1
  272. package/dist/utils/colors.d.ts +0 -5
  273. package/dist/utils/colors.js +0 -10
  274. package/dist/utils/colors.js.map +0 -1
  275. package/dist/utils/css-types.d.ts +0 -7
  276. package/dist/utils/deps-equal.js +0 -15
  277. package/dist/utils/deps-equal.js.map +0 -1
  278. package/dist/utils/dotize.d.ts +0 -26
  279. package/dist/utils/dotize.js +0 -122
  280. package/dist/utils/dotize.js.map +0 -1
  281. package/dist/utils/filter-base-props.d.ts +0 -15
  282. package/dist/utils/filter-base-props.js +0 -45
  283. package/dist/utils/filter-base-props.js.map +0 -1
  284. package/dist/utils/get-display-name.d.ts +0 -7
  285. package/dist/utils/get-display-name.js +0 -10
  286. package/dist/utils/get-display-name.js.map +0 -1
  287. package/dist/utils/has-keys.js +0 -13
  288. package/dist/utils/has-keys.js.map +0 -1
  289. package/dist/utils/hash.js +0 -14
  290. package/dist/utils/hash.js.map +0 -1
  291. package/dist/utils/is-dev-env.js +0 -19
  292. package/dist/utils/is-dev-env.js.map +0 -1
  293. package/dist/utils/is-valid-element-type.js +0 -15
  294. package/dist/utils/is-valid-element-type.js.map +0 -1
  295. package/dist/utils/merge-styles.js.map +0 -1
  296. package/dist/utils/mod-attrs.d.ts +0 -6
  297. package/dist/utils/mod-attrs.js +0 -20
  298. package/dist/utils/mod-attrs.js.map +0 -1
  299. package/dist/utils/process-tokens.d.ts +0 -17
  300. package/dist/utils/process-tokens.js +0 -83
  301. package/dist/utils/process-tokens.js.map +0 -1
  302. package/dist/utils/resolve-recipes.d.ts +0 -17
  303. package/dist/utils/resolve-recipes.js.map +0 -1
  304. package/dist/utils/selector-transform.js +0 -32
  305. package/dist/utils/selector-transform.js.map +0 -1
  306. package/dist/utils/string.js +0 -8
  307. package/dist/utils/string.js.map +0 -1
  308. package/dist/utils/styles.d.ts +0 -99
  309. package/dist/utils/styles.js +0 -220
  310. package/dist/utils/styles.js.map +0 -1
  311. package/dist/utils/typography.d.ts +0 -58
  312. package/dist/utils/typography.js +0 -51
  313. package/dist/utils/typography.js.map +0 -1
  314. package/dist/utils/warnings.d.ts +0 -16
  315. package/dist/utils/warnings.js +0 -16
  316. package/dist/utils/warnings.js.map +0 -1
  317. package/dist/zero/css-writer.d.ts +0 -45
  318. package/dist/zero/css-writer.js +0 -73
  319. package/dist/zero/css-writer.js.map +0 -1
  320. package/dist/zero/extractor.d.ts +0 -24
  321. package/dist/zero/extractor.js.map +0 -1
@@ -1,690 +0,0 @@
1
- import { Lru } from "../parser/lru.js";
2
- import { and, falseCondition, getConditionUniqueId, not, or, trueCondition } from "./conditions.js";
3
- //#region src/pipeline/simplify.ts
4
- /**
5
- * Condition Simplification Engine
6
- *
7
- * Simplifies condition trees by applying boolean algebra rules,
8
- * detecting contradictions, merging ranges, and deduplicating terms.
9
- *
10
- * This is critical for:
11
- * 1. Detecting invalid combinations (A & !A → FALSE)
12
- * 2. Reducing CSS output size
13
- * 3. Producing cleaner selectors
14
- */
15
- const simplifyCache = new Lru(5e3);
16
- /**
17
- * Simplify a condition tree aggressively.
18
- *
19
- * This applies all possible simplification rules:
20
- * - Boolean algebra (identity, annihilator, idempotent, absorption)
21
- * - Contradiction detection (A & !A → FALSE)
22
- * - Tautology detection (A | !A → TRUE)
23
- * - Range intersection for numeric queries
24
- * - Attribute value conflict detection
25
- * - Deduplication and sorting
26
- */
27
- function simplifyCondition(node) {
28
- const key = getConditionUniqueId(node);
29
- const cached = simplifyCache.get(key);
30
- if (cached) return cached;
31
- const result = simplifyInner(node);
32
- simplifyCache.set(key, result);
33
- return result;
34
- }
35
- function simplifyInner(node) {
36
- if (node.kind === "true" || node.kind === "false") return node;
37
- if (node.kind === "state") return node;
38
- if (node.kind === "compound") {
39
- const simplifiedChildren = node.children.map((c) => simplifyInner(c));
40
- if (node.operator === "AND") return simplifyAnd(simplifiedChildren);
41
- else return simplifyOr(simplifiedChildren);
42
- }
43
- return node;
44
- }
45
- function simplifyAnd(children) {
46
- let terms = [];
47
- for (const child of children) {
48
- if (child.kind === "false") return falseCondition();
49
- if (child.kind === "true") continue;
50
- if (child.kind === "compound" && child.operator === "AND") terms.push(...child.children);
51
- else terms.push(child);
52
- }
53
- if (terms.length === 0) return trueCondition();
54
- if (terms.length === 1) return terms[0];
55
- if (hasContradiction(terms)) return falseCondition();
56
- if (hasRangeContradiction(terms)) return falseCondition();
57
- if (hasAttributeConflict(terms)) return falseCondition();
58
- if (hasContainerStyleConflict(terms)) return falseCondition();
59
- terms = removeImpliedNegations(terms);
60
- terms = deduplicateTerms(terms);
61
- terms = mergeRanges(terms);
62
- terms = sortTerms(terms);
63
- terms = applyAbsorptionAnd(terms);
64
- terms = applyConsensusAnd(terms);
65
- if (terms.length === 0) return trueCondition();
66
- if (terms.length === 1) return terms[0];
67
- return {
68
- kind: "compound",
69
- operator: "AND",
70
- children: terms
71
- };
72
- }
73
- function simplifyOr(children) {
74
- let terms = [];
75
- for (const child of children) {
76
- if (child.kind === "true") return trueCondition();
77
- if (child.kind === "false") continue;
78
- if (child.kind === "compound" && child.operator === "OR") terms.push(...child.children);
79
- else terms.push(child);
80
- }
81
- if (terms.length === 0) return falseCondition();
82
- if (terms.length === 1) return terms[0];
83
- if (hasTautology(terms)) return trueCondition();
84
- terms = deduplicateTerms(terms);
85
- terms = sortTerms(terms);
86
- terms = applyAbsorptionOr(terms);
87
- terms = applyComplementaryFactoring(terms);
88
- if (terms.length === 0) return falseCondition();
89
- if (terms.length === 1) return terms[0];
90
- return {
91
- kind: "compound",
92
- operator: "OR",
93
- children: terms
94
- };
95
- }
96
- /**
97
- * Check if any pair of terms has complementary negation (A and !A).
98
- * Used for both contradiction detection (in AND) and tautology detection (in OR),
99
- * since the underlying check is identical: the context determines the semantics.
100
- */
101
- function hasComplementaryPair(terms) {
102
- const uniqueIds = /* @__PURE__ */ new Set();
103
- for (const term of terms) {
104
- if (term.kind !== "state") continue;
105
- const id = term.uniqueId;
106
- const negatedId = term.negated ? id.slice(1) : `!${id}`;
107
- if (uniqueIds.has(negatedId)) return true;
108
- uniqueIds.add(id);
109
- }
110
- return false;
111
- }
112
- const hasContradiction = hasComplementaryPair;
113
- const hasTautology = hasComplementaryPair;
114
- /**
115
- * Check for range contradictions in media/container queries
116
- * e.g., @media(w < 400px) & @media(w > 800px) → FALSE
117
- *
118
- * Also handles negated conditions:
119
- * - Single-bound negations are inverted (not (w < 600px) → w >= 600px)
120
- * - Range negations create excluded ranges that are checked against positive bounds
121
- */
122
- function hasRangeContradiction(terms) {
123
- const mediaByDim = /* @__PURE__ */ new Map();
124
- const containerByDim = /* @__PURE__ */ new Map();
125
- for (const term of terms) {
126
- if (term.kind !== "state") continue;
127
- if (term.type === "media" && term.subtype === "dimension") {
128
- const key = term.dimension || "width";
129
- if (!mediaByDim.has(key)) mediaByDim.set(key, {
130
- positive: [],
131
- negated: []
132
- });
133
- const group = mediaByDim.get(key);
134
- if (term.negated) group.negated.push(term);
135
- else group.positive.push(term);
136
- }
137
- if (term.type === "container" && term.subtype === "dimension") {
138
- const key = `${term.containerName || "_"}:${term.dimension || "width"}`;
139
- if (!containerByDim.has(key)) containerByDim.set(key, {
140
- positive: [],
141
- negated: []
142
- });
143
- const group = containerByDim.get(key);
144
- if (term.negated) group.negated.push(term);
145
- else group.positive.push(term);
146
- }
147
- }
148
- for (const group of mediaByDim.values()) if (rangesAreImpossibleWithNegations(group.positive, group.negated)) return true;
149
- for (const group of containerByDim.values()) if (rangesAreImpossibleWithNegations(group.positive, group.negated)) return true;
150
- return false;
151
- }
152
- /**
153
- * Check if conditions are impossible, including negated conditions.
154
- *
155
- * For negated single-bound conditions:
156
- * not (w < 600px) → w >= 600px (inverted to lower bound)
157
- * not (w >= 800px) → w < 800px (inverted to upper bound)
158
- *
159
- * For negated range conditions:
160
- * not (400px <= w < 800px) → excludes [400, 800)
161
- * If the effective bounds fall entirely within an excluded range, it's impossible.
162
- */
163
- function rangesAreImpossibleWithNegations(positive, negated) {
164
- const bounds = computeEffectiveBounds(positive);
165
- const excludedRanges = [];
166
- for (const cond of negated) {
167
- const hasLower = cond.lowerBound?.valueNumeric != null;
168
- const hasUpper = cond.upperBound?.valueNumeric != null;
169
- if (hasLower && hasUpper) excludedRanges.push({
170
- lower: cond.lowerBound.valueNumeric,
171
- lowerInclusive: cond.lowerBound.inclusive,
172
- upper: cond.upperBound.valueNumeric,
173
- upperInclusive: cond.upperBound.inclusive
174
- });
175
- else if (hasUpper) {
176
- const value = cond.upperBound.valueNumeric;
177
- const inclusive = !cond.upperBound.inclusive;
178
- if (bounds.lowerBound === null || value > bounds.lowerBound) {
179
- bounds.lowerBound = value;
180
- bounds.lowerInclusive = inclusive;
181
- } else if (value === bounds.lowerBound && !inclusive) bounds.lowerInclusive = false;
182
- } else if (hasLower) {
183
- const value = cond.lowerBound.valueNumeric;
184
- const inclusive = !cond.lowerBound.inclusive;
185
- if (bounds.upperBound === null || value < bounds.upperBound) {
186
- bounds.upperBound = value;
187
- bounds.upperInclusive = inclusive;
188
- } else if (value === bounds.upperBound && !inclusive) bounds.upperInclusive = false;
189
- }
190
- }
191
- if (bounds.lowerBound !== null && bounds.upperBound !== null) {
192
- if (bounds.lowerBound > bounds.upperBound) return true;
193
- if (bounds.lowerBound === bounds.upperBound && (!bounds.lowerInclusive || !bounds.upperInclusive)) return true;
194
- }
195
- if (bounds.lowerBound !== null && bounds.upperBound !== null && excludedRanges.length > 0) {
196
- for (const excluded of excludedRanges) if (boundsWithinExcludedRange(bounds, excluded)) return true;
197
- }
198
- return false;
199
- }
200
- /**
201
- * Compute effective bounds from positive (non-negated) conditions
202
- */
203
- function computeEffectiveBounds(conditions) {
204
- let lowerBound = null;
205
- let lowerInclusive = false;
206
- let upperBound = null;
207
- let upperInclusive = false;
208
- for (const cond of conditions) {
209
- if (cond.lowerBound?.valueNumeric != null) {
210
- const value = cond.lowerBound.valueNumeric;
211
- const inclusive = cond.lowerBound.inclusive;
212
- if (lowerBound === null || value > lowerBound) {
213
- lowerBound = value;
214
- lowerInclusive = inclusive;
215
- } else if (value === lowerBound && !inclusive) lowerInclusive = false;
216
- }
217
- if (cond.upperBound?.valueNumeric != null) {
218
- const value = cond.upperBound.valueNumeric;
219
- const inclusive = cond.upperBound.inclusive;
220
- if (upperBound === null || value < upperBound) {
221
- upperBound = value;
222
- upperInclusive = inclusive;
223
- } else if (value === upperBound && !inclusive) upperInclusive = false;
224
- }
225
- }
226
- return {
227
- lowerBound,
228
- lowerInclusive,
229
- upperBound,
230
- upperInclusive
231
- };
232
- }
233
- /**
234
- * Check if effective bounds fall entirely within an excluded range.
235
- *
236
- * For example:
237
- * Effective: [400, 800)
238
- * Excluded: [400, 800)
239
- * → bounds fall entirely within excluded range → impossible
240
- */
241
- function boundsWithinExcludedRange(bounds, excluded) {
242
- if (bounds.lowerBound === null || bounds.upperBound === null) return false;
243
- let lowerOk = false;
244
- if (bounds.lowerBound > excluded.lower) lowerOk = true;
245
- else if (bounds.lowerBound === excluded.lower) lowerOk = excluded.lowerInclusive || !bounds.lowerInclusive;
246
- let upperOk = false;
247
- if (bounds.upperBound < excluded.upper) upperOk = true;
248
- else if (bounds.upperBound === excluded.upper) upperOk = excluded.upperInclusive || !bounds.upperInclusive;
249
- return lowerOk && upperOk;
250
- }
251
- /**
252
- * Check for attribute value conflicts
253
- * e.g., [data-theme="dark"] & [data-theme="light"] → FALSE
254
- * e.g., [data-theme="dark"] & ![data-theme] → FALSE
255
- */
256
- /**
257
- * Generic value-conflict checker for grouped conditions.
258
- *
259
- * Groups terms by a key, splits into positive/negated, then checks:
260
- * 1. Multiple distinct positive values → conflict
261
- * 2. Positive value + negated existence (value === undefined) → conflict
262
- * 3. Positive value + negated same value → conflict
263
- */
264
- function hasGroupedValueConflict(terms, match, groupKey, getValue) {
265
- const groups = /* @__PURE__ */ new Map();
266
- for (const term of terms) {
267
- const matched = match(term);
268
- if (!matched) continue;
269
- const key = groupKey(matched);
270
- let group = groups.get(key);
271
- if (!group) {
272
- group = {
273
- positive: [],
274
- negated: []
275
- };
276
- groups.set(key, group);
277
- }
278
- if (matched.negated) group.negated.push(matched);
279
- else group.positive.push(matched);
280
- }
281
- for (const [, group] of groups) {
282
- const positiveValues = group.positive.map(getValue).filter((v) => v !== void 0);
283
- if (new Set(positiveValues).size > 1) return true;
284
- const hasPositiveValue = positiveValues.length > 0;
285
- const hasNegatedExistence = group.negated.some((t) => getValue(t) === void 0);
286
- if (hasPositiveValue && hasNegatedExistence) return true;
287
- for (const pos of group.positive) {
288
- const posVal = getValue(pos);
289
- if (posVal !== void 0) {
290
- for (const neg of group.negated) if (getValue(neg) === posVal) return true;
291
- }
292
- }
293
- }
294
- return false;
295
- }
296
- function hasAttributeConflict(terms) {
297
- return hasGroupedValueConflict(terms, (t) => t.kind === "state" && t.type === "modifier" ? t : null, (t) => t.attribute, (t) => t.value);
298
- }
299
- function hasContainerStyleConflict(terms) {
300
- return hasGroupedValueConflict(terms, (t) => t.kind === "state" && t.type === "container" && t.subtype === "style" ? t : null, (t) => `${t.containerName || "_"}:${t.property}`, (t) => t.propertyValue);
301
- }
302
- /**
303
- * Remove negations that are implied by positive terms.
304
- *
305
- * Key optimizations:
306
- * 1. style(--variant: danger) implies NOT style(--variant: success)
307
- * → If we have style(--variant: danger) & not style(--variant: success),
308
- * the negation is redundant and can be removed.
309
- *
310
- * 2. [data-theme="dark"] implies NOT [data-theme="light"]
311
- * → Same logic for attribute selectors.
312
- *
313
- * This produces cleaner CSS:
314
- * Before: @container style(--variant: danger) and (not style(--variant: success))
315
- * After: @container style(--variant: danger)
316
- */
317
- /**
318
- * Collect positive values from terms and build a "is this negation implied?" check.
319
- *
320
- * A negation is implied (redundant) when a positive term for the same group
321
- * already pins a specific value, making "NOT other-value" obvious.
322
- * e.g. style(--variant: danger) implies NOT style(--variant: success).
323
- */
324
- function buildImpliedNegationCheck(terms) {
325
- const positiveValues = /* @__PURE__ */ new Map();
326
- for (const term of terms) {
327
- if (term.kind !== "state" || term.negated) continue;
328
- if (term.type === "container" && term.subtype === "style") {
329
- if (term.propertyValue !== void 0) positiveValues.set(`c:${term.containerName || "_"}:${term.property}`, term.propertyValue);
330
- } else if (term.type === "modifier" && term.value !== void 0) positiveValues.set(`m:${term.attribute}`, term.value);
331
- }
332
- return (term) => {
333
- if (term.kind !== "state" || !term.negated) return false;
334
- if (term.type === "container" && term.subtype === "style") {
335
- if (term.propertyValue === void 0) return false;
336
- const pos = positiveValues.get(`c:${term.containerName || "_"}:${term.property}`);
337
- return pos !== void 0 && term.propertyValue !== pos;
338
- }
339
- if (term.type === "modifier" && term.value !== void 0) {
340
- const pos = positiveValues.get(`m:${term.attribute}`);
341
- return pos !== void 0 && term.value !== pos;
342
- }
343
- return false;
344
- };
345
- }
346
- function removeImpliedNegations(terms) {
347
- const isImplied = buildImpliedNegationCheck(terms);
348
- return terms.filter((t) => !isImplied(t));
349
- }
350
- function deduplicateTerms(terms) {
351
- const seen = /* @__PURE__ */ new Set();
352
- const result = [];
353
- for (const term of terms) {
354
- const id = getConditionUniqueId(term);
355
- if (!seen.has(id)) {
356
- seen.add(id);
357
- result.push(term);
358
- }
359
- }
360
- return result;
361
- }
362
- /**
363
- * Merge compatible range conditions
364
- * e.g., @media(w >= 400px) & @media(w <= 800px) → @media(400px <= w <= 800px)
365
- */
366
- function mergeRanges(terms) {
367
- const mediaByDim = /* @__PURE__ */ new Map();
368
- const containerByDim = /* @__PURE__ */ new Map();
369
- terms.forEach((term, index) => {
370
- if (term.kind !== "state") return;
371
- if (term.type === "media" && term.subtype === "dimension" && !term.negated) {
372
- const key = term.dimension || "width";
373
- if (!mediaByDim.has(key)) mediaByDim.set(key, {
374
- conditions: [],
375
- indices: []
376
- });
377
- const group = mediaByDim.get(key);
378
- group.conditions.push(term);
379
- group.indices.push(index);
380
- }
381
- if (term.type === "container" && term.subtype === "dimension" && !term.negated) {
382
- const key = `${term.containerName || "_"}:${term.dimension || "width"}`;
383
- if (!containerByDim.has(key)) containerByDim.set(key, {
384
- conditions: [],
385
- indices: []
386
- });
387
- const group = containerByDim.get(key);
388
- group.conditions.push(term);
389
- group.indices.push(index);
390
- }
391
- });
392
- const indicesToRemove = /* @__PURE__ */ new Set();
393
- const mergedTerms = [];
394
- for (const [_dim, group] of mediaByDim) if (group.conditions.length > 1) {
395
- const merged = mergeMediaRanges(group.conditions);
396
- if (merged) {
397
- group.indices.forEach((i) => indicesToRemove.add(i));
398
- mergedTerms.push(merged);
399
- }
400
- }
401
- for (const [, group] of containerByDim) if (group.conditions.length > 1) {
402
- const merged = mergeContainerRanges(group.conditions);
403
- if (merged) {
404
- group.indices.forEach((i) => indicesToRemove.add(i));
405
- mergedTerms.push(merged);
406
- }
407
- }
408
- const result = [];
409
- terms.forEach((term, index) => {
410
- if (!indicesToRemove.has(index)) result.push(term);
411
- });
412
- result.push(...mergedTerms);
413
- return result;
414
- }
415
- /**
416
- * Tighten bounds by picking the most restrictive lower and upper bounds
417
- * from a set of conditions that have lowerBound/upperBound fields.
418
- */
419
- function tightenBounds(conditions) {
420
- let lowerBound;
421
- let upperBound;
422
- for (const cond of conditions) {
423
- if (cond.lowerBound) {
424
- if (!lowerBound || (cond.lowerBound.valueNumeric ?? -Infinity) > (lowerBound.valueNumeric ?? -Infinity)) lowerBound = cond.lowerBound;
425
- }
426
- if (cond.upperBound) {
427
- if (!upperBound || (cond.upperBound.valueNumeric ?? Infinity) < (upperBound.valueNumeric ?? Infinity)) upperBound = cond.upperBound;
428
- }
429
- }
430
- return {
431
- lowerBound,
432
- upperBound
433
- };
434
- }
435
- function appendBoundsToUniqueId(parts, lowerBound, upperBound) {
436
- if (lowerBound) {
437
- parts.push(lowerBound.inclusive ? ">=" : ">");
438
- parts.push(lowerBound.value);
439
- }
440
- if (upperBound) {
441
- parts.push(upperBound.inclusive ? "<=" : "<");
442
- parts.push(upperBound.value);
443
- }
444
- }
445
- function mergeDimensionRanges(conditions, idPrefix) {
446
- if (conditions.length === 0) return null;
447
- const { lowerBound, upperBound } = tightenBounds(conditions);
448
- const base = conditions[0];
449
- const parts = [...idPrefix];
450
- appendBoundsToUniqueId(parts, lowerBound, upperBound);
451
- return {
452
- ...base,
453
- negated: false,
454
- raw: buildMergedRaw(base.dimension || "width", lowerBound, upperBound),
455
- uniqueId: parts.join(":"),
456
- lowerBound,
457
- upperBound
458
- };
459
- }
460
- function mergeMediaRanges(conditions) {
461
- return mergeDimensionRanges(conditions, [
462
- "media",
463
- "dim",
464
- conditions[0]?.dimension ?? "width"
465
- ]);
466
- }
467
- function mergeContainerRanges(conditions) {
468
- const base = conditions[0];
469
- if (!base) return null;
470
- return mergeDimensionRanges(conditions, [
471
- "container",
472
- "dim",
473
- base.containerName || "_",
474
- base.dimension ?? "width"
475
- ]);
476
- }
477
- function buildMergedRaw(dimension, lowerBound, upperBound) {
478
- if (lowerBound && upperBound) {
479
- const lowerOp = lowerBound.inclusive ? "<=" : "<";
480
- const upperOp = upperBound.inclusive ? "<=" : "<";
481
- return `@media(${lowerBound.value} ${lowerOp} ${dimension} ${upperOp} ${upperBound.value})`;
482
- } else if (upperBound) return `@media(${dimension} ${upperBound.inclusive ? "<=" : "<"} ${upperBound.value})`;
483
- else if (lowerBound) return `@media(${dimension} ${lowerBound.inclusive ? ">=" : ">"} ${lowerBound.value})`;
484
- return "@media()";
485
- }
486
- /**
487
- * Apply complementary factoring: (A & B) | (A & !B) → A
488
- *
489
- * Finds pairs of AND compounds that share all children except one,
490
- * where the differing child is complementary (X vs !X).
491
- * Replaces the pair with the common terms.
492
- *
493
- * This is applied iteratively until no more reductions are possible,
494
- * since factoring can expose further simplification opportunities.
495
- */
496
- function applyComplementaryFactoring(terms) {
497
- let changed = true;
498
- while (changed) {
499
- changed = false;
500
- for (let i = 0; i < terms.length; i++) {
501
- const a = terms[i];
502
- if (a.kind !== "compound" || a.operator !== "AND") continue;
503
- for (let j = i + 1; j < terms.length; j++) {
504
- const b = terms[j];
505
- if (b.kind !== "compound" || b.operator !== "AND") continue;
506
- const factored = tryFactorPair(a.children, b.children);
507
- if (factored) {
508
- const replacement = simplifyInner(factored);
509
- terms = [
510
- ...terms.slice(0, i),
511
- ...terms.slice(i + 1, j),
512
- ...terms.slice(j + 1),
513
- replacement
514
- ];
515
- changed = true;
516
- break;
517
- }
518
- }
519
- if (changed) break;
520
- }
521
- }
522
- return terms;
523
- }
524
- /**
525
- * Try to factor two AND children lists.
526
- *
527
- * Extracts the common children (by uniqueId). If the remaining
528
- * (non-common) parts of each side OR to TRUE, the common part alone
529
- * is sufficient: `(common & restA) | (common & restB) → common`
530
- * when `restA | restB → TRUE`.
531
- *
532
- * Also handles the simpler case where exactly one child is
533
- * complementary: `[A, B, C]` and `[A, !B, C]` → `AND(A, C)`.
534
- */
535
- function tryFactorPair(aChildren, bChildren) {
536
- const aIds = aChildren.map((c) => getConditionUniqueId(c));
537
- const bIds = bChildren.map((c) => getConditionUniqueId(c));
538
- const bIdSet = new Set(bIds);
539
- const aIdSet = new Set(aIds);
540
- const commonIndicesA = [];
541
- const restIndicesA = [];
542
- for (let i = 0; i < aIds.length; i++) if (bIdSet.has(aIds[i])) commonIndicesA.push(i);
543
- else restIndicesA.push(i);
544
- const restIndicesB = [];
545
- for (let i = 0; i < bIds.length; i++) if (!aIdSet.has(bIds[i])) restIndicesB.push(i);
546
- if (commonIndicesA.length === 0) return null;
547
- if (restIndicesA.length === 0 && restIndicesB.length === 0) return null;
548
- const restA = restIndicesA.length === 0 ? trueCondition() : restIndicesA.length === 1 ? aChildren[restIndicesA[0]] : and(...restIndicesA.map((i) => aChildren[i]));
549
- const restB = restIndicesB.length === 0 ? trueCondition() : restIndicesB.length === 1 ? bChildren[restIndicesB[0]] : and(...restIndicesB.map((i) => bChildren[i]));
550
- if (simplifyInner({
551
- kind: "compound",
552
- operator: "OR",
553
- children: [restA, restB]
554
- }).kind !== "true") {
555
- const simplifiedRestB = simplifyInner(restB);
556
- if (getConditionUniqueId(simplifyInner(not(restA))) !== getConditionUniqueId(simplifiedRestB)) return null;
557
- }
558
- const common = commonIndicesA.map((i) => aChildren[i]);
559
- if (common.length === 0) return trueCondition();
560
- if (common.length === 1) return common[0];
561
- return and(...common);
562
- }
563
- function sortTerms(terms) {
564
- const withIds = terms.map((t) => [getConditionUniqueId(t), t]);
565
- withIds.sort((a, b) => a[0].localeCompare(b[0]));
566
- return withIds.map(([, t]) => t);
567
- }
568
- /**
569
- * Apply the absorption law: removes compound terms that are absorbed by
570
- * another term already present (simple or compound).
571
- *
572
- * For AND context: A & (A | B) → A (absorbs OR compounds)
573
- * For OR context: A | (A & B) → A (absorbs AND compounds)
574
- *
575
- * After flattening, a compound A = OR(X, Y) becomes [X, Y, ...] in the
576
- * outer OR. A child AND(A, B) = AND(OR(X, Y), B) still references the
577
- * original un-flattened compound. We reconstruct possible compound
578
- * absorbers from the flattened terms so absorption works across nesting.
579
- */
580
- function applyAbsorption(terms, absorbedOperator) {
581
- const absorberIds = /* @__PURE__ */ new Set();
582
- for (const term of terms) absorberIds.add(getConditionUniqueId(term));
583
- let changed = true;
584
- while (changed) {
585
- changed = false;
586
- for (const term of terms) {
587
- if (term.kind !== "compound" || term.operator !== absorbedOperator) continue;
588
- for (const child of term.children) {
589
- if (child.kind !== "compound") continue;
590
- const childId = getConditionUniqueId(child);
591
- if (absorberIds.has(childId)) continue;
592
- if (child.children.every((c) => absorberIds.has(getConditionUniqueId(c)))) {
593
- absorberIds.add(childId);
594
- changed = true;
595
- }
596
- }
597
- }
598
- }
599
- return terms.filter((term) => {
600
- if (term.kind === "compound" && term.operator === absorbedOperator) {
601
- for (const child of term.children) if (absorberIds.has(getConditionUniqueId(child))) return false;
602
- }
603
- return true;
604
- });
605
- }
606
- function applyAbsorptionAnd(terms) {
607
- return applyAbsorption(terms, "OR");
608
- }
609
- function applyAbsorptionOr(terms) {
610
- return applyAbsorption(terms, "AND");
611
- }
612
- /**
613
- * Apply the consensus/resolution rule for AND:
614
- * (A | B) & (A | !B) → A
615
- *
616
- * This is the dual of complementary factoring in OR context:
617
- * (A & B) | (A & !B) → A
618
- *
619
- * Extracts common children from two OR terms. If the remaining
620
- * parts of each side AND to FALSE, the common part alone is
621
- * sufficient.
622
- */
623
- function applyConsensusAnd(terms) {
624
- let changed = true;
625
- while (changed) {
626
- changed = false;
627
- for (let i = 0; i < terms.length; i++) {
628
- const a = terms[i];
629
- if (a.kind !== "compound" || a.operator !== "OR") continue;
630
- for (let j = i + 1; j < terms.length; j++) {
631
- const b = terms[j];
632
- if (b.kind !== "compound" || b.operator !== "OR") continue;
633
- const resolved = tryResolvePair(a.children, b.children);
634
- if (resolved) {
635
- const replacement = simplifyInner(resolved);
636
- terms = [
637
- ...terms.slice(0, i),
638
- ...terms.slice(i + 1, j),
639
- ...terms.slice(j + 1),
640
- replacement
641
- ];
642
- changed = true;
643
- break;
644
- }
645
- }
646
- if (changed) break;
647
- }
648
- }
649
- return terms;
650
- }
651
- /**
652
- * Try to resolve two OR children lists.
653
- *
654
- * Extracts common children (by uniqueId). If the remaining
655
- * (non-common) parts AND to FALSE, the common part alone
656
- * is sufficient: `(common | restA) & (common | restB) → common`
657
- * when `restA & restB → FALSE`.
658
- */
659
- function tryResolvePair(aChildren, bChildren) {
660
- const aIds = aChildren.map((c) => getConditionUniqueId(c));
661
- const bIds = bChildren.map((c) => getConditionUniqueId(c));
662
- const bIdSet = new Set(bIds);
663
- const aIdSet = new Set(aIds);
664
- const commonIndicesA = [];
665
- const restIndicesA = [];
666
- for (let i = 0; i < aIds.length; i++) if (bIdSet.has(aIds[i])) commonIndicesA.push(i);
667
- else restIndicesA.push(i);
668
- const restIndicesB = [];
669
- for (let i = 0; i < bIds.length; i++) if (!aIdSet.has(bIds[i])) restIndicesB.push(i);
670
- if (commonIndicesA.length === 0) return null;
671
- if (restIndicesA.length === 0 && restIndicesB.length === 0) return null;
672
- const restA = restIndicesA.length === 0 ? falseCondition() : restIndicesA.length === 1 ? aChildren[restIndicesA[0]] : or(...restIndicesA.map((i) => aChildren[i]));
673
- const restB = restIndicesB.length === 0 ? falseCondition() : restIndicesB.length === 1 ? bChildren[restIndicesB[0]] : or(...restIndicesB.map((i) => bChildren[i]));
674
- if (simplifyInner({
675
- kind: "compound",
676
- operator: "AND",
677
- children: [restA, restB]
678
- }).kind !== "false") {
679
- const simplifiedRestB = simplifyInner(restB);
680
- if (getConditionUniqueId(simplifyInner(not(restA))) !== getConditionUniqueId(simplifiedRestB)) return null;
681
- }
682
- const common = commonIndicesA.map((i) => aChildren[i]);
683
- if (common.length === 0) return falseCondition();
684
- if (common.length === 1) return common[0];
685
- return or(...common);
686
- }
687
- //#endregion
688
- export { simplifyCondition };
689
-
690
- //# sourceMappingURL=simplify.js.map