zyzz 0.0.28 → 0.0.29

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 (302) hide show
  1. package/binding/wasi/wasi-worker.mjs +186 -0
  2. package/binding/wasi/zyzz.wasi.cjs +2302 -0
  3. package/binding/wasi/zyzz.wasm32-wasi.wasm +0 -0
  4. package/binding/zyzz.linux-x64-gnu.node +0 -0
  5. package/dist/babel/index.d.ts.map +1 -1
  6. package/dist/babel/index.js +2 -4
  7. package/dist/babel/index.js.map +1 -1
  8. package/dist/babel/internal/Compilation.d.ts +0 -1
  9. package/dist/babel/internal/Compilation.d.ts.map +1 -1
  10. package/dist/compiler/Graph.d.ts +14 -11
  11. package/dist/compiler/Graph.d.ts.map +1 -1
  12. package/dist/compiler/Graph.js +57 -1442
  13. package/dist/compiler/Graph.js.map +1 -1
  14. package/dist/compiler/Native.d.ts +7 -9
  15. package/dist/compiler/Native.d.ts.map +1 -1
  16. package/dist/compiler/Native.js +12 -716
  17. package/dist/compiler/Native.js.map +1 -1
  18. package/dist/compiler/Source.d.ts +122 -24
  19. package/dist/compiler/Source.d.ts.map +1 -1
  20. package/dist/compiler/Source.js +10 -1267
  21. package/dist/compiler/Source.js.map +1 -1
  22. package/dist/compiler/Transform.d.ts +4 -3
  23. package/dist/compiler/Transform.d.ts.map +1 -1
  24. package/dist/compiler/Transform.js +13 -961
  25. package/dist/compiler/Transform.js.map +1 -1
  26. package/dist/compiler/internal/AtRules.d.ts +5 -1
  27. package/dist/compiler/internal/AtRules.d.ts.map +1 -1
  28. package/dist/compiler/internal/AtRules.js +12 -106
  29. package/dist/compiler/internal/AtRules.js.map +1 -1
  30. package/dist/compiler/internal/Context.d.ts +11 -0
  31. package/dist/compiler/internal/Context.d.ts.map +1 -0
  32. package/dist/compiler/internal/Context.js +11 -0
  33. package/dist/compiler/internal/Context.js.map +1 -0
  34. package/dist/compiler/internal/Results.d.ts +148 -0
  35. package/dist/compiler/internal/Results.d.ts.map +1 -0
  36. package/dist/compiler/internal/Results.js +259 -0
  37. package/dist/compiler/internal/Results.js.map +1 -0
  38. package/dist/compiler/internal/Syntax.d.ts +0 -2
  39. package/dist/compiler/internal/Syntax.d.ts.map +1 -1
  40. package/dist/compiler/internal/Syntax.js +0 -2
  41. package/dist/compiler/internal/Syntax.js.map +1 -1
  42. package/dist/compiler/internal/Wire.d.ts +17 -0
  43. package/dist/compiler/internal/Wire.d.ts.map +1 -0
  44. package/dist/compiler/internal/Wire.js +795 -0
  45. package/dist/compiler/internal/Wire.js.map +1 -0
  46. package/dist/internal/Addon.d.ts +28 -0
  47. package/dist/internal/Addon.d.ts.map +1 -0
  48. package/dist/internal/Addon.js +87 -0
  49. package/dist/internal/Addon.js.map +1 -0
  50. package/dist/internal/Literal.d.ts +4 -1
  51. package/dist/internal/Literal.d.ts.map +1 -1
  52. package/dist/internal/Literal.js +4 -2
  53. package/dist/internal/Literal.js.map +1 -1
  54. package/dist/internal/Token.d.ts +2 -1
  55. package/dist/internal/Token.d.ts.map +1 -1
  56. package/dist/internal/Token.js +2 -2
  57. package/dist/internal/Token.js.map +1 -1
  58. package/dist/internal/Vlq.d.ts +14 -0
  59. package/dist/internal/Vlq.d.ts.map +1 -0
  60. package/dist/internal/Vlq.js +47 -0
  61. package/dist/internal/Vlq.js.map +1 -0
  62. package/dist/internal/Wasm.d.ts +22 -0
  63. package/dist/internal/Wasm.d.ts.map +1 -0
  64. package/dist/internal/Wasm.js +83 -0
  65. package/dist/internal/Wasm.js.map +1 -0
  66. package/dist/metro/Graph.d.ts +0 -1
  67. package/dist/metro/Graph.d.ts.map +1 -1
  68. package/dist/metro/transformer.d.ts.map +1 -1
  69. package/dist/metro/transformer.js +0 -1
  70. package/dist/metro/transformer.js.map +1 -1
  71. package/dist/next/internal/Project.d.ts.map +1 -1
  72. package/dist/next/internal/Project.js +2 -5
  73. package/dist/next/internal/Project.js.map +1 -1
  74. package/dist/node/Host.d.ts.map +1 -1
  75. package/dist/node/Host.js +0 -2
  76. package/dist/node/Host.js.map +1 -1
  77. package/dist/node/internal/Contracts.d.ts.map +1 -1
  78. package/dist/node/internal/Contracts.js +3 -7
  79. package/dist/node/internal/Contracts.js.map +1 -1
  80. package/dist/node/internal/Snapshot.d.ts +0 -1
  81. package/dist/node/internal/Snapshot.d.ts.map +1 -1
  82. package/dist/node/internal/Snapshot.js +0 -6
  83. package/dist/node/internal/Snapshot.js.map +1 -1
  84. package/dist/runtime/Composition.d.ts +2 -3
  85. package/dist/runtime/Composition.d.ts.map +1 -1
  86. package/dist/runtime/Composition.js +51 -30
  87. package/dist/runtime/Composition.js.map +1 -1
  88. package/dist/runtime/Recipe.d.ts.map +1 -1
  89. package/dist/runtime/Recipe.js +16 -12
  90. package/dist/runtime/Recipe.js.map +1 -1
  91. package/dist/unplugin/index.d.ts.map +1 -1
  92. package/dist/unplugin/index.js +3 -6
  93. package/dist/unplugin/index.js.map +1 -1
  94. package/dist/vite/index.d.ts.map +1 -1
  95. package/dist/vite/index.js +696 -201
  96. package/dist/vite/index.js.map +1 -1
  97. package/dist/web/Css.d.ts +8 -3
  98. package/dist/web/Css.d.ts.map +1 -1
  99. package/dist/web/Css.js +5 -721
  100. package/dist/web/Css.js.map +1 -1
  101. package/dist/web/internal/Block.d.ts +0 -2
  102. package/dist/web/internal/Block.d.ts.map +1 -1
  103. package/dist/web/internal/Block.js +1 -12
  104. package/dist/web/internal/Block.js.map +1 -1
  105. package/dist/web/internal/ClassName.d.ts +23 -18
  106. package/dist/web/internal/ClassName.d.ts.map +1 -1
  107. package/dist/web/internal/ClassName.js +26 -55
  108. package/dist/web/internal/ClassName.js.map +1 -1
  109. package/dist/web/internal/Contributions.d.ts +3 -5
  110. package/dist/web/internal/Contributions.d.ts.map +1 -1
  111. package/dist/web/internal/Contributions.js +0 -45
  112. package/dist/web/internal/Contributions.js.map +1 -1
  113. package/dist/web/internal/Engine.browser.d.ts +8 -0
  114. package/dist/web/internal/Engine.browser.d.ts.map +1 -0
  115. package/dist/web/internal/Engine.browser.js +42 -0
  116. package/dist/web/internal/Engine.browser.js.map +1 -0
  117. package/dist/web/internal/Engine.d.ts +9 -0
  118. package/dist/web/internal/Engine.d.ts.map +1 -0
  119. package/dist/web/internal/Engine.js +14 -0
  120. package/dist/web/internal/Engine.js.map +1 -0
  121. package/dist/web/internal/Themes.d.ts +1 -9
  122. package/dist/web/internal/Themes.d.ts.map +1 -1
  123. package/dist/web/internal/Themes.js +3 -221
  124. package/dist/web/internal/Themes.js.map +1 -1
  125. package/dist/web/internal/Wasm.generated.d.ts +4 -0
  126. package/dist/web/internal/Wasm.generated.d.ts.map +1 -0
  127. package/dist/web/internal/Wasm.generated.js +4 -0
  128. package/dist/web/internal/Wasm.generated.js.map +1 -0
  129. package/dist/web/internal/Wire.d.ts +19 -0
  130. package/dist/web/internal/Wire.d.ts.map +1 -0
  131. package/dist/web/internal/Wire.js +387 -0
  132. package/dist/web/internal/Wire.js.map +1 -0
  133. package/package.json +20 -1
  134. package/src/babel/index.ts +2 -5
  135. package/src/babel/internal/Compilation.ts +0 -1
  136. package/src/compiler/Graph.ts +89 -1930
  137. package/src/compiler/Native.ts +18 -871
  138. package/src/compiler/Source.ts +144 -1803
  139. package/src/compiler/Transform.ts +16 -1315
  140. package/src/compiler/internal/AtRules.ts +27 -115
  141. package/src/compiler/internal/Context.ts +11 -0
  142. package/src/compiler/internal/Results.ts +406 -0
  143. package/src/compiler/internal/Syntax.ts +0 -3
  144. package/src/compiler/internal/Wire.ts +1045 -0
  145. package/src/internal/Addon.ts +118 -0
  146. package/src/internal/Literal.ts +4 -2
  147. package/src/internal/Token.ts +2 -2
  148. package/src/internal/Vlq.ts +59 -0
  149. package/src/internal/Wasm.ts +111 -0
  150. package/src/metro/transformer.ts +0 -1
  151. package/src/next/internal/Project.ts +2 -9
  152. package/src/node/Host.ts +0 -2
  153. package/src/node/internal/Contracts.ts +3 -7
  154. package/src/node/internal/Snapshot.ts +0 -8
  155. package/src/runtime/Composition.ts +48 -25
  156. package/src/runtime/Recipe.ts +21 -14
  157. package/src/unplugin/index.ts +6 -6
  158. package/src/vite/index.ts +922 -221
  159. package/src/web/Css.ts +12 -908
  160. package/src/web/internal/Block.ts +0 -14
  161. package/src/web/internal/ClassName.ts +52 -85
  162. package/src/web/internal/Contributions.ts +3 -59
  163. package/src/web/internal/Engine.browser.ts +51 -0
  164. package/src/web/internal/Engine.ts +17 -0
  165. package/src/web/internal/Themes.ts +3 -279
  166. package/src/web/internal/Wasm.generated.ts +3 -0
  167. package/src/web/internal/Wire.ts +466 -0
  168. package/src/web/internal/wasm.d.ts +9 -0
  169. package/dist/compiler/internal/Applications.d.ts +0 -55
  170. package/dist/compiler/internal/Applications.d.ts.map +0 -1
  171. package/dist/compiler/internal/Applications.js +0 -393
  172. package/dist/compiler/internal/Applications.js.map +0 -1
  173. package/dist/compiler/internal/ColorProfiles.d.ts +0 -3
  174. package/dist/compiler/internal/ColorProfiles.d.ts.map +0 -1
  175. package/dist/compiler/internal/ColorProfiles.js +0 -84
  176. package/dist/compiler/internal/ColorProfiles.js.map +0 -1
  177. package/dist/compiler/internal/CompositionBindings.d.ts +0 -16
  178. package/dist/compiler/internal/CompositionBindings.d.ts.map +0 -1
  179. package/dist/compiler/internal/CompositionBindings.js +0 -89
  180. package/dist/compiler/internal/CompositionBindings.js.map +0 -1
  181. package/dist/compiler/internal/Compositions.d.ts +0 -37
  182. package/dist/compiler/internal/Compositions.d.ts.map +0 -1
  183. package/dist/compiler/internal/Compositions.js +0 -494
  184. package/dist/compiler/internal/Compositions.js.map +0 -1
  185. package/dist/compiler/internal/Configurations.d.ts +0 -26
  186. package/dist/compiler/internal/Configurations.d.ts.map +0 -1
  187. package/dist/compiler/internal/Configurations.js +0 -259
  188. package/dist/compiler/internal/Configurations.js.map +0 -1
  189. package/dist/compiler/internal/Contract.d.ts +0 -30
  190. package/dist/compiler/internal/Contract.d.ts.map +0 -1
  191. package/dist/compiler/internal/Contract.js +0 -753
  192. package/dist/compiler/internal/Contract.js.map +0 -1
  193. package/dist/compiler/internal/Contributions.d.ts +0 -54
  194. package/dist/compiler/internal/Contributions.d.ts.map +0 -1
  195. package/dist/compiler/internal/Contributions.js +0 -1151
  196. package/dist/compiler/internal/Contributions.js.map +0 -1
  197. package/dist/compiler/internal/Descriptors.d.ts +0 -15
  198. package/dist/compiler/internal/Descriptors.d.ts.map +0 -1
  199. package/dist/compiler/internal/Descriptors.js +0 -192
  200. package/dist/compiler/internal/Descriptors.js.map +0 -1
  201. package/dist/compiler/internal/Dynamic.d.ts +0 -14
  202. package/dist/compiler/internal/Dynamic.d.ts.map +0 -1
  203. package/dist/compiler/internal/Dynamic.js +0 -175
  204. package/dist/compiler/internal/Dynamic.js.map +0 -1
  205. package/dist/compiler/internal/Expression.d.ts +0 -19
  206. package/dist/compiler/internal/Expression.d.ts.map +0 -1
  207. package/dist/compiler/internal/Expression.js +0 -164
  208. package/dist/compiler/internal/Expression.js.map +0 -1
  209. package/dist/compiler/internal/Functions.d.ts +0 -5
  210. package/dist/compiler/internal/Functions.d.ts.map +0 -1
  211. package/dist/compiler/internal/Functions.js +0 -191
  212. package/dist/compiler/internal/Functions.js.map +0 -1
  213. package/dist/compiler/internal/Keyframes.d.ts +0 -5
  214. package/dist/compiler/internal/Keyframes.d.ts.map +0 -1
  215. package/dist/compiler/internal/Keyframes.js +0 -51
  216. package/dist/compiler/internal/Keyframes.js.map +0 -1
  217. package/dist/compiler/internal/Names.d.ts +0 -5
  218. package/dist/compiler/internal/Names.d.ts.map +0 -1
  219. package/dist/compiler/internal/Names.js +0 -37
  220. package/dist/compiler/internal/Names.js.map +0 -1
  221. package/dist/compiler/internal/NativeBindings.d.ts +0 -72
  222. package/dist/compiler/internal/NativeBindings.d.ts.map +0 -1
  223. package/dist/compiler/internal/NativeBindings.js +0 -171
  224. package/dist/compiler/internal/NativeBindings.js.map +0 -1
  225. package/dist/compiler/internal/NativeMedia.d.ts +0 -14
  226. package/dist/compiler/internal/NativeMedia.d.ts.map +0 -1
  227. package/dist/compiler/internal/NativeMedia.js +0 -287
  228. package/dist/compiler/internal/NativeMedia.js.map +0 -1
  229. package/dist/compiler/internal/NativeVars.d.ts +0 -28
  230. package/dist/compiler/internal/NativeVars.d.ts.map +0 -1
  231. package/dist/compiler/internal/NativeVars.js +0 -160
  232. package/dist/compiler/internal/NativeVars.js.map +0 -1
  233. package/dist/compiler/internal/PackedStyles.d.ts +0 -37
  234. package/dist/compiler/internal/PackedStyles.d.ts.map +0 -1
  235. package/dist/compiler/internal/PackedStyles.js +0 -344
  236. package/dist/compiler/internal/PackedStyles.js.map +0 -1
  237. package/dist/compiler/internal/Properties.d.ts +0 -5
  238. package/dist/compiler/internal/Properties.d.ts.map +0 -1
  239. package/dist/compiler/internal/Properties.js +0 -82
  240. package/dist/compiler/internal/Properties.js.map +0 -1
  241. package/dist/compiler/internal/RecipeConditions.d.ts +0 -41
  242. package/dist/compiler/internal/RecipeConditions.d.ts.map +0 -1
  243. package/dist/compiler/internal/RecipeConditions.js +0 -82
  244. package/dist/compiler/internal/RecipeConditions.js.map +0 -1
  245. package/dist/compiler/internal/RecipePayloads.d.ts +0 -31
  246. package/dist/compiler/internal/RecipePayloads.d.ts.map +0 -1
  247. package/dist/compiler/internal/RecipePayloads.js +0 -99
  248. package/dist/compiler/internal/RecipePayloads.js.map +0 -1
  249. package/dist/compiler/internal/Recipes.d.ts +0 -32
  250. package/dist/compiler/internal/Recipes.d.ts.map +0 -1
  251. package/dist/compiler/internal/Recipes.js +0 -339
  252. package/dist/compiler/internal/Recipes.js.map +0 -1
  253. package/dist/compiler/internal/Selectors.d.ts +0 -13
  254. package/dist/compiler/internal/Selectors.d.ts.map +0 -1
  255. package/dist/compiler/internal/Selectors.js +0 -280
  256. package/dist/compiler/internal/Selectors.js.map +0 -1
  257. package/dist/compiler/internal/Static.d.ts +0 -39
  258. package/dist/compiler/internal/Static.d.ts.map +0 -1
  259. package/dist/compiler/internal/Static.js +0 -534
  260. package/dist/compiler/internal/Static.js.map +0 -1
  261. package/dist/compiler/internal/Themes.d.ts +0 -190
  262. package/dist/compiler/internal/Themes.d.ts.map +0 -1
  263. package/dist/compiler/internal/Themes.js +0 -1577
  264. package/dist/compiler/internal/Themes.js.map +0 -1
  265. package/dist/compiler/internal/Vars.d.ts +0 -33
  266. package/dist/compiler/internal/Vars.d.ts.map +0 -1
  267. package/dist/compiler/internal/Vars.js +0 -387
  268. package/dist/compiler/internal/Vars.js.map +0 -1
  269. package/dist/compiler/internal/ViewTransitions.d.ts +0 -3
  270. package/dist/compiler/internal/ViewTransitions.d.ts.map +0 -1
  271. package/dist/compiler/internal/ViewTransitions.js +0 -68
  272. package/dist/compiler/internal/ViewTransitions.js.map +0 -1
  273. package/dist/internal/Cascade.d.ts +0 -74
  274. package/dist/internal/Cascade.d.ts.map +0 -1
  275. package/dist/internal/Cascade.js +0 -210
  276. package/dist/internal/Cascade.js.map +0 -1
  277. package/src/compiler/internal/Applications.ts +0 -610
  278. package/src/compiler/internal/ColorProfiles.ts +0 -93
  279. package/src/compiler/internal/CompositionBindings.ts +0 -120
  280. package/src/compiler/internal/Compositions.ts +0 -678
  281. package/src/compiler/internal/Configurations.ts +0 -349
  282. package/src/compiler/internal/Contract.ts +0 -1028
  283. package/src/compiler/internal/Contributions.ts +0 -1561
  284. package/src/compiler/internal/Descriptors.ts +0 -242
  285. package/src/compiler/internal/Dynamic.ts +0 -275
  286. package/src/compiler/internal/Expression.ts +0 -218
  287. package/src/compiler/internal/Functions.ts +0 -206
  288. package/src/compiler/internal/Keyframes.ts +0 -62
  289. package/src/compiler/internal/Names.ts +0 -48
  290. package/src/compiler/internal/NativeBindings.ts +0 -235
  291. package/src/compiler/internal/NativeMedia.ts +0 -342
  292. package/src/compiler/internal/NativeVars.ts +0 -231
  293. package/src/compiler/internal/PackedStyles.ts +0 -473
  294. package/src/compiler/internal/Properties.ts +0 -121
  295. package/src/compiler/internal/RecipeConditions.ts +0 -139
  296. package/src/compiler/internal/RecipePayloads.ts +0 -132
  297. package/src/compiler/internal/Recipes.ts +0 -531
  298. package/src/compiler/internal/Selectors.ts +0 -353
  299. package/src/compiler/internal/Static.ts +0 -784
  300. package/src/compiler/internal/Themes.ts +0 -2398
  301. package/src/compiler/internal/Vars.ts +0 -516
  302. package/src/compiler/internal/ViewTransitions.ts +0 -82
