zyzz 0.0.28 → 0.0.30

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
@@ -1,531 +0,0 @@
1
- /** Lowers static recipe structure into ordered ordinary style conditions. @module */
2
- import type * as Ast from '@oxc-project/types'
3
- import type * as Query from '../../internal/Query.js'
4
- import * as ConditionalRecipe from '../../runtime/ConditionalRecipe.js'
5
- import type * as Recipe from '../../runtime/Recipe.js'
6
- import type * as StaticRecipe from '../../internal/Recipe.js'
7
- import * as Expression from './Expression.js'
8
- import * as RecipeConditions from './RecipeConditions.js'
9
- import * as RecipePayloads from './RecipePayloads.js'
10
- import * as Themes from './Themes.js'
11
-
12
- type Property = Extract<
13
- Ast.ObjectExpression['properties'][number],
14
- { type: 'Property' }
15
- >
16
-
17
- function object(node: Ast.Node): asserts node is Ast.ObjectExpression {
18
- if (node.type !== 'ObjectExpression')
19
- throw new Themes.InvalidError('Recipes require static object bodies.', node)
20
- }
21
-
22
- function entries(node: Ast.Node): readonly (readonly [string, Property])[] {
23
- if (node.type !== 'ObjectExpression')
24
- throw new Themes.InvalidError('Recipes require static object bodies.', node)
25
-
26
- const seen = new Set<string>()
27
- return node.properties.map((property) => {
28
- if (
29
- property.type !== 'Property' ||
30
- property.computed ||
31
- property.method ||
32
- property.shorthand ||
33
- property.kind !== 'init'
34
- )
35
- throw new Themes.InvalidError(
36
- 'Recipe structure requires explicit static keys.',
37
- property,
38
- )
39
-
40
- const key =
41
- property.key.type === 'Identifier'
42
- ? property.key.name
43
- : property.key.type === 'Literal'
44
- ? String(property.key.value)
45
- : undefined
46
- if (key === undefined || seen.has(key))
47
- throw new Themes.InvalidError('Recipe keys must be unique.', property)
48
-
49
- seen.add(key)
50
- return [key, property] as const
51
- })
52
- }
53
-
54
- function choice(node: Ast.Node, choices: readonly string[]): string | null {
55
- if (
56
- node.type !== 'Literal' ||
57
- !(
58
- node.value === null ||
59
- typeof node.value === 'string' ||
60
- typeof node.value === 'boolean'
61
- )
62
- )
63
- throw new Themes.InvalidError(
64
- 'Selections require literal choice names, booleans, or null.',
65
- node,
66
- )
67
-
68
- if (node.value === null) return null
69
- const value = String(node.value)
70
- if (!choices.includes(value))
71
- throw new Themes.InvalidError('Unknown recipe choice.', node)
72
-
73
- return value
74
- }
75
-
76
- function predicate(attribute: string, value: string): string {
77
- const quoted =
78
- '"' +
79
- value.replace(
80
- // oxlint-disable-next-line no-control-regex -- CSS strings require hexadecimal escapes for control characters.
81
- /[\x00-\x1f\x7f"\\]/g,
82
- (character) => `\\${character.codePointAt(0)!.toString(16)} `,
83
- ) +
84
- '"'
85
- return `[${attribute}=${quoted}]`
86
- }
87
-
88
- /** Expands every finite alternative while retaining authored style-node locations. */
89
- export function expand(
90
- node: Ast.ObjectExpression,
91
- options: expand.Options,
92
- ): {
93
- bindings: RecipePayloads.Bindings
94
- types: { readonly [axis: string]: { readonly [choice: string]: string } }
95
- body: Ast.ObjectExpression
96
- recipe: Recipe.Definition
97
- dynamicRecipe?: StaticRecipe.Definition<Ast.ObjectExpression> | undefined
98
- staticRecipe?: StaticRecipe.Definition<Ast.ObjectExpression> | undefined
99
- } {
100
- const bindings = RecipePayloads.create(options)
101
- const payloads: Recipe.Payload[] = []
102
- const defaultsValidators = new Map<
103
- Recipe.Payload,
104
- NonNullable<ReturnType<typeof bindings.read>>
105
- >()
106
- const types: Record<string, Record<string, string>> = Object.create(null)
107
- const defaultPayloads: Record<
108
- string,
109
- Record<string, string | number>
110
- > = Object.create(null)
111
- const properties: Ast.ObjectExpression['properties'] = []
112
- const fields = new Map(entries(node))
113
- const axes: Record<string, readonly string[]> = Object.create(null)
114
- const defaults: Record<string, string | null> = Object.create(null)
115
-
116
- for (const [key, property] of fields)
117
- if (
118
- ![
119
- 'base',
120
- 'variants',
121
- 'defaultVariants',
122
- 'compoundVariants',
123
- 'conditions',
124
- ].includes(key)
125
- )
126
- throw new Themes.InvalidError(`Unknown recipe field: ${key}.`, property)
127
-
128
- const conditions = fields.get('conditions')
129
- const named = (conditions ? entries(conditions.value) : []).map(
130
- ([name, property]) =>
131
- RecipeConditions.read({
132
- name,
133
- node: property.value,
134
- queries: options.queries,
135
- }),
136
- )
137
- const regions = RecipeConditions.regions(named)
138
- const base = fields.get('base')
139
- if (base) {
140
- object(base.value)
141
- if (
142
- named.length ||
143
- base.value.properties.some(
144
- (property) =>
145
- property.type === 'Property' &&
146
- !property.computed &&
147
- (property.key.type === 'Identifier'
148
- ? property.key.name === 'targets'
149
- : property.key.type === 'Literal' &&
150
- property.key.value === 'targets'),
151
- )
152
- )
153
- properties.push(group(base.value, '&', base.value))
154
- else properties.push(...(base.value as Ast.ObjectExpression).properties)
155
- }
156
-
157
- function group(node: Ast.Node, key: string, value: Ast.Expression): Property {
158
- return {
159
- type: 'Property',
160
- kind: 'init',
161
- method: false,
162
- shorthand: false,
163
- start: node.start,
164
- end: node.end,
165
- computed: false,
166
- key: {
167
- type: 'Literal',
168
- value: key,
169
- raw: JSON.stringify(key),
170
- start: node.start,
171
- end: node.end,
172
- },
173
- value,
174
- }
175
- }
176
-
177
- type Rule = {
178
- bodies?: readonly Ast.ObjectExpression[] | undefined
179
- matches: readonly (readonly [string, readonly string[]])[]
180
- property: Property
181
- suffix: string
182
- }
183
- const rules: Rule[] = []
184
-
185
- const variants = fields.get('variants')
186
- for (const [axis, property] of variants ? entries(variants.value) : []) {
187
- if (
188
- !/^[a-z][a-z0-9-]*$/.test(axis) ||
189
- axis.startsWith('zyzz-condition-') ||
190
- [
191
- 'class',
192
- 'className',
193
- 'conditions',
194
- 'key',
195
- 'ref',
196
- 'style',
197
- 'vars',
198
- ].includes(axis)
199
- )
200
- throw new Themes.InvalidError(
201
- 'Recipe axes require lowercase data-attribute names and cannot use reserved props.',
202
- property,
203
- )
204
-
205
- const choices = entries(property.value)
206
- if (!choices.length)
207
- throw new Themes.InvalidError(
208
- 'Recipe axes require at least one choice.',
209
- property,
210
- )
211
-
212
- for (const [key, property] of choices)
213
- if (
214
- (property.key.type === 'Literal' &&
215
- typeof property.key.value === 'number') ||
216
- key.includes('\0') ||
217
- /[\ud800-\udfff]/u.test(key)
218
- )
219
- throw new Themes.InvalidError(
220
- 'Recipe choice names require CSS-safe strings.',
221
- property,
222
- )
223
-
224
- axes[axis] = choices.map(([key]) => key)
225
- for (const [key, style] of choices) {
226
- if (
227
- key === '__proto__' &&
228
- (style.value.type === 'ArrowFunctionExpression' ||
229
- style.value.type === 'FunctionExpression')
230
- )
231
- throw new Themes.InvalidError(
232
- 'Dynamic choice names cannot use __proto__.',
233
- style,
234
- )
235
- const models = Array.from({ length: named.length + 1 }, (_, context) =>
236
- bindings.read(
237
- style.value,
238
- `${options.identity}-${Object.keys(axes).length}-${choices.findIndex(([name]) => name === key)}-${context}`,
239
- ),
240
- )
241
- const first = models[0]
242
- if (first) {
243
- types[axis] ??= Object.create(null)
244
- types[axis]![key] = options.source.slice(
245
- first.type.start,
246
- first.type.end,
247
- )
248
- const payload: Recipe.Payload = {
249
- axis,
250
- choice: key,
251
- slots: models.map((model) =>
252
- Object.fromEntries(
253
- Object.entries(model!.slots).map(([field, slot]) => [
254
- field,
255
- slot.name,
256
- ]),
257
- ),
258
- ),
259
- }
260
- payloads.push(payload)
261
- defaultsValidators.set(payload, first)
262
- }
263
- rules.push({
264
- matches: [[axis, [key]]],
265
- property: style,
266
- suffix: '',
267
- ...(first ? { bodies: models.map((model) => model!.body) } : {}),
268
- })
269
- }
270
- }
271
-
272
- const defaultVariants = fields.get('defaultVariants')
273
- for (const [axis, property] of defaultVariants
274
- ? entries(defaultVariants.value)
275
- : []) {
276
- if (!Object.hasOwn(axes, axis))
277
- throw new Themes.InvalidError('Unknown default variant axis.', property)
278
-
279
- if (
280
- property.value.type === 'Identifier' &&
281
- property.value.name === 'undefined'
282
- )
283
- continue
284
-
285
- if (property.value.type === 'ObjectExpression') {
286
- const selections = entries(property.value)
287
- const selected = selections[0]
288
- const payload =
289
- selected &&
290
- payloads.find(
291
- (item) => item.axis === axis && item.choice === selected[0],
292
- )
293
- if (selections.length !== 1 || !selected || !payload)
294
- throw new Themes.InvalidError(
295
- 'Dynamic defaults require exactly one declared dynamic choice.',
296
- property,
297
- )
298
- const values: Record<string, string | number> = Object.create(null)
299
- for (const [field, input] of entries(selected[1].value)) {
300
- const node = input.value
301
- const value =
302
- node.type === 'TemplateLiteral'
303
- ? Expression.template(node)
304
- : node.type === 'Literal'
305
- ? node.value
306
- : node.type === 'UnaryExpression' &&
307
- node.argument.type === 'Literal' &&
308
- typeof node.argument.value === 'number' &&
309
- (node.operator === '-' || node.operator === '+')
310
- ? node.operator === '-'
311
- ? -node.argument.value
312
- : node.argument.value
313
- : undefined
314
- if (
315
- !Object.hasOwn(payload.slots[0]!, field) ||
316
- (typeof value !== 'string' && typeof value !== 'number')
317
- )
318
- throw new Themes.InvalidError(
319
- 'Dynamic defaults require complete scalar payloads.',
320
- input,
321
- )
322
- if (!defaultsValidators.get(payload)!.acceptsValue(field, value))
323
- throw new Themes.InvalidError(
324
- 'Dynamic default does not match its declared payload type.',
325
- input,
326
- )
327
- values[field] = value
328
- }
329
- if (Object.keys(values).length !== Object.keys(payload.slots[0]!).length)
330
- throw new Themes.InvalidError(
331
- 'Dynamic defaults require complete scalar payloads.',
332
- property,
333
- )
334
- defaults[axis] = selected[0]
335
- defaultPayloads[axis] = values
336
- } else {
337
- defaults[axis] = choice(property.value, axes[axis]!)
338
- if (
339
- payloads.some(
340
- (item) => item.axis === axis && item.choice === defaults[axis],
341
- )
342
- )
343
- throw new Themes.InvalidError(
344
- 'Dynamic choices require a scoped payload.',
345
- property,
346
- )
347
- }
348
- }
349
-
350
- const compounds = fields.get('compoundVariants')
351
- if (compounds) {
352
- if (compounds.value.type !== 'ArrayExpression')
353
- throw new Themes.InvalidError(
354
- 'Compounds require a static array.',
355
- compounds,
356
- )
357
-
358
- for (const [index, element] of compounds.value.elements.entries()) {
359
- if (!element)
360
- throw new Themes.InvalidError(
361
- 'Compounds require dense entries.',
362
- compounds,
363
- )
364
- const fields = new Map(entries(element))
365
- const when = fields.get('when')
366
- const style = fields.get('style')
367
- if (!when || !style || fields.size !== 2)
368
- throw new Themes.InvalidError(
369
- 'Compounds require only when and style.',
370
- element,
371
- )
372
-
373
- const matches: (readonly [string, readonly string[]])[] = []
374
- for (const [axis, property] of entries(when.value)) {
375
- if (!Object.hasOwn(axes, axis))
376
- throw new Themes.InvalidError(
377
- 'Unknown compound variant axis.',
378
- property,
379
- )
380
-
381
- const values =
382
- property.value.type === 'ArrayExpression'
383
- ? property.value.elements
384
- : [property.value]
385
- if (!values.length || values.some((value) => !value))
386
- throw new Themes.InvalidError(
387
- 'Compound matches require nonempty choices.',
388
- property,
389
- )
390
-
391
- matches.push([
392
- axis,
393
- values.map((value) => {
394
- const selected = choice(value!, axes[axis]!)
395
- if (selected === null)
396
- throw new Themes.InvalidError(
397
- 'Compounds match choice names, not null.',
398
- value!,
399
- )
400
- return selected
401
- }),
402
- ])
403
- }
404
-
405
- // Distinct zero-specificity suffixes preserve repeated compound groups.
406
- rules.push({
407
- matches,
408
- property: style,
409
- suffix: `:where(*, .__zyzz-compound-${index})`,
410
- })
411
- }
412
- }
413
-
414
- const tree: Ast.ObjectExpression = { ...node, properties: [] }
415
- for (const region of regions) {
416
- let target = tree
417
- for (const { node: source, rule } of region.rules) {
418
- const existing = target.properties.find(
419
- (property) =>
420
- property.type === 'Property' &&
421
- property.key.type === 'Literal' &&
422
- property.key.value === rule,
423
- ) as Property | undefined
424
- if (existing) target = existing.value as Ast.ObjectExpression
425
- else {
426
- const nested: Ast.ObjectExpression = { ...node, properties: [] }
427
- target.properties.push(group(source, rule, nested))
428
- target = nested
429
- }
430
- }
431
-
432
- for (const { bodies, matches, property, suffix } of rules) {
433
- if (bodies) {
434
- const [axis, choices] = matches[0]!
435
- const sources = [-1, ...region.active]
436
- for (const [index, condition] of sources.entries()) {
437
- const attribute =
438
- condition === -1
439
- ? `data-${axis}`
440
- : ConditionalRecipe.attribute({ axis, condition })
441
- const excluded = sources
442
- .slice(index + 1)
443
- .map(
444
- (condition) =>
445
- `:not([${ConditionalRecipe.attribute({ axis, condition })}])`,
446
- )
447
- .join('')
448
- const selector = `&:where(${predicate(attribute, condition === -1 ? choices[0]! : `s${choices[0]}`)}${excluded})`
449
- target.properties.push(
450
- group(property.key, selector, bodies[condition + 1]!),
451
- )
452
- }
453
- continue
454
- }
455
- object(property.value)
456
- const selector =
457
- '&' +
458
- matches
459
- .map(([axis, choices]) => {
460
- const sources = [-1, ...region.active]
461
- const alternatives = sources.flatMap((condition, index) => {
462
- const attribute =
463
- condition === -1
464
- ? `data-${axis}`
465
- : ConditionalRecipe.attribute({ axis, condition })
466
- const excluded = sources
467
- .slice(index + 1)
468
- .map(
469
- (condition) =>
470
- `:not([${ConditionalRecipe.attribute({ axis, condition })}])`,
471
- )
472
- .join('')
473
- return choices.map(
474
- (choice) =>
475
- predicate(
476
- attribute,
477
- condition === -1 ? choice : `s${choice}`,
478
- ) + excluded,
479
- )
480
- })
481
- return `:where(${alternatives.join(',')})`
482
- })
483
- .join('') +
484
- suffix
485
- target.properties.push(group(property.key, selector, property.value))
486
- }
487
- }
488
- properties.push(...tree.properties)
489
-
490
- return {
491
- bindings,
492
- types,
493
- body: { ...node, properties },
494
- ...(!named.length
495
- ? {
496
- [payloads.length ? 'dynamicRecipe' : 'staticRecipe']: {
497
- axes,
498
- defaults,
499
- rules: [
500
- ...(base
501
- ? [{ matches: [], value: base.value as Ast.ObjectExpression }]
502
- : []),
503
- ...rules.map(({ matches, property, bodies }) => ({
504
- matches,
505
- value: bodies?.[0] ?? (property.value as Ast.ObjectExpression),
506
- })),
507
- ],
508
- },
509
- }
510
- : {}),
511
- recipe: {
512
- axes,
513
- defaults,
514
- ...(payloads.length ? { payloads, defaultPayloads } : {}),
515
- ...(named.length ? { conditions: named.map(({ name }) => name) } : {}),
516
- },
517
- }
518
- }
519
-
520
- /** Source inputs for finite recipe lowering. */
521
- export declare namespace expand {
522
- /** Resolution hooks and source identity for isolated payload slots. */
523
- type Options = RecipePayloads.create.Options & {
524
- /** Stable module and call identity. */
525
- readonly identity: string
526
- /** Bound query aliases. */
527
- readonly queries?: Query.Metadata | undefined
528
- /** Original source retained for declaration signatures. */
529
- readonly source: string
530
- }
531
- }