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,610 +0,0 @@
1
- /** Finds nonescaping local static callables whose applications can become props. @module */
2
- import type * as Ast from '@oxc-project/types'
3
- import * as Walker from 'oxc-walker'
4
- import * as Expression from './Expression.js'
5
- import * as Scope from './Scope.js'
6
- import type * as Source from '../Source.js'
7
-
8
- /** Conservatively proves direct applications without changing binding reads. */
9
- export function create(
10
- program: Ast.Program,
11
- calls: readonly Source.Call[],
12
- options: create.Options = {},
13
- ): Collector | undefined {
14
- const definitions = new Map(calls.map((call) => [call.start, call]))
15
- const memberBindings = new Map<number, string>()
16
- const referencedDefinitions = new Set<string>()
17
- const namespaceCounts = new Map<string, number>()
18
-
19
- for (const statement of program.body) {
20
- const node =
21
- statement.type === 'ExportNamedDeclaration'
22
- ? statement.declaration
23
- : statement
24
-
25
- if (node?.type === 'TSModuleDeclaration' && node.id.type === 'Identifier')
26
- namespaceCounts.set(
27
- node.id.name,
28
- (namespaceCounts.get(node.id.name) ?? 0) + 1,
29
- )
30
- }
31
-
32
- const candidates: {
33
- declaration: {
34
- id: Extract<Ast.Node, { type: 'Identifier' }>
35
- }
36
- direct: Source.Call | undefined
37
- members: Map<string, Source.Call>
38
- /** Namespace statement start and member identifier ends by extracted name. */
39
- namespace?: Namespace | undefined
40
- /** Offset after which top-level reads observe an initialized binding. */
41
- ready: number
42
- }[] = []
43
-
44
- for (const statement of program.body) {
45
- if (
46
- statement.type === 'TSModuleDeclaration' &&
47
- statement.id.type === 'Identifier' &&
48
- statement.body?.type === 'TSModuleBlock'
49
- ) {
50
- const members = new Map<string, Source.Call>()
51
- const ends = new Map<string, number>()
52
- let valid = true
53
-
54
- for (const member of statement.body.body) {
55
- const node =
56
- member.type === 'ExportNamedDeclaration'
57
- ? member.declaration
58
- : undefined
59
-
60
- if (node?.type !== 'VariableDeclaration' || node.kind !== 'const') {
61
- valid = false
62
- break
63
- }
64
-
65
- for (const declaration of node.declarations) {
66
- const call =
67
- declaration.init && definitions.get(declaration.init.start)
68
-
69
- if (
70
- declaration.id.type !== 'Identifier' ||
71
- declaration.init?.type !== 'CallExpression' ||
72
- declaration.init.end !== call?.end ||
73
- members.has(declaration.id.name)
74
- ) {
75
- valid = false
76
- break
77
- }
78
-
79
- members.set(declaration.id.name, call)
80
- ends.set(call.name, declaration.id.end)
81
- memberBindings.set(declaration.id.start, call.name)
82
- }
83
- }
84
-
85
- if (valid && members.size)
86
- candidates.push({
87
- declaration: { id: statement.id },
88
- direct: undefined,
89
- members,
90
- namespace: { ends, start: statement.start },
91
- ready: statement.end,
92
- })
93
-
94
- continue
95
- }
96
-
97
- // Exported values can escape and object members can subsequently be replaced.
98
- if (statement.type !== 'VariableDeclaration' || statement.kind !== 'const')
99
- continue
100
-
101
- for (const declaration of statement.declarations) {
102
- if (declaration.id.type !== 'Identifier' || !declaration.init) continue
103
-
104
- const members = new Map<string, Source.Call>()
105
- const candidate = definitions.get(declaration.init.start)
106
-
107
- const direct =
108
- declaration.init.type === 'CallExpression' &&
109
- declaration.init.end === candidate?.end
110
- ? candidate
111
- : undefined
112
-
113
- if (!direct) {
114
- if (declaration.init.type !== 'ObjectExpression') continue
115
-
116
- let valid = true
117
-
118
- for (const property of declaration.init.properties) {
119
- if (
120
- property.type !== 'Property' ||
121
- property.computed ||
122
- property.method ||
123
- property.kind !== 'init'
124
- ) {
125
- valid = false
126
- break
127
- }
128
-
129
- const key =
130
- property.key.type === 'Identifier' ? property.key.name : undefined
131
- const candidate = definitions.get(property.value.start)
132
-
133
- const call =
134
- property.value.type === 'CallExpression' &&
135
- property.value.end === candidate?.end
136
- ? candidate
137
- : undefined
138
-
139
- if (!key || key === '__proto__' || !call || members.has(key)) {
140
- valid = false
141
- break
142
- }
143
-
144
- members.set(key, call)
145
- }
146
-
147
- if (!valid || !members.size) continue
148
- }
149
-
150
- candidates.push({
151
- declaration: { ...declaration, id: declaration.id },
152
- direct,
153
- members,
154
- ready: declaration.end,
155
- })
156
- }
157
- }
158
-
159
- if (!candidates.length) return undefined
160
-
161
- const lexical = new Set<Ast.Node>()
162
- // Extraction resolves these reads and rewrites their definitions, so none run.
163
- const resolved = new Set<Ast.Node>()
164
- // Reads inside functions, classes, or namespaces may run before initialization.
165
- const deferred = new Set<Ast.Node>()
166
- const terminals = new Set<Ast.Node>()
167
- const scope = new Scope.Tracker({ preserveExitedScopes: true })
168
- Walker.walk(program, { scopeTracker: scope })
169
- scope.freeze()
170
- const ancestors: Ast.Node[] = []
171
- Walker.walk(program, {
172
- scopeTracker: scope,
173
- enter(node, parent) {
174
- ancestors.push(node)
175
- if (
176
- node.type !== 'Identifier' ||
177
- !parent ||
178
- !Walker.isReferenceIdentifier(node, parent)
179
- )
180
- return
181
- if (
182
- ancestors.some((node) =>
183
- [
184
- 'TSTypeQuery',
185
- 'TSTypeAnnotation',
186
- 'TSTypeAliasDeclaration',
187
- 'TSInterfaceDeclaration',
188
- 'TSTypeParameterInstantiation',
189
- 'TSTypeParameterDeclaration',
190
- ].includes(node.type),
191
- )
192
- )
193
- return
194
- const binding = scope.getDeclaration(node.name, { mode: 'value' })
195
- const id = binding?.node
196
- const member = id && memberBindings.get(id.start)
197
- if (member) referencedDefinitions.add(member)
198
- if (
199
- id &&
200
- candidates.some(
201
- (candidate) => candidate.declaration.id.start === id.start,
202
- )
203
- ) {
204
- lexical.add(node)
205
- if (terminal(ancestors)) terminals.add(node)
206
- if (extracted(ancestors, definitions)) resolved.add(node)
207
- if (
208
- ancestors.some((node) =>
209
- [
210
- 'ArrowFunctionExpression',
211
- 'ClassDeclaration',
212
- 'ClassExpression',
213
- 'FunctionDeclaration',
214
- 'FunctionExpression',
215
- 'TSModuleDeclaration',
216
- ].includes(node.type),
217
- )
218
- )
219
- deferred.add(node)
220
- }
221
- },
222
- leave() {
223
- ancestors.pop()
224
- },
225
- })
226
-
227
- const parents = new Map<Ast.Node, Ast.Node>()
228
- const references = new Map<
229
- string,
230
- Extract<Ast.Node, { type: 'Identifier' }>[]
231
- >(candidates.map(({ declaration }) => [declaration.id.name, []]))
232
- let evaluation = false
233
-
234
- // Returns undefined when any read escapes. Recipes, dynamic styles, and
235
- // applications with overrides keep their runtime calls.
236
- function collect(candidate: (typeof candidates)[number]):
237
- | {
238
- readonly applications: readonly Application[]
239
- readonly called: ReadonlySet<string>
240
- }
241
- | undefined {
242
- const { declaration, direct, members } = candidate
243
- const applications: Application[] = []
244
- const called = new Set<string>()
245
-
246
- for (const reference of references.get(declaration.id.name) ?? []) {
247
- if (reference === declaration.id || resolved.has(reference)) continue
248
-
249
- let callee: Ast.Node = reference
250
- let call = direct
251
-
252
- if (!direct) {
253
- const member = parents.get(reference)
254
-
255
- if (
256
- member?.type !== 'MemberExpression' ||
257
- member.object !== reference ||
258
- member.computed ||
259
- member.optional ||
260
- member.property.type !== 'Identifier'
261
- )
262
- return undefined
263
-
264
- call = members.get(member.property.name)
265
- callee = member
266
- }
267
-
268
- if (
269
- call?.composition ||
270
- call?.runtimeComposition ||
271
- (!options.dynamic && (call?.slots || call?.recipe))
272
- )
273
- continue
274
-
275
- const application = parents.get(callee)
276
-
277
- if (
278
- !call ||
279
- application?.type !== 'CallExpression' ||
280
- application.callee !== callee ||
281
- application.optional
282
- )
283
- return undefined
284
-
285
- // An override needs the runtime callable, but exposes no other definition.
286
- if (!options.dynamic && application.arguments.length) {
287
- called.add(call.name)
288
- continue
289
- }
290
-
291
- applications.push({
292
- calleeEnd: callee.end,
293
- end: application.end,
294
- initialized:
295
- !deferred.has(reference) &&
296
- reference.start >= candidate.ready &&
297
- (!candidate.namespace ||
298
- namespaceCounts.get(declaration.id.name) === 1),
299
- name: call.name,
300
- start: application.start,
301
- terminal: terminals.has(reference),
302
- })
303
- }
304
-
305
- return { applications, called }
306
- }
307
-
308
- return {
309
- dead() {
310
- if (evaluation) return new Set<string>()
311
-
312
- const result = new Set<string>()
313
- const counts = new Map<string, number>()
314
-
315
- for (const { declaration } of candidates)
316
- counts.set(
317
- declaration.id.name,
318
- (counts.get(declaration.id.name) ?? 0) + 1,
319
- )
320
-
321
- for (const { declaration, direct, members } of candidates) {
322
- if (
323
- counts.get(declaration.id.name)! > 1 ||
324
- (namespaceCounts.get(declaration.id.name) ?? 0) > 1
325
- )
326
- continue
327
-
328
- const reads = references.get(declaration.id.name) ?? []
329
-
330
- if (direct) {
331
- if (!reads.length) result.add(direct.name)
332
- continue
333
- }
334
-
335
- const used = new Set<string>()
336
- let escapes = false
337
-
338
- for (const reference of reads) {
339
- const member = parents.get(reference)
340
-
341
- if (
342
- member?.type !== 'MemberExpression' ||
343
- member.object !== reference ||
344
- member.computed ||
345
- member.optional ||
346
- member.property.type !== 'Identifier'
347
- ) {
348
- escapes = true
349
- break
350
- }
351
-
352
- used.add(member.property.name)
353
- }
354
-
355
- if (!escapes)
356
- for (const [name, call] of members)
357
- if (!used.has(name) && !referencedDefinitions.has(call.name))
358
- result.add(call.name)
359
- }
360
-
361
- return result
362
- },
363
- definitions() {
364
- const namespaces: Namespace[] = []
365
- const values = new Map<string, boolean>()
366
-
367
- if (evaluation) return { namespaces, values }
368
-
369
- const counts = new Map<string, number>()
370
-
371
- for (const { declaration } of candidates)
372
- counts.set(
373
- declaration.id.name,
374
- (counts.get(declaration.id.name) ?? 0) + 1,
375
- )
376
-
377
- for (const candidate of candidates) {
378
- const name = candidate.declaration.id.name
379
- if (counts.get(name)! > 1 || (namespaceCounts.get(name) ?? 0) > 1)
380
- continue
381
-
382
- const result = collect(candidate)
383
- if (!result) continue
384
-
385
- let erased = !!candidate.namespace
386
-
387
- for (const call of candidate.direct
388
- ? [candidate.direct]
389
- : candidate.members.values()) {
390
- if (
391
- call.composition ||
392
- call.runtimeComposition ||
393
- call.slots ||
394
- call.recipe ||
395
- result.called.has(call.name)
396
- ) {
397
- erased = false
398
- continue
399
- }
400
-
401
- const initialized = result.applications.every(
402
- (application) =>
403
- application.name !== call.name || application.initialized,
404
- )
405
-
406
- values.set(call.name, initialized)
407
- erased &&= initialized
408
- }
409
-
410
- if (erased) namespaces.push(candidate.namespace!)
411
- }
412
-
413
- return { namespaces, values }
414
- },
415
- enter(node, parent) {
416
- if (
417
- node.type === 'MemberExpression' &&
418
- node.object.type === 'Identifier' &&
419
- references.has(node.object.name) &&
420
- parent
421
- )
422
- parents.set(node, parent)
423
-
424
- if (node.type !== 'Identifier') return
425
-
426
- if (node.name === 'eval') evaluation = true
427
-
428
- if (!lexical.has(node)) return
429
-
430
- const nodes = references.get(node.name)
431
- if (!nodes) return
432
-
433
- nodes.push(node)
434
-
435
- if (parent) parents.set(node, parent)
436
- },
437
- find() {
438
- if (evaluation) return []
439
-
440
- return candidates.flatMap(
441
- (candidate) => collect(candidate)?.applications ?? [],
442
- )
443
- },
444
- }
445
- }
446
-
447
- /** Proven call site and its compiled definition. */
448
- type Application = {
449
- /** End of the original binding or property read. */
450
- readonly calleeEnd: number
451
- /** End of the application. */
452
- readonly end: number
453
- /** Whether the read runs at top level after its definition initializes. */
454
- readonly initialized: boolean
455
- /** Extracted class identity. */
456
- readonly name: string
457
- /** Start of the application. */
458
- readonly start: number
459
- /** Whether a DOM element receives the props alone, so its classes meet no other style's. */
460
- readonly terminal: boolean
461
- }
462
-
463
- /** A top-level namespace whose members are all static definitions. */
464
- type Namespace = {
465
- /** Member identifier ends keyed by extracted name. */
466
- readonly ends: ReadonlyMap<string, number>
467
- /** Start of the namespace statement. */
468
- readonly start: number
469
- }
470
-
471
- /** Binding references gathered during the transform's existing walk. */
472
- type Collector = {
473
- /** Definitions with no observable value reads, retaining escaped containers. */
474
- dead: () => ReadonlySet<string>
475
- /**
476
- * Static definitions whose every read is a found application, keyed by
477
- * extracted name with whether every read is initialized. Namespaces list
478
- * those whose definitions all qualify with initialized reads.
479
- */
480
- definitions: () => {
481
- readonly namespaces: readonly Namespace[]
482
- readonly values: ReadonlyMap<string, boolean>
483
- }
484
- /** Records relevant reads and their immediate parents. */
485
- enter: (node: Ast.Node, parent: Ast.Node | null | undefined) => void
486
- /** Resolves applications after traversal completes. */
487
- find: () => readonly Application[]
488
- }
489
-
490
- /** Local application collection modes. */
491
- export declare namespace create {
492
- /** Controls whether arguments are retained for fixed runtime compositions. */
493
- type Options = {
494
- /** Includes recipe/value applications while preserving their runtime calls. */
495
- readonly dynamic?: boolean | undefined
496
- }
497
- }
498
-
499
- // Matches a selector interpolation or composition entry inside a definition, which
500
- // extraction resolves statically. Computed keys elsewhere in a definition fail extraction.
501
- function extracted(
502
- path: readonly Ast.Node[],
503
- definitions: ReadonlyMap<number, Source.Call>,
504
- ): boolean {
505
- let index = path.length - 1
506
- const member = path[index - 1]
507
- if (
508
- member?.type === 'MemberExpression' &&
509
- member.object === path[index] &&
510
- !member.computed
511
- )
512
- index--
513
-
514
- // Type assertions around a node keep the same read.
515
- function parent() {
516
- const node = path[index]!
517
- while (index > 0 && Expression.unwrap(path[index - 1]!) === node) index--
518
- return path[--index]
519
- }
520
-
521
- function definition(node: Ast.Node | undefined) {
522
- return (
523
- node?.type === 'CallExpression' &&
524
- definitions.get(node.start)?.end === node.end
525
- )
526
- }
527
-
528
- const container = parent()
529
-
530
- if (container?.type === 'ArrayExpression') {
531
- const call = parent()
532
- return (
533
- call?.type === 'CallExpression' &&
534
- definition(call) &&
535
- !!call.arguments[0] &&
536
- Expression.unwrap(call.arguments[0]) === container
537
- )
538
- }
539
-
540
- if (container?.type !== 'TemplateLiteral') return false
541
-
542
- const property = parent()
543
- return (
544
- property?.type === 'Property' &&
545
- property.computed &&
546
- Expression.unwrap(property.key) === container &&
547
- path.slice(0, index).some(definition)
548
- )
549
- }
550
-
551
- // Matches a no-argument application spread onto, or read as the class of, a DOM element.
552
- function terminal(path: readonly Ast.Node[]): boolean {
553
- let index = path.length - 1
554
- let node = path[index]
555
- const member = path[index - 1]
556
- if (member?.type === 'MemberExpression' && member.object === node)
557
- node = path[--index]
558
-
559
- const call = path[--index]
560
- if (
561
- call?.type !== 'CallExpression' ||
562
- call.callee !== node ||
563
- call.arguments.length
564
- )
565
- return false
566
-
567
- const parent = path[--index]
568
- if (parent?.type === 'JSXSpreadAttribute')
569
- return parent.argument === call && alone(path[index - 1], parent)
570
-
571
- if (
572
- parent?.type !== 'MemberExpression' ||
573
- parent.object !== call ||
574
- parent.computed ||
575
- parent.property.type !== 'Identifier' ||
576
- !/^class(?:Name)?$/.test(parent.property.name)
577
- )
578
- return false
579
-
580
- const container = path[--index]
581
- const attribute = path[--index]
582
- return (
583
- container?.type === 'JSXExpressionContainer' &&
584
- container.expression === parent &&
585
- attribute?.type === 'JSXAttribute' &&
586
- attribute.value === container &&
587
- attribute.name.type === 'JSXIdentifier' &&
588
- /^class(?:Name)?$/.test(attribute.name.name) &&
589
- alone(path[index - 1], attribute)
590
- )
591
- }
592
-
593
- // Other spreads or class attributes could add another style's classes.
594
- function alone(element: Ast.Node | undefined, own: Ast.Node): boolean {
595
- return (
596
- element?.type === 'JSXOpeningElement' &&
597
- element.name.type === 'JSXIdentifier' &&
598
- /^[a-z]/.test(element.name.name) &&
599
- element.attributes.every(
600
- (attribute) =>
601
- attribute === own ||
602
- (attribute.type === 'JSXAttribute' &&
603
- !(
604
- attribute.name.type === 'JSXIdentifier'
605
- ? attribute.name.name
606
- : attribute.name.namespace.name
607
- ).startsWith('class')),
608
- )
609
- )
610
- }
@@ -1,93 +0,0 @@
1
- /** Checks custom color-profile descriptors before source or packed publication. @module */
2
- import * as Lightning from 'lightningcss'
3
-
4
- /** Validates complete profile blocks, including decoded component and intent tokens. */
5
- export function validate(source: string): void {
6
- Lightning.transform({
7
- filename: 'color-profiles.css',
8
- code: new TextEncoder().encode(source),
9
- visitor: {
10
- Rule(rule) {
11
- if (rule.type !== 'unknown' || rule.value.name !== 'color-profile')
12
- return
13
- const name = rule.value.prelude[0]
14
- if (
15
- rule.value.prelude.length !== 1 ||
16
- !rule.value.block ||
17
- !(
18
- name?.type === 'dashed-ident' ||
19
- (name?.type === 'token' &&
20
- name.value.type === 'ident' &&
21
- name.value.value.toLowerCase() === 'device-cmyk')
22
- )
23
- )
24
- throw new Error('Expected a color-profile name and descriptor block.')
25
-
26
- let declaration: Lightning.TokenOrValue[] = []
27
- let src = false
28
- const flush = () => {
29
- if (!declaration.length) return
30
- const [name, colon, ...values] = declaration
31
- if (
32
- name?.type !== 'token' ||
33
- name.value.type !== 'ident' ||
34
- colon?.type !== 'token' ||
35
- colon.value.type !== 'colon'
36
- )
37
- throw new Error('Invalid color-profile descriptor.')
38
- const key = name.value.value.toLowerCase()
39
- if (key === 'src') {
40
- if (values.length !== 1 || values[0]?.type !== 'url')
41
- throw new Error('Color-profile src requires one URL.')
42
- src = true
43
- } else if (key === 'rendering-intent') {
44
- const token = values[0]
45
- if (
46
- values.length !== 1 ||
47
- token?.type !== 'token' ||
48
- token.value.type !== 'ident' ||
49
- ![
50
- 'absolute-colorimetric',
51
- 'relative-colorimetric',
52
- 'perceptual',
53
- 'saturation',
54
- ].includes(token.value.value.toLowerCase())
55
- )
56
- throw new Error('Invalid color-profile rendering intent.')
57
- } else if (key === 'components') {
58
- if (
59
- values.length % 2 !== 1 ||
60
- values.some((token, index) => {
61
- if (index % 2)
62
- return token.type !== 'token' || token.value.type !== 'comma'
63
- const name =
64
- token.type === 'dashed-ident'
65
- ? token.value
66
- : token.type === 'token' && token.value.type === 'ident'
67
- ? token.value.value
68
- : undefined
69
- return name === undefined || name.toLowerCase() === 'none'
70
- })
71
- )
72
- throw new Error(
73
- 'Color-profile components require comma-separated identifiers other than none.',
74
- )
75
- } else throw new Error('Unknown color-profile descriptor.')
76
- declaration = []
77
- }
78
- for (const token of rule.value.block) {
79
- if (
80
- token.type === 'token' &&
81
- ['white-space', 'comment'].includes(token.value.type)
82
- )
83
- continue
84
- if (token.type === 'token' && token.value.type === 'semicolon')
85
- flush()
86
- else declaration.push(token)
87
- }
88
- flush()
89
- if (!src) throw new Error('Color-profile requires a src descriptor.')
90
- },
91
- },
92
- })
93
- }