package/src/web/Css.ts CHANGED
@@ -1,19 +1,16 @@
1
1
  /**
2
2
  * Emits deterministic CSS, class mappings, and live theme scopes from ordered styles.
3
+ * The Rust compiler emits the CSS: Node runs its native addon and browsers its WebAssembly build.
3
4
  * @module
4
5
  */
5
- import * as Targets from '../internal/Targets.js'
6
- import * as ClassName from './internal/ClassName.js'
7
- import * as Identity from '../internal/Identity.js'
8
- import * as Contributions from './internal/Contributions.js'
9
- import * as Binding from '../internal/Binding.js'
10
- import * as Cascade from '../internal/Cascade.js'
11
- import * as Literal from '../internal/Literal.js'
12
- import * as Token from '../internal/Token.js'
13
6
  import type * as Style from '../Style.js'
14
7
  import type * as Vars from '../Vars.js'
15
8
  import type * as Theme from '../internal/Theme.js'
16
- import * as Themes from './internal/Themes.js'
9
+ import * as ClassName from './internal/ClassName.js'
10
+ import type * as Contributions from './internal/Contributions.js'
11
+ import * as Engine from './internal/Engine.js'
12
+ import type * as Themes from './internal/Themes.js'
13
+ import * as Wire from './internal/Wire.js'
17
14
 
