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,678 +0,0 @@
1
- /** Resolves known applications into ordered compiler-owned composition groups. @module */
2
- import * as Identity from '../../internal/Identity.js'
3
- import type * as Ast from '@oxc-project/types'
4
- import * as Walker from 'oxc-walker'
5
- import * as ConditionalRecipe from '../../runtime/ConditionalRecipe.js'
6
- import type * as Composition from '../../runtime/Composition.js'
7
- import type * as Style from '../../Style.js'
8
- import type * as Source from '../Source.js'
9
- import * as Applications from './Applications.js'
10
- import * as CompositionBindings from './CompositionBindings.js'
11
- import * as Expression from './Expression.js'
12
- import * as Scope from './Scope.js'
13
- import * as Themes from './Themes.js'
14
-
15
- /** Collects ordered compositions without evaluating expressions or changing binding reads. */
16
- export function collect(options: collect.Options) {
17
- if (
18
- !options.program.body.some(
19
- (node) =>
20
- node.type === 'ImportDeclaration' &&
21
- node.source.value === 'zyzz' &&
22
- node.importKind !== 'type' &&
23
- node.specifiers.some(
24
- (specifier) =>
25
- specifier.type === 'ImportSpecifier' &&
26
- (specifier.imported.type === 'Identifier'
27
- ? specifier.imported.name
28
- : specifier.imported.value) === 'cx',
29
- ),
30
- )
31
- )
32
- return []
33
-
34
- const bodies = new Map<number, Ast.ObjectExpression>()
35
- const undefinedReads = new Set<number>()
36
- const applications = Applications.create(options.program, options.calls, {
37
- dynamic: true,
38
- })
39
- const scope = new Scope.Tracker()
40
- const bindings = CompositionBindings.create({
41
- declaration: (name) => scope.getDeclaration(name)?.node,
42
- })
43
- const nodes: Ast.CallExpression[] = []
44
- const aliases = new Map<Ast.Node, Themes.Link>()
45
- const externalCalls = new Map<string, Source.Call>()
46
- const externalStyles = new Map<string, Style.NamedStyle>()
47
- const externalApplications = new Map<
48
- number,
49
- { calleeEnd: number; end: number; name: string; start: number }
50
- >()
51
-
52
- function external(node: Ast.Node): Themes.Link | undefined {
53
- if (node.type === 'Identifier') {
54
- const binding = scope.getDeclaration(node.name)
55
- const alias = binding?.node && aliases.get(binding.node)
56
- if (alias) return alias
57
-
58
- if (
59
- binding?.type === 'Import' &&
60
- binding.importNode.importKind !== 'type'
61
- )
62
- return options.links?.[node.name]
63
- }
64
- if (
65
- node.type === 'MemberExpression' &&
66
- !node.computed &&
67
- !node.optional &&
68
- node.property.type === 'Identifier'
69
- )
70
- return external(node.object)?.members?.[node.property.name]
71
- return undefined
72
- }
73
-
74
- Walker.walk(options.program, {
75
- scopeTracker: scope,
76
- enter(node, parent) {
77
- applications?.enter(node, parent)
78
- bindings.enter(node, parent)
79
- if (
80
- node.type === 'VariableDeclarator' &&
81
- node.init &&
82
- parent?.type === 'VariableDeclaration' &&
83
- parent.kind === 'const'
84
- ) {
85
- const link = external(node.init)
86
- if (link && node.id.type === 'Identifier') aliases.set(node.id, link)
87
- if (link && node.id.type === 'ObjectPattern')
88
- for (const property of node.id.properties)
89
- if (
90
- property.type === 'Property' &&
91
- !property.computed &&
92
- property.key.type === 'Identifier' &&
93
- property.value.type === 'Identifier'
94
- ) {
95
- const member = link.members?.[property.key.name]
96
- if (member) aliases.set(property.value, member)
97
- }
98
- }
99
-
100
- if (node.type === 'CallExpression') {
101
- const link = external(node.callee)
102
- if (link?.style && !node.optional) {
103
- const name = link.binding
104
- externalCalls.set(name, {
105
- end: -1,
106
- identity: name,
107
- portable: link.style.className,
108
- name,
109
- ...(link.style.output ? { output: link.style.output } : {}),
110
- ownership: {
111
- attributes: link.style.attributes,
112
- identity: name,
113
- slots: link.style.slots,
114
- },
115
- start: node.start,
116
- })
117
- externalStyles.set(name, { ...link.style.style, name })
118
- externalApplications.set(node.start, {
119
- calleeEnd: node.callee.end,
120
- end: node.end,
121
- name,
122
- start: node.start,
123
- })
124
- }
125
- const call = options.calls.find((call) => call.start === node.start)
126
- const argument = node.arguments[0]
127
- const body =
128
- call?.body ??
129
- (argument?.type === 'ArrowFunctionExpression'
130
- ? Expression.unwrap(argument.body)
131
- : argument)
132
- if (call && body?.type === 'ObjectExpression')
133
- bodies.set(call.start, body)
134
- }
135
- if (
136
- node.type === 'Identifier' &&
137
- node.name === 'undefined' &&
138
- !scope.getDeclaration(node.name)
139
- )
140
- undefinedReads.add(node.start)
141
- if (node.type !== 'CallExpression' || node.callee.type !== 'Identifier')
142
- return
143
- const binding = scope.getDeclaration(node.callee.name)
144
- if (
145
- binding?.type !== 'Import' ||
146
- binding.importNode.source.value !== 'zyzz' ||
147
- binding.node.type !== 'ImportSpecifier' ||
148
- binding.importNode.importKind === 'type' ||
149
- binding.node.importKind === 'type'
150
- )
151
- return
152
- const imported = binding.node.imported
153
- if (
154
- (imported.type === 'Identifier' ? imported.name : imported.value) ===
155
- 'cx'
156
- )
157
- nodes.push(node)
158
- },
159
- })
160
- const applied = new Map(
161
- [...(applications?.find() ?? []), ...externalApplications.values()].map(
162
- (application) => [application.start, application],
163
- ),
164
- )
165
- const calls = new Map(options.calls.map((call) => [call.start, call]))
166
- const byName = new Map(
167
- [...options.calls, ...externalCalls.values()].map((call) => [
168
- call.name,
169
- call,
170
- ]),
171
- )
172
- const styles = new Map(
173
- [...options.styles, ...externalStyles.values()].map((style) => [
174
- style.name,
175
- style,
176
- ]),
177
- )
178
- type Entry = {
179
- call: Source.Call
180
- style: Style.NamedStyle
181
- cases?:
182
- | readonly { call: Source.Call; style: Style.NamedStyle }[]
183
- | undefined
184
- }
185
- const result: Entry[] = []
186
-
187
- for (const node of nodes.sort((a, b) =>
188
- a.start < b.start && a.end >= b.end
189
- ? 1
190
- : b.start < a.start && b.end >= a.end
191
- ? -1
192
- : a.start - b.start,
193
- )) {
194
- const selected: Source.Call[] = []
195
- const inputs: NonNullable<Source.Call['runtimeComposition']>[number][] = []
196
- const outputs = new Set<'html' | undefined>()
197
- let runtime = false
198
- let conditions = 0
199
- const attributes = new Map<string, string>()
200
-
201
- function owners(call: Source.Call): readonly Composition.Owner[] {
202
- if (call.ownership) return [call.ownership]
203
- if (call.runtimeComposition)
204
- return call.runtimeComposition.flatMap((input) => input.owners)
205
- return [
206
- {
207
- identity: call.name,
208
- attributes: Object.keys(call.recipe?.axes ?? {}).flatMap((axis) => [
209
- `data-${axis}`,
210
- ...(call.recipe?.conditions ?? []).map((_, condition) =>
211
- ConditionalRecipe.attribute({ axis, condition }),
212
- ),
213
- ]),
214
- slots: [
215
- ...Object.values(call.slots ?? {}).map((slot) => slot.name),
216
- ...(call.recipe?.payloads ?? []).flatMap((payload) =>
217
- payload.slots.flatMap((slots) => Object.values(slots)),
218
- ),
219
- ],
220
- },
221
- ]
222
- }
223
- function input(
224
- call: Source.Call,
225
- value: Ast.Node,
226
- condition?: number,
227
- applicationStart = value.start,
228
- ) {
229
- const owned = owners(call)
230
- for (const owner of owned)
231
- for (const attribute of owner.attributes) {
232
- const previous = attributes.get(attribute)
233
- if (previous && previous !== owner.identity)
234
- throw new Themes.InvalidError(
235
- `Recipe attribute ${attribute} has conflicting owners.`,
236
- value,
237
- )
238
- attributes.set(attribute, owner.identity)
239
- }
240
- inputs.push({
241
- applicationStart,
242
- end: value.end,
243
- name: call.name,
244
- owners: owned,
245
- start: value.start,
246
- ...(condition !== undefined ? { condition } : {}),
247
- })
248
- }
249
- const guards: string[] = []
250
- if (node.optional)
251
- throw new Themes.InvalidError(
252
- 'Composition does not support optional calls.',
253
- node,
254
- )
255
- for (const argument of node.arguments) {
256
- const expression = Expression.unwrap(argument)
257
- const resolved = bindings.resolve(expression, nodes)
258
- const conditional =
259
- resolved.type === 'LogicalExpression' && resolved.operator === '&&'
260
- const value = conditional
261
- ? bindings.resolve(resolved.right, nodes)
262
- : resolved
263
- runtime ||= conditional || resolved !== expression
264
- if (
265
- conditional &&
266
- (undefinedReads.has(value.start) ||
267
- (value.type === 'Literal' &&
268
- (value.value === false || value.value === null)) ||
269
- (value.type === 'UnaryExpression' &&
270
- value.operator === 'void' &&
271
- value.argument.type === 'Literal'))
272
- )
273
- throw new Themes.InvalidError(
274
- 'Conditional omissions must be evaluated outside composition.',
275
- expression,
276
- )
277
- const omitted =
278
- undefinedReads.has(value.start) ||
279
- (value.type === 'Literal' &&
280
- (value.value === false || value.value === null)) ||
281
- (value.type === 'UnaryExpression' &&
282
- value.operator === 'void' &&
283
- value.argument.type === 'Literal')
284
- if (omitted && resolved !== expression)
285
- inputs.push({
286
- end: expression.end,
287
- name: '',
288
- owners: [],
289
- start: expression.start,
290
- })
291
- if (undefinedReads.has(value.start)) continue
292
- if (
293
- value.type === 'Literal' &&
294
- (value.value === false || value.value === null)
295
- )
296
- continue
297
- if (
298
- value.type === 'UnaryExpression' &&
299
- value.operator === 'void' &&
300
- value.argument.type === 'Literal'
301
- )
302
- continue
303
- if (value.type !== 'CallExpression' || value.optional)
304
- throw new Themes.InvalidError(
305
- 'Composition requires statically known local style applications.',
306
- value,
307
- )
308
- const scope = options.scopes?.get(value.start)
309
- if (scope?.end === value.end) {
310
- outputs.add(scope.output)
311
- inputs.push({
312
- start: expression.start,
313
- end: expression.end,
314
- name: '',
315
- owners: [],
316
- })
317
- runtime = true
318
- continue
319
- }
320
- const condition = conditional ? conditions++ : undefined
321
- const nested = calls.get(value.start)
322
- if (nested?.compositionCases && resolved !== expression)
323
- throw new Themes.InvalidError(
324
- 'Conditional composition results must remain direct arguments.',
325
- expression,
326
- )
327
- if (nested?.compositionCases && nested.end === value.end) {
328
- if (conditional)
329
- throw new Themes.InvalidError(
330
- 'Conditional nested compositions require flattening into one cx call.',
331
- expression,
332
- )
333
- for (const child of nested.runtimeComposition!) {
334
- if (child.name === '') {
335
- inputs.push(child)
336
- continue
337
- }
338
- const call =
339
- byName.get(child.name) ??
340
- [...calls.values()].find((call) => call.name === child.name)
341
- if (!call)
342
- throw new Themes.InvalidError(
343
- 'Nested composition has an unresolved definition.',
344
- expression,
345
- )
346
- selected.push(call)
347
- input(
348
- call,
349
- { ...node, start: child.start, end: child.end },
350
- child.condition === undefined ? undefined : conditions++,
351
- child.applicationStart,
352
- )
353
- }
354
- runtime = true
355
- continue
356
- }
357
- if (
358
- nested?.end === value.end &&
359
- (nested.composition || nested.runtimeComposition)
360
- ) {
361
- selected.push(nested)
362
- guards.push(...(nested.composition ?? []))
363
- input(nested, expression, condition, value.start)
364
- runtime ||= !!nested.runtimeComposition
365
- continue
366
- }
367
- const found = applied.get(value.start)
368
- const application = found?.end === value.end ? found : undefined
369
- const call = application
370
- ? byName.get(application.name)
371
- : value.callee.type === 'CallExpression'
372
- ? (() => {
373
- const call = calls.get(value.callee.start)
374
- return call?.end === value.callee.end ? call : undefined
375
- })()
376
- : undefined
377
- if (!call || call.composition || call.runtimeComposition)
378
- throw new Themes.InvalidError(
379
- 'Composition requires statically known local style applications.',
380
- value,
381
- )
382
- selected.push(call.ownership ? { ...call, start: value.start } : call)
383
- input(call, expression, condition, value.start)
384
- runtime ||= !!(
385
- call.ownership ||
386
- call.recipe ||
387
- call.slots ||
388
- value.arguments.length
389
- )
390
- if (application)
391
- guards.push(
392
- options.source.slice(application.start, application.calleeEnd),
393
- )
394
- }
395
- for (const call of selected) outputs.add(call.output)
396
- if (outputs.size > 1)
397
- throw new Themes.InvalidError(
398
- 'Composition cannot mix HTML and React props.',
399
- node,
400
- )
401
-
402
- if (conditions > 8)
403
- throw new Themes.InvalidError(
404
- 'Composition supports at most eight conditional arguments.',
405
- node,
406
- )
407
- const name = `composition-${options.identity}-${node.start}`
408
- // A composition of independent styles keeps their sharing contract.
409
- const independent = (calls: readonly Source.Call[]) =>
410
- calls.every(
411
- (call) => styles.get(call.name)!.composition === 'independent',
412
- )
413
- ? ({ composition: 'independent' } as const)
414
- : {}
415
- const style: Style.NamedStyle = {
416
- ...independent(selected),
417
- cssOutput: 'atomic',
418
- name,
419
- declarations: [],
420
- rules: selected.flatMap((call) => {
421
- const style = styles.get(call.name)!
422
- return (
423
- style.rules?.map((rule) => ({
424
- ...rule,
425
- style: {
426
- ...rule.style,
427
- cssOutput: rule.style.cssOutput ?? style.cssOutput,
428
- },
429
- })) ?? [{ style }]
430
- )
431
- }),
432
- }
433
- const identities = selected.flatMap((call) =>
434
- call.identity ? [call.identity] : [],
435
- )
436
- function properties(
437
- call: Source.Call,
438
- body = call.body ?? bodies.get(call.start),
439
- ): Ast.ObjectExpression['properties'] {
440
- // Imported declarations map to the application; publisher maps retain authored locations.
441
- if (call.ownership) {
442
- function declarations(
443
- style: Style.NamedStyle,
444
- ): readonly Style.Declaration[] {
445
- return style.rules
446
- ? style.rules.flatMap((rule) => declarations(rule.style))
447
- : style.declarations
448
- }
449
-
450
- return declarations(styles.get(call.name)!).map((declaration) => ({
451
- type: 'Property',
452
- computed: false,
453
- kind: 'init',
454
- method: false,
455
- shorthand: false,
456
- start: call.start,
457
- end: call.start,
458
- key: {
459
- type: 'Literal',
460
- value: declaration.property,
461
- raw: JSON.stringify(declaration.property),
462
- start: call.start,
463
- end: call.start,
464
- },
465
- value: {
466
- type: 'Literal',
467
- value: '',
468
- raw: '""',
469
- start: call.start,
470
- end: call.start,
471
- },
472
- }))
473
- }
474
-
475
- return (
476
- body?.properties.flatMap<Ast.ObjectExpression['properties'][number]>(
477
- (property) => {
478
- if (property.type !== 'Property') return [property]
479
- const value = Expression.unwrap(property.value)
480
- if (value.type === 'ObjectExpression')
481
- return [
482
- {
483
- ...property,
484
- value: { ...value, properties: properties(call, value) },
485
- },
486
- ]
487
- const key =
488
- property.key.type === 'Identifier'
489
- ? property.key.name
490
- : property.key.type === 'Literal'
491
- ? String(property.key.value)
492
- : ''
493
- return (call.shorthands?.[key] ?? [key]).map((key) => ({
494
- ...property,
495
- key: {
496
- type: 'Literal' as const,
497
- raw: JSON.stringify(key),
498
- value: key,
499
- start: property.key.start,
500
- end: property.key.end,
501
- },
502
- }))
503
- },
504
- ) ?? []
505
- )
506
- }
507
- const portable = (calls: readonly Source.Call[]) =>
508
- calls.every((call) => call.portable)
509
- ? Identity.composition(
510
- calls.flatMap((call) => call.portableInputs ?? [call.portable!]),
511
- )
512
- : undefined
513
- const call: Source.Call = {
514
- cssName: selected
515
- .map((call) =>
516
- [call.cssNamespace, call.cssName ?? call.identity ?? 'style']
517
- .filter(Boolean)
518
- .join('-'),
519
- )
520
- .join('-'),
521
- ...(portable(selected)
522
- ? {
523
- portable: portable(selected),
524
- portableInputs: selected.flatMap(
525
- (call) => call.portableInputs ?? [call.portable!],
526
- ),
527
- }
528
- : {}),
529
- typography: new Map(
530
- selected.flatMap((call) => [...(call.typography ?? [])]),
531
- ),
532
- typographyQueries: new Map(
533
- selected.flatMap((call) => [...(call.typographyQueries ?? [])]),
534
- ),
535
- name,
536
- start: node.start,
537
- end: node.end,
538
- ...(runtime ? { runtimeComposition: inputs } : { composition: guards }),
539
- body: {
540
- type: 'ObjectExpression',
541
- start: node.start,
542
- end: node.end,
543
- properties: selected.flatMap((call) => properties(call)),
544
- },
545
- ...(outputs.has('html') ? { output: 'html' as const } : {}),
546
- ...(identities.length ? { identity: identities.join(' ') } : {}),
547
- }
548
- calls.set(node.start, call)
549
- styles.set(name, style)
550
- const cases: NonNullable<Entry['cases']>[number][] = []
551
- const names: string[] = []
552
- // Omitted bindings retain evaluation but own no selected style.
553
- const selectedInputs = inputs.filter((input) => input.name !== '')
554
- for (let mask = 0; mask < 2 ** conditions - 1; mask++) {
555
- const included = selected.filter(
556
- (_, index) =>
557
- selectedInputs[index]!.condition === undefined ||
558
- mask & (1 << selectedInputs[index]!.condition!),
559
- )
560
- const name = `${call.name}-${mask}`
561
- names.push(name)
562
- cases.push({
563
- call: {
564
- ...(portable(included)
565
- ? {
566
- portable: portable(included),
567
- portableInputs: included.flatMap(
568
- (call) => call.portableInputs ?? [call.portable!],
569
- ),
570
- }
571
- : {}),
572
- name,
573
- start: call.start,
574
- end: call.end,
575
- compositionCase: true,
576
- typography: new Map(
577
- included.flatMap((call) => [...(call.typography ?? [])]),
578
- ),
579
- typographyQueries: new Map(
580
- included.flatMap((call) => [...(call.typographyQueries ?? [])]),
581
- ),
582
- body: {
583
- ...call.body!,
584
- properties: included.flatMap((call) => properties(call)),
585
- },
586
- identity: included
587
- .flatMap((call) => (call.identity ? [call.identity] : []))
588
- .join(' '),
589
- },
590
- style: {
591
- ...independent(included),
592
- cssOutput: 'atomic',
593
- name,
594
- declarations: [],
595
- rules: included.flatMap((call) => {
596
- const style = styles.get(call.name)!
597
- return (
598
- style.rules?.map((rule) => ({
599
- ...rule,
600
- style: {
601
- ...rule.style,
602
- cssOutput: rule.style.cssOutput ?? style.cssOutput,
603
- },
604
- })) ?? [{ style }]
605
- )
606
- }),
607
- },
608
- })
609
- }
610
- names.push(call.name)
611
- const composed = conditions ? { ...call, compositionCases: names } : call
612
- calls.set(node.start, composed)
613
- result.push({
614
- call: composed,
615
- style: immutable(style),
616
- ...(cases.length
617
- ? {
618
- cases: cases.map((entry) => ({
619
- ...entry,
620
- style: immutable(entry.style),
621
- })),
622
- }
623
- : {}),
624
- })
625
- }
626
- return result.filter(
627
- ({ call }) =>
628
- !result.some(
629
- ({ call: other }) =>
630
- !!other.composition &&
631
- other.start < call.start &&
632
- other.end >= call.end,
633
- ),
634
- )
635
- }
636
-
637
- /** Static composition extraction inputs. */
638
- export declare namespace collect {
639
- /** Parsed source and previously validated style applications. */
640
- type Options = {
641
- /** Extracted authoring calls. */
642
- readonly calls: readonly Source.Call[]
643
- /** Stable module identity. */
644
- readonly identity: string
645
- /** Immutable imported style definitions supplied by the source or package graph. */
646
- readonly links?: Readonly<Record<string, Themes.Link>> | undefined
647
- /** Parsed module with lexical binding scopes. */
648
- readonly program: Ast.Program
649
- /** Validated variable scope applications preserved as runtime props. */
650
- readonly scopes?:
651
- | ReadonlyMap<
652
- number,
653
- { readonly end: number; readonly output: 'html' | undefined }
654
- >
655
- | undefined
656
- /** Source used to preserve initialization-sensitive binding reads. */
657
- readonly source: string
658
- /** Validated ordered style bodies. */
659
- readonly styles: readonly Style.NamedStyle[]
660
- }
661
- }
662
-
663
- function immutable(style: Style.NamedStyle): Style.NamedStyle {
664
- if (Object.isFrozen(style)) return style
665
- return Object.freeze({
666
- ...style,
667
- declarations: Object.freeze([...style.declarations]),
668
- ...(style.rules
669
- ? {
670
- rules: Object.freeze(
671
- style.rules.map((rule) =>
672
- Object.freeze({ ...rule, style: immutable(rule.style) }),
673
- ),
674
- ),
675
- }
676
- : {}),
677
- })
678
- }