18
15
  /** Explicit ordered stylesheet contribution data. */
19
16
  export type Contribution = Contributions.Definition
@@ -35,898 +32,13 @@ export function compile<
35
32
  >(
36
33
  options: compile.Options<name, themeName>,
37
34
  ): compile.ReturnType<name, themeName> {
38
- const labels = options[ClassName.labels] ?? options.styles[ClassName.labels]
39
- const units =
40
- options[ClassName.units] ??
41
- ClassName.registry().scope({ owner: '', qualifier: '' })
42
- options = {
43
- ...options,
44
- styles: { styles: options.styles.styles.map(Targets.web) },
45
- }
46
- let theme: ReturnType<typeof Themes.create> | undefined
47
-
48
- const references = new Map<object, boolean>()
49
-
50
- function isReference(value: unknown): value is Token.Reference {
51
- if (typeof value !== 'object' || value === null) return false
52
-
53
- const previous = references.get(value)
54
- if (previous !== undefined) return previous
55
-
56
- const result = Token.is(value)
57
-
58
- references.set(value, result)
59
-
60
- return result
61
- }
62
-
63
- const bodies = new Map<Style.NamedStyle, string>()
64
- const declarations = new Map<Style.Declaration, string>()
65
- type Property = {
66
- readonly important: Map<Style.Declaration['value'], string>
67
- readonly name: string
68
- readonly normal: Map<Style.Declaration['value'], string>
69
- }
70
- const declarationProperties = new Map<string, Property>()
71
- const serialized = new Map<object, string>()
72
-
73
- // Only primitive declaration lists can be interned without erasing token identity.
74
- // Reuse their emitted bodies throughout analysis and output.
75
- const repeated = new Map<string, Style.NamedStyle>()
76
-
77
- const canonicalStyles = options.styles.styles.map((style) => {
78
- if (
79
- 'rules' in style ||
80
- style.declarations.some(
81
- (declaration) => typeof declaration.value === 'object',
82
- )
83
- )
84
- return style
85
-
86
- const key = nested(style)
87
- const previous = repeated.get(key)
88
- if (previous) return previous
89
-
90
- repeated.set(key, style)
91
-
92
- return style
93
- })
94
-
95
- const analyzed = [...new Set(canonicalStyles)]
96
- const classes = Object.create(null) as Record<name, string>
97
- const diagnostics: Diagnostic[] = []
98
- const groups = new Map<string, false | string>()
99
- const nestedComposition = options.styles.styles.some(
100
- (style) => style.rules && !isolated(style),
101
- )
102
-
103
- const properties = new Set<Style.Declaration['property']>()
104
- // Conditional and composed declarations join the same conflict domains.
105
- function collect(style: Style.NamedStyle): void {
106
- for (const { property } of style.declarations) properties.add(property)
107
- for (const rule of style.rules ?? []) collect(rule.style)
108
- }
109
- for (const style of analyzed) collect(style)
110
-
111
- // Logical dimensions may alias either physical axis in inherited writing modes.
112
- // Preserve physical-only factoring when no logical dimension is authored.
113
- const logicalSizing = [...properties].some((property) =>
114
- /^(min|max)?(blockSize|inlineSize)$/i.test(canonical(property)),
115
- )
116
- const resets = properties.has('all')
117
- const combinedLines = new Set<string>()
118
-
119
- for (const property of properties)
120
- if (Literal.rule(property)?.kind === 'line') {
121
- const name = canonical(property)
122
- combinedLines.add(name.startsWith('border') ? 'border' : name)
123
- }
124
-
125
- function canonical(property: string): string {
126
- return property in Literal.aliases
127
- ? Literal.aliases[property as keyof typeof Literal.aliases]
128
- : property
129
- }
130
-
131
- function domain(property: string): string {
132
- if (
133
- resets &&
134
- !property.startsWith('--') &&
135
- property !== 'direction' &&
136
- property !== 'unicodeBidi'
137
- )
138
- return 'all'
139
-
140
- if (/^marker(?:Start|Mid|End)?$/.test(property)) return 'marker'
141
- if (property.startsWith('corner')) return 'cornerShape'
142
- if (property.startsWith('containIntrinsic')) return 'containIntrinsicSize'
143
- if (property.startsWith('interestDelay')) return 'interestDelay'
144
- if (property.startsWith('backgroundPosition')) return 'backgroundPosition'
145
-
146
- if (combinedLines.has('columnRule') && property.startsWith('columnRule'))
147
- return 'columnRule'
148
-
149
- if (combinedLines.has('outline') && property.startsWith('outline'))
150
- return 'outline'
151
-
152
- if (property.startsWith('borderImage')) return 'borderImage'
153
-
154
- if (property.startsWith('border')) {
155
- if (combinedLines.has('border')) return 'border'
156
-
157
- if (property.endsWith('Color')) {
158
- return 'borderColor'
159
- }
160
-
161
- if (property.endsWith('Style')) {
162
- return 'borderStyle'
163
- }
164
-
165
- if (property.endsWith('Width')) {
166
- return 'borderWidth'
167
- }
168
-
169
- return 'borderRadius'
170
- }
171
-
172
- if (['flexDirection', 'flexFlow', 'flexWrap'].includes(property))
173
- return 'flexFlow'
174
-
175
- if (/^(pageBreak|break)(After|Before|Inside)$/.test(property))
176
- return property.replace('pageBreak', 'break')
177
-
178
- if (['fontStretch', 'fontWidth'].includes(property)) return 'fontWidth'
179
- if (property.startsWith('fontSynthesis')) return 'fontSynthesis'
180
-
181
- if (
182
- [
183
- 'whiteSpace',
184
- 'whiteSpaceCollapse',
185
- 'whiteSpaceTrim',
186
- 'textWrap',
187
- 'textWrapMode',
188
- 'textWrapStyle',
189
- ].includes(property)
190
- )
191
- return 'whiteSpace'
192
-
193
- if (['wordWrap', 'overflowWrap'].includes(property)) return 'overflowWrap'
194
-
195
- if (property.startsWith('margin')) {
196
- return 'margin'
197
- }
198
-
199
- if (property.startsWith('padding')) {
200
- return 'padding'
201
- }
202
-
203
- if (
204
- property === 'overflow' ||
205
- property === 'overflowX' ||
206
- property === 'overflowY' ||
207
- property === 'overflowBlock' ||
208
- property === 'overflowInline'
209
- ) {
210
- return 'overflow'
211
- }
212
-
213
- if (property.startsWith('overscrollBehavior')) {
214
- return 'overscrollBehavior'
215
- }
216
-
217
- if (property.startsWith('scrollMargin')) {
218
- return 'scrollMargin'
219
- }
220
-
221
- if (property.startsWith('scrollPadding')) {
222
- return 'scrollPadding'
223
- }
224
-
225
- if (['columnGap', 'gap', 'rowGap'].includes(property)) {
226
- return 'gap'
227
- }
228
-
229
- if (/^(inset|top$|right$|bottom$|left$)/.test(property)) {
230
- return 'inset'
231
- }
232
-
233
- if (
234
- logicalSizing &&
235
- /^(min|max)?(width|height|blockSize|inlineSize)$/i.test(property)
236
- ) {
237
- if (property.startsWith('min')) {
238
- return 'min-size'
239
- }
240
-
241
- if (property.startsWith('max')) {
242
- return 'max-size'
243
- }
244
-
245
- return 'size'
246
- }
247
-
248
- return property
249
- }
250
-
251
- const parents = new Map<string, string>()
252
-
253
- function root(domain: string): string {
254
- const parent = parents.get(domain)
255
- if (!parent) return domain
256
-
257
- const result = root(parent)
258
-
259
- parents.set(domain, result)
260
-
261
- return result
262
- }
263
-
264
- // Union only authored shorthands. Unrelated axes retain their original factoring.
265
- // Recursion includes nested and reset-only shorthands without parsing CSS values.
266
- function join(property: string, target: string, visited = new Set<string>()) {
267
- if (visited.has(property)) return
268
-
269
- visited.add(property)
270
-
271
- const current = root(domain(canonical(property)))
272
- const group = root(target)
273
-
274
- if (current !== group) parents.set(current, group)
275
-
276
- if (Object.hasOwn(Cascade.shorthands, property))
277
- for (const child of Cascade.shorthands[
278
- property as keyof typeof Cascade.shorthands
279
- ])
280
- join(child, target, visited)
281
- }
282
-
283
- for (const property of new Set([...properties].map(canonical)))
284
- if (Object.hasOwn(Cascade.shorthands, property))
285
- join(property, domain(property))
286
-
287
- function serialize(input: Style.Declaration['value']): number | string {
288
- if (typeof input !== 'object' || input === null) return input
289
-
290
- const cached = serialized.get(input)
291
- if (cached !== undefined) return cached
292
-
293
- const value = serializeReference(input)
294
-
295
- if (typeof value === 'string') serialized.set(input, value)
296
-
297
- return value
298
- }
299
-
300
- function serializeReference(
301
- input: Style.Declaration['value'],
302
- ): number | string {
303
- if (Binding.is(input)) return `var(${input.name})`
304
- if (isReference(input)) return (theme ??= Themes.create()).serialize(input)
305
-
306
- if (Token.isExpression(input))
307
- return input.parts
308
- .map((part) => (typeof part === 'string' ? part : serialize(part)))
309
- .join('')
310
-
311
- return input as number | string
312
- }
313
-
314
- function declarationBody(declaration: Style.Declaration): string {
315
- const previous = declarations.get(declaration)
316
- if (previous !== undefined) return previous
317
-
318
- const { important, property, value } = declaration
319
- let entry = declarationProperties.get(property)
320
- if (!entry) {
321
- entry = {
322
- important: new Map(),
323
- name: Literal.name(property),
324
- normal: new Map(),
325
- }
326
- declarationProperties.set(property, entry)
327
- }
35
+ const input = Wire.encode(options as compile.Options)
328
36
 
329
- const values = important ? entry.important : entry.normal
330
- let body = values.get(value)
331
- if (body === undefined) {
332
- body = `${entry.name}:${serialize(value)}${important ? '!important' : ''};`
333
- values.set(value, body)
334
- }
335
-
336
- declarations.set(declaration, body)
337
- return body
338
- }
339
-
340
- function nested(style: Style.NamedStyle): string {
341
- const previous = bodies.get(style)
342
- if (previous !== undefined) return previous
343
- const body = renderNested(style)
344
- bodies.set(style, body)
345
- return body
346
- }
347
-
348
- function renderNested(style: Style.NamedStyle): string {
349
- if (style.rules)
350
- return style.rules
351
- .map((rule) => {
352
- const body = nested(rule.style)
353
-
354
- return rule.condition === undefined
355
- ? body
356
- : `${rule.condition}{${body}}`
357
- })
358
- .join('')
359
-
360
- return style.declarations.map(declarationBody).join('')
361
- }
362
-
363
- const domainsByProperty = new Map<string, string>()
364
- function conflict(property: string): string {
365
- const previous = domainsByProperty.get(property)
366
- if (previous !== undefined) return previous
367
- const value = root(domain(canonical(property)))
368
- domainsByProperty.set(property, value)
369
- return value
370
- }
371
-
372
- // Sharing is safe only when every use of a conflict domain has the same
373
- // declaration sequence. Conditions conservatively retain contextual identities.
374
- // Isolated class lists never combine, so atomic sharing considers ordered styles only.
375
- const ordered = new Map<string, false | string>()
376
- const combinable = new Set<Style.NamedStyle>()
377
- for (const [index, style] of options.styles.styles.entries())
378
- if (!isolated(style)) combinable.add(canonicalStyles[index]!)
379
-
380
- for (const style of analyzed) {
381
- const domains = new Map<
382
- string,
383
- { body: string; mixed: boolean; property: string }
384
- >()
385
-
386
- for (const item of style.declarations) {
387
- const property = item.property
388
- const key = conflict(property)
389
- const entry = domains.get(key) ?? { body: '', mixed: false, property }
390
- entry.body += declarationBody(item)
391
- entry.mixed ||= entry.property !== property
392
- domains.set(key, entry)
393
- }
394
-
395
- for (const [key, entry] of domains)
396
- for (const map of combinable.has(style) ? [groups, ordered] : [groups]) {
397
- const previous = map.get(key)
398
- map.set(
399
- key,
400
- previous === false ||
401
- entry.mixed ||
402
- (previous !== undefined && previous !== entry.body)
403
- ? false
404
- : entry.body,
405
- )
406
- }
407
- }
408
-
409
- const defaultMode = options.cssOutput ?? 'atomic'
410
- if (defaultMode !== 'atomic' && defaultMode !== 'grouped')
411
- throw new CompileError([
412
- {
413
- code: 'invalid_output',
414
- message: 'cssOutput must be atomic or grouped.',
415
- path: ['cssOutput'],
416
- },
417
- ])
418
-
419
- function outputMode(style: Style.NamedStyle) {
420
- return Object.getOwnPropertyDescriptor(style, 'cssOutput')?.value as
421
- | 'atomic'
422
- | 'grouped'
423
- | undefined
424
- }
425
-
426
- function compositionMode(style: Style.NamedStyle) {
427
- const mode = Object.getOwnPropertyDescriptor(style, 'composition')
428
- ?.value as 'independent' | 'ordered' | undefined
429
-
430
- return mode ?? options.composition ?? 'ordered'
431
- }
432
-
433
- // Development keeps every style ordered so names survive value edits.
434
- function isolated(style: Style.NamedStyle) {
435
- return compositionMode(style) === 'independent' && !options.development
436
- }
437
-
438
- type Item = {
439
- readonly conditions: readonly string[]
440
- readonly property: string
441
- readonly value: string
442
- }
443
-
444
- // Lists declaration groups in authored order; undefined marks styles whose
445
- // nested grouped output or anonymous layers emit one opaque rule.
446
- function flatten(
447
- style: Style.NamedStyle,
448
- conditions: readonly string[] = [],
449
- ): Item[] | undefined {
450
- if (outputMode(style) === 'grouped') return undefined
451
-
452
- if (style.rules) {
453
- const items: Item[] = []
454
- for (const rule of style.rules) {
455
- if (rule.condition?.trim() === '@layer') return undefined
456
-
457
- const nested = flatten(
458
- rule.style,
459
- rule.condition === undefined
460
- ? conditions
461
- : [...conditions, rule.condition],
462
- )
463
- if (!nested) return undefined
464
-
465
- items.push(...nested)
466
- }
467
- return items
468
- }
469
-
470
- const items: Item[] = []
471
- for (let index = 0; index < style.declarations.length; ) {
472
- const property = style.declarations[index]!.property
473
- let value = ''
474
- // Keep same-property fallbacks ordered; they form one semantic value.
475
- while (style.declarations[index]?.property === property) {
476
- const declaration = style.declarations[index++]!
477
- value += `${Literal.name(property)}:${serialize(declaration.value)}${declaration.important ? '!important' : ''};`
478
- }
479
- items.push({ conditions, property, value })
480
- }
481
- return items
482
- }
483
-
484
- function byDomain(items: readonly Item[]) {
485
- const result = new Map<string, Item[]>()
486
- for (const item of items) {
487
- const key = conflict(item.property)
488
- const domain = result.get(key)
489
- if (domain) domain.push(item)
490
- else result.set(key, [item])
491
- }
492
- return result
493
- }
494
-
495
- function representation(style: Style.NamedStyle): unknown {
496
- return [
497
- outputMode(style),
498
- style.rules?.map((rule) => representation(rule.style)),
499
- ]
500
- }
501
-
502
- function validate(style: Style.NamedStyle) {
503
- const mode = outputMode(style)
504
- if (mode !== undefined && mode !== 'atomic' && mode !== 'grouped')
505
- throw new CompileError([
506
- {
507
- code: 'invalid_output',
508
- message: 'cssOutput must be atomic or grouped.',
509
- path: [style.name, 'cssOutput'],
510
- },
511
- ])
512
- for (const rule of style.rules ?? []) validate(rule.style)
513
- }
514
- for (const style of options.styles.styles) validate(style)
515
-
516
- const identities = new Map<string, string>()
517
- const rules = new Map<string, string>()
518
- type ConditionalRule = { conditions: readonly string[]; value: string }
519
- const conditionalRules = new Map<string, ConditionalRule>()
520
- type SharedRules = Record<'atomic' | 'grouped', Map<string, string>>
521
- const identical = new Map<string | undefined, SharedRules>()
522
- const explicitBodies = new Map<string, string>()
523
- const selectors = new Map<string, string>()
524
- const explicitModes = new Set<string>()
525
- const applications = new Map<string, string>()
526
- const occurrences = new Map<string, number>()
527
- for (const style of options.styles.styles)
528
- for (const declaration of style.declarations) {
529
- const key = conflict(declaration.property)
530
- occurrences.set(key, (occurrences.get(key) ?? 0) + 1)
531
- }
532
-
533
- // An ordered atomic style reuses the rules of the previous style that set a
534
- // domain to the same sequence: no differing rule sits between them.
535
- const runs = new Map<number, Map<string, number>>()
536
- const owned = new Map<number, Map<string, string[]>>()
537
- if (!options.development) {
538
- const last = new Map<string, { key: string; owner: number }>()
539
-
540
- for (const [index, style] of options.styles.styles.entries()) {
541
- if (isolated(style)) continue
542
-
543
- const items =
544
- (outputMode(style) ?? defaultMode) === 'atomic' &&
545
- options.names?.[style.name] === undefined
546
- ? flatten(style)
547
- : undefined
548
- // Grouped, explicit, and opaque rules may set any domain.
549
- if (!items) {
550
- last.clear()
551
- continue
552
- }
553
-
554
- for (const [domain, list] of byDomain(items)) {
555
- const key = JSON.stringify(
556
- list.map((item) => [item.conditions, item.value]),
557
- )
558
- const previous = last.get(domain)
559
- if (previous?.key !== key) {
560
- last.set(domain, { key, owner: index })
561
- continue
562
- }
563
-
564
- const reuse = runs.get(index) ?? new Map<string, number>()
565
- reuse.set(domain, previous.owner)
566
- runs.set(index, reuse)
567
- }
568
- }
569
- }
570
-
571
- for (const [styleIndex, style] of options.styles.styles.entries()) {
572
- const mode = outputMode(style) ?? defaultMode
573
- const independent =
574
- compositionMode(style) === 'independent' && !options.development
575
- if (!style.name || Object.hasOwn(classes, style.name)) {
576
- diagnostics.push({
577
- code: 'invalid_name',
578
- message: 'Style names must be nonempty and unique.',
579
- path: [style.name],
580
- })
581
- continue
582
- }
583
-
584
- const explicit = options.names?.[style.name]
585
- if (explicit !== undefined) {
586
- const body = nested(style)
587
- const previous = explicitBodies.get(explicit)
588
- if (previous !== undefined && previous !== body)
589
- diagnostics.push({
590
- code: 'identity_collision',
591
- message: 'An explicit id is used for different styles.',
592
- path: [style.name],
593
- })
594
- explicitBodies.set(explicit, body)
595
- classes[style.name] = explicit
596
- const key = `${explicit}:${mode}`
597
- if (explicitModes.has(key)) continue
598
- explicitModes.add(key)
599
- }
600
-
601
- const application =
602
- explicit === undefined && independent
603
- ? `${mode}:${style.rules ? JSON.stringify(representation(style)) : ''}:${nested(canonicalStyles[styleIndex]!)}`
604
- : undefined
605
- if (application !== undefined && applications.has(application)) {
606
- classes[style.name] = applications.get(application)!
607
- continue
608
- }
609
-
610
- const names: string[] = explicit === undefined ? [] : [explicit]
611
- let ordinal = 0
612
- const cssName = labels?.[style.name]?.name ?? encode(style.name)
613
- const cssNamespace =
614
- labels?.[style.name]?.namespace ??
615
- (options.scope ? Identity.name(options.scope) : undefined)
616
- let sharedRules = identical.get(cssNamespace)
617
- if (!sharedRules) {
618
- sharedRules = { atomic: new Map(), grouped: new Map() }
619
- identical.set(cssNamespace, sharedRules)
620
- }
621
-
622
- function emit(
623
- body: string,
624
- label: string,
625
- shared: boolean,
626
- output = mode,
627
- conditional?: ConditionalRule,
628
- ): string | undefined {
629
- if (!body) return undefined
630
-
631
- const reusable =
632
- explicit === undefined &&
633
- (shared || (independent && mode === 'grouped' && output === mode))
634
- const previous = reusable ? sharedRules![output].get(body) : undefined
635
- if (previous && !names.includes(previous)) {
636
- names.push(previous)
637
- return previous
638
- }
639
-
640
- if (previous) shared = false
641
-
642
- // Contextual slots preserve authored ordering; development names survive value edits.
643
- const slot = ordinal++
644
- const identity = (() => {
645
- if (explicit !== undefined)
646
- return `${explicit}-${mode}-${encode(label)}-${slot}`
647
- if (output === 'grouped' && mode === 'grouped') {
648
- return `z-${cssNamespace ? `${cssNamespace}-` : ''}${cssName}${slot ? `__${slot}` : ''}`
649
- }
650
- return ClassName.create({
651
- body,
652
- context: !shared ? cssName : undefined,
653
- namespace: cssNamespace,
654
- property: label,
655
- slot: !shared ? slot : undefined,
656
- })
657
- })()
658
- const owner =
659
- mode === 'atomic' && !shared ? `${style.name}:${slot}` : undefined
660
- if (
661
- (rules.has(identity) && rules.get(identity) !== body) ||
662
- (owner !== undefined &&
663
- identities.has(identity) &&
664
- identities.get(identity) !== owner)
665
- )
666
- diagnostics.push({
667
- code: 'identity_collision',
668
- message:
669
- 'Generated class names conflict. Supply distinct config or style ids.',
670
- path: [style.name],
671
- })
672
-
673
- if (owner !== undefined) identities.set(identity, owner)
674
- rules.set(identity, body)
675
- if (
676
- conditional?.conditions.some((condition) =>
677
- /^@(media|supports)\b/.test(condition),
678
- )
679
- )
680
- conditionalRules.set(identity, conditional)
681
- if (explicit !== undefined) selectors.set(identity, explicit)
682
- else {
683
- if (reusable) sharedRules![output].set(body, identity)
684
- names.push(identity)
685
- }
686
-
687
- return identity
688
- }
689
-
690
- function atoms(
691
- style: Style.NamedStyle,
692
- conditions: readonly string[] = [],
693
- ) {
694
- if (outputMode(style) === 'grouped') {
695
- const body = conditions.reduceRight(
696
- (body, condition) => `${condition}{${body}}`,
697
- nested(style),
698
- )
699
- emit(body, 'style', false, 'grouped')
700
- return
701
- }
702
- if (style.rules) {
703
- for (const rule of style.rules) {
704
- if (rule.condition?.trim() === '@layer') {
705
- // Repeating an anonymous layer would change cascade precedence.
706
- const body = [...conditions, rule.condition].reduceRight(
707
- (body, condition) => `${condition}{${body}}`,
708
- nested(rule.style),
709
- )
710
- emit(body, 'layer', false)
711
- continue
712
- }
713
- atoms(
714
- rule.style,
715
- rule.condition === undefined
716
- ? conditions
717
- : [...conditions, rule.condition],
718
- )
719
- }
720
- return
721
- }
722
-
723
- for (let index = 0; index < style.declarations.length; ) {
724
- const declaration = style.declarations[index++]!
725
- const property = declaration.property
726
- const values = [declaration]
727
- // Keep same-property fallbacks ordered; they form one semantic value.
728
- while (style.declarations[index]?.property === property)
729
- values.push(style.declarations[index++]!)
730
-
731
- const domain = conflict(property)
732
- const owner = runs.get(styleIndex)?.get(domain)
733
- const reused =
734
- owner === undefined ? undefined : owned.get(owner)?.get(domain)
735
- if (reused) {
736
- for (const identity of reused)
737
- if (!names.includes(identity)) names.push(identity)
738
- continue
739
- }
740
-
741
- const value = values
742
- .map(
743
- ({ important, value }) =>
744
- `${Literal.name(property)}:${serialize(value)}${important ? '!important' : ''};`,
745
- )
746
- .join('')
747
- const body = conditions.reduceRight(
748
- (body, condition) => `${condition}{${body}}`,
749
- value,
750
- )
751
- const shared =
752
- !nestedComposition &&
753
- !conditions.length &&
754
- ordered.get(domain) !== false
755
- const identity = emit(body, property, shared, mode, {
756
- conditions,
757
- value,
758
- })
759
- if (identity === undefined) continue
760
-
761
- const domains = owned.get(styleIndex) ?? new Map<string, string[]>()
762
- domains.set(domain, [...(domains.get(domain) ?? []), identity])
763
- owned.set(styleIndex, domains)
764
- }
765
- }
766
-
767
- // Independent class lists never combine, so only declarations within one
768
- // conflict domain need relative order. Equal domain bodies share one rule.
769
- function share(style: Style.NamedStyle) {
770
- const items = flatten(style)
771
- if (!items) return atoms(style)
772
-
773
- for (const domain of byDomain(items).values()) {
774
- // Conditional rules stay contextual to keep their order against base declarations.
775
- if (domain.some((item) => item.conditions.length)) {
776
- for (const item of domain)
777
- emit(
778
- item.conditions.reduceRight(
779
- (body, condition) => `${condition}{${body}}`,
780
- item.value,
781
- ),
782
- item.property,
783
- false,
784
- mode,
785
- item,
786
- )
787
- continue
788
- }
789
-
790
- const body = domain.map((item) => item.value).join('')
791
- const identity = units.name(body, cssNamespace)
792
- if (rules.has(identity) && rules.get(identity) !== body)
793
- diagnostics.push({
794
- code: 'identity_collision',
795
- message:
796
- 'Generated class names conflict. Supply distinct config or style ids.',
797
- path: [style.name],
798
- })
799
-
800
- rules.set(identity, body)
801
- names.push(identity)
802
- }
803
- }
804
-
805
- try {
806
- if (mode === 'grouped') {
807
- const shared: Style.Declaration[] = []
808
- const local: Style.Declaration[] = []
809
- for (const declaration of style.declarations) {
810
- const key = conflict(declaration.property)
811
- const reusable =
812
- !style.rules &&
813
- independent &&
814
- groups.get(key) !== false &&
815
- (occurrences.get(key) ?? 0) > 1
816
- if (reusable) shared.push(declaration)
817
- else local.push(declaration)
818
- }
819
- if (shared.length && local.length) {
820
- emit(shared.map(declarationBody).join(''), 'shared', false)
821
- emit(local.map(declarationBody).join(''), 'style', false)
822
- } else emit(nested(style), 'style', false)
823
- } else if (explicit === undefined && independent) share(style)
824
- else atoms(style)
825
- } catch (error) {
826
- diagnostics.push({
827
- code: 'invalid_declaration',
828
- message: (error as Error).message,
829
- path: [style.name],
830
- })
831
- }
832
-
833
- classes[style.name] = [...new Set(names)].join(' ')
834
- if (application !== undefined)
835
- applications.set(application, classes[style.name])
836
- }
837
-
838
- if (diagnostics.length) throw new CompileError(diagnostics)
839
-
840
- const contributionCss = (() => {
841
- try {
842
- return Contributions.render(options.contributions ?? [], nested)
843
- } catch (error) {
844
- throw new CompileError([
845
- {
846
- code: 'invalid_declaration',
847
- message: (error as Error).message,
848
- path: ['contributions'],
849
- },
850
- ])
851
- }
852
- })()
853
-
854
- let scopes: ReturnType<NonNullable<typeof theme>['emit']>
855
-
856
- try {
857
- scopes =
858
- theme || options.vars || options.schemes
859
- ? (theme ??= Themes.create()).emit(
860
- options.vars ?? {},
861
- options.schemes ?? false,
862
- options[Themes.shared],
863
- )
864
- : { classes: Object.freeze({}), css: '', resources: [], rules: [] }
865
- } catch (error) {
866
- throw new CompileError([
867
- {
868
- code: 'invalid_theme',
869
- message: (error as Error).message,
870
- path: ['vars'],
871
- },
872
- ])
873
- }
874
-
875
- const scopedCss = [
876
- scopes.css,
877
- ...[...rules].map((entry) => {
878
- const [name, body] = entry
879
- const selector = `.${ClassName.selector(selectors.get(name) ?? name)}`
880
- const conditional = conditionalRules.get(name)
881
- if (
882
- !conditional ||
883
- conditional.conditions.some(
884
- (condition) =>
885
- condition.startsWith('@') &&
886
- !/^@(media|supports)\b/.test(condition),
887
- )
888
- )
889
- return `${selector}{${body}}`
890
-
891
- // Inactive conditions must surround the class rather than leave a matched empty wrapper.
892
- const conditions = conditional.conditions.filter((condition) =>
893
- condition.startsWith('@'),
894
- )
895
- const nested = conditional.conditions
896
- .filter((condition) => !condition.startsWith('@'))
897
- .reduceRight(
898
- (body, condition) => `${condition}{${body}}`,
899
- conditional.value,
900
- )
901
- return conditions.reduceRight(
902
- (body, condition) => `${condition}{${body}}`,
903
- `${selector}{${nested}}`,
904
- )
905
- }),
906
- ]
907
- .filter(Boolean)
908
- .join('\n')
909
-
910
- const result = {
911
- ...(scopes.resources.length ? { [Themes.shared]: scopes.resources } : {}),
912
- ...(contributionCss ? { contributionCss, scopedCss } : {}),
913
- [ClassName.units]: units.used,
914
- [ClassName.rules]: Object.freeze({
915
- ...Object.fromEntries(rules),
916
- ...Object.fromEntries(
917
- scopes.rules.map((rule) => [
918
- `@scope:${rule.selector.slice(1)}:${Identity.name(rule.property)}:${Identity.name(JSON.stringify(rule.conditions))}`,
919
- rule.value,
920
- ]),
921
- ),
922
- }),
923
- classes: Object.freeze(classes),
924
- css: [contributionCss, scopedCss].filter(Boolean).join('\n'),
925
- vars: scopes.classes as Readonly<Record<themeName, string>>,
926
- }
927
- Object.defineProperty(result, ClassName.rules, { enumerable: false })
928
- Object.defineProperty(result, ClassName.units, { enumerable: false })
929
- return Object.freeze(result)
37
+ // A supplied unit scope receives the naming decisions the engine made against its table.
38
+ return Wire.decode(
39
+ Engine.call('css.compile', input),
40
+ options[ClassName.units],
41
+ ) as compile.ReturnType<name, themeName>
930
42
  }
931
43
 
932
44
  /** Input and output contracts for literal compilation. */
@@ -1036,11 +148,3 @@ export type Diagnostic = {
1036
148
  /** Authored style name, followed by a property when applicable. */
1037
149
  readonly path: readonly string[]
1038
150
  }
1039
-
1040
- // Encoding underscores and delimiters makes the value form injective.
1041
- function encode(value: string): string {
1042
- return value.replace(
1043
- /[^a-zA-Z0-9-]/g,
1044
- (character) => `_${character.charCodeAt(0).toString(16)}_`,
1045
- )
1046
- }