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,784 +0,0 @@
1
- /** Resolves immutable module data and finite local type bindings without executing source. @module */
2
- import type * as Ast from '@oxc-project/types'
3
- import * as Expression from './Expression.js'
4
- import type * as Scope from './Scope.js'
5
- import * as Themes from './Themes.js'
6
- import * as Walker from 'oxc-walker'
7
-
8
- /** Collects lexical immutable values and local scalar/object type declarations. */
9
- export function collect(
10
- program: Ast.Program,
11
- scope: Scope.Tracker,
12
- imports: Readonly<Record<string, Ast.Node>> = {},
13
- ) {
14
- const collector = create(program, scope, imports)
15
- Walker.walk(program, { ...collector.visitor, scopeTracker: scope })
16
- return collector
17
- }
18
-
19
- /** Collects immutable references during a host-owned traversal of frozen scopes. */
20
- export function create(
21
- program: Ast.Program,
22
- scope: Scope.Tracker,
23
- imports: Readonly<Record<string, Ast.Node>> = {},
24
- ) {
25
- const values = new Map<number, Ast.Node>()
26
- const references = new Map<number, number>()
27
- const usages = new Map<number, Ast.Node[][]>()
28
- const types = new Map<number, Ast.Node>()
29
- const typeReferences = new Map<number, number>()
30
- const used = new Set<number>()
31
- const absent = new Set<number>()
32
-
33
- function collectValues(statements: readonly Ast.Statement[]) {
34
- for (const statement of statements) {
35
- const node =
36
- statement.type === 'ExportNamedDeclaration'
37
- ? statement.declaration
38
- : statement
39
-
40
- if (
41
- node?.type === 'TSModuleDeclaration' &&
42
- node.body?.type === 'TSModuleBlock'
43
- )
44
- collectValues(node.body.body)
45
-
46
- if (node?.type === 'VariableDeclaration' && node.kind === 'const')
47
- for (const declaration of node.declarations)
48
- if (declaration.id.type === 'Identifier' && declaration.init) {
49
- values.set(declaration.start, declaration.init)
50
- }
51
- }
52
- }
53
-
54
- collectValues(program.body)
55
- const imported = new Set<number>()
56
- for (const statement of program.body)
57
- if (
58
- statement.type === 'ImportDeclaration' &&
59
- statement.importKind !== 'type'
60
- )
61
- for (const specifier of statement.specifiers) {
62
- const value = imports[specifier.local.name]
63
- if (!value) continue
64
- values.set(specifier.start, value)
65
- imported.add(specifier.start)
66
- }
67
-
68
- const ancestors: Ast.Node[] = []
69
-
70
- const visitor = {
71
- enter(node: Ast.Node, parent: Ast.Node | null) {
72
- ancestors.push(node)
73
-
74
- if (node.type === 'TSTypeAliasDeclaration' && !node.typeParameters)
75
- types.set(node.id.start, node.typeAnnotation)
76
-
77
- if (
78
- node.type === 'TSInterfaceDeclaration' &&
79
- !node.extends?.length &&
80
- !node.typeParameters
81
- ) {
82
- const key =
83
- scope.getDeclaration(node.id.name, { mode: 'type' })?.node.start ??
84
- node.id.start
85
- const previous = types.get(key)
86
-
87
- types.set(key, {
88
- ...node.body,
89
- type: 'TSTypeLiteral',
90
- members: [
91
- ...(previous?.type === 'TSTypeLiteral' ? previous.members : []),
92
- ...node.body.body,
93
- ],
94
- } as Ast.TSTypeLiteral)
95
- }
96
-
97
- if (
98
- node.type === 'TSTypeReference' &&
99
- node.typeName.type === 'Identifier' &&
100
- !node.typeArguments
101
- ) {
102
- const declaration = scope.getDeclaration(node.typeName.name, {
103
- mode: 'type',
104
- })
105
-
106
- if (declaration) typeReferences.set(node.start, declaration.node.start)
107
- }
108
-
109
- if (
110
- node.type !== 'Identifier' ||
111
- !parent ||
112
- !Walker.isReferenceIdentifier(node, parent)
113
- )
114
- return undefined
115
-
116
- // Distinguish unbound references from nodes that are not references.
117
- const binding = scope.getDeclaration(node.name) ?? null
118
- if (!binding && node.name === 'undefined') absent.add(node.start)
119
- if (!binding || !values.has(binding.node.start)) return binding
120
- if (ancestors.some((node) => node.type === 'TSTypeQuery')) return binding
121
-
122
- references.set(node.start, binding.node.start)
123
- const value = Expression.unwrap(values.get(binding.node.start)!)
124
- // Escape paths are only consulted for object and array resolutions.
125
- if (
126
- value.type === 'ArrowFunctionExpression' ||
127
- value.type === 'CallExpression' ||
128
- value.type === 'FunctionExpression' ||
129
- value.type === 'Literal' ||
130
- value.type === 'NewExpression'
131
- )
132
- return binding
133
- const previous = usages.get(binding.node.start)
134
- if (previous) previous.push([...ancestors])
135
- else usages.set(binding.node.start, [[...ancestors]])
136
- return binding
137
- },
138
- leave() {
139
- ancestors.pop()
140
- },
141
- }
142
-
143
- let aliases: Map<number, number[]> | undefined
144
-
145
- function root(node: Ast.Node): number | undefined {
146
- node = Expression.unwrap(node)
147
-
148
- while (node.type === 'MemberExpression') node = node.object
149
-
150
- return node.type === 'Identifier' ? references.get(node.start) : undefined
151
- }
152
-
153
- function initial(
154
- input: Ast.Node,
155
- seen = new Set<number>(),
156
- ): Ast.Node | undefined {
157
- const node = Expression.unwrap(input)
158
-
159
- if (node.type === 'Identifier') {
160
- const binding = references.get(node.start)
161
- if (binding === undefined || seen.has(binding)) return undefined
162
-
163
- const value = values.get(binding)
164
- if (!value) return undefined
165
-
166
- seen.add(binding)
167
-
168
- return initial(value, seen)
169
- }
170
-
171
- if (node.type === 'MemberExpression' && !node.optional) {
172
- const object = initial(node.object, seen)
173
-
174
- const key =
175
- !node.computed && node.property.type === 'Identifier'
176
- ? node.property.name
177
- : node.property.type === 'Literal'
178
- ? String(node.property.value)
179
- : undefined
180
-
181
- if (object?.type === 'ObjectExpression' && key !== undefined) {
182
- for (const property of [...object.properties].reverse()) {
183
- if (property.type === 'SpreadElement') return undefined
184
-
185
- const name =
186
- property.key.type === 'Identifier' && !property.computed
187
- ? property.key.name
188
- : property.key.type === 'Literal'
189
- ? String(property.key.value)
190
- : undefined
191
- if (name === key)
192
- return property.method || property.kind !== 'init'
193
- ? undefined
194
- : initial(property.value, seen)
195
- }
196
- }
197
-
198
- if (
199
- object?.type === 'ArrayExpression' &&
200
- key !== undefined &&
201
- /^(?:0|[1-9]\d*)$/.test(key)
202
- ) {
203
- if (
204
- object.elements
205
- .slice(0, Number(key) + 1)
206
- .some((element) => element?.type === 'SpreadElement')
207
- )
208
- return undefined
209
-
210
- const element = object.elements[Number(key)]
211
-
212
- return element && element.type !== 'SpreadElement'
213
- ? initial(element, seen)
214
- : undefined
215
- }
216
-
217
- return undefined
218
- }
219
-
220
- return node
221
- }
222
-
223
- function scalar(node: Ast.Node): boolean {
224
- const value = initial(node)
225
-
226
- return (
227
- value?.type === 'Literal' ||
228
- value?.type === 'TemplateLiteral' ||
229
- (value?.type === 'UnaryExpression' && value.operator !== 'delete')
230
- )
231
- }
232
-
233
- function owners(input: Ast.Node): number[] {
234
- const node = Expression.unwrap(input)
235
- if (scalar(node)) return []
236
-
237
- const owner = root(node)
238
- if (owner !== undefined) return [owner]
239
-
240
- if (node.type === 'ObjectExpression')
241
- return node.properties.flatMap((property) =>
242
- property.type === 'SpreadElement'
243
- ? owners(property.argument)
244
- : property.type === 'Property'
245
- ? owners(property.value)
246
- : [],
247
- )
248
-
249
- if (node.type === 'ArrayExpression')
250
- return node.elements.flatMap((element) =>
251
- element
252
- ? owners(
253
- element.type === 'SpreadElement' ? element.argument : element,
254
- )
255
- : [],
256
- )
257
-
258
- return []
259
- }
260
-
261
- function paths(
262
- binding: number,
263
- seen = new Set<number>(),
264
- ): readonly (readonly Ast.Node[])[] {
265
- if (!aliases) {
266
- aliases = new Map()
267
- for (const [id, input] of values)
268
- for (const owner of owners(input))
269
- aliases.set(owner, [...(aliases.get(owner) ?? []), id])
270
- }
271
- if (seen.has(binding)) return []
272
-
273
- seen.add(binding)
274
-
275
- return [
276
- ...(usages.get(binding) ?? []),
277
- ...(aliases.get(binding) ?? []).flatMap((alias) => paths(alias, seen)),
278
- ]
279
- }
280
-
281
- function resolve(
282
- node: Ast.Node,
283
- allowed: ReadonlySet<number>,
284
- active = new Set<number>(),
285
- ): Ast.Node {
286
- node = Expression.unwrap(node)
287
-
288
- if (node.type === 'Identifier') {
289
- const binding = references.get(node.start)
290
- const value = binding === undefined ? undefined : values.get(binding)
291
- if (binding === undefined || !value) return node
292
-
293
- if (
294
- active.has(binding) ||
295
- (!imported.has(binding) && node.start < value.end)
296
- )
297
- throw new Themes.InvalidError(
298
- 'Static bindings must be acyclic and follow their declaration.',
299
- node,
300
- )
301
-
302
- active.add(binding)
303
-
304
- const resolved = resolve(value, allowed, active)
305
-
306
- active.delete(binding)
307
-
308
- if (
309
- ['CallExpression', 'NewExpression', 'Identifier'].includes(
310
- resolved.type,
311
- )
312
- )
313
- return node
314
-
315
- if (
316
- resolved.type === 'ObjectExpression' ||
317
- resolved.type === 'ArrayExpression'
318
- ) {
319
- for (const path of paths(binding)) {
320
- if (path.some((node) => allowed.has(node.start))) continue
321
-
322
- if (
323
- !path.some(
324
- (node) =>
325
- node.type === 'AssignmentExpression' ||
326
- node.type === 'UpdateExpression' ||
327
- ((node.type === 'ForInStatement' ||
328
- node.type === 'ForOfStatement') &&
329
- path.includes(node.left)) ||
330
- (node.type === 'UnaryExpression' && node.operator === 'delete'),
331
- ) &&
332
- path.some(
333
- (node) => node.type === 'MemberExpression' && scalar(node),
334
- )
335
- )
336
- continue
337
-
338
- const unsupported = path.find(
339
- (node) =>
340
- ![
341
- 'Program',
342
- 'TSModuleDeclaration',
343
- 'TSModuleBlock',
344
- 'VariableDeclaration',
345
- 'VariableDeclarator',
346
- 'Identifier',
347
- 'MemberExpression',
348
- 'ObjectExpression',
349
- 'Property',
350
- 'ArrayExpression',
351
- 'SpreadElement',
352
- 'TSAsExpression',
353
- 'TSSatisfiesExpression',
354
- 'TSNonNullExpression',
355
- 'TSTypeAssertion',
356
- 'ExportNamedDeclaration',
357
- 'ExportDefaultDeclaration',
358
- 'ExportSpecifier',
359
- ].includes(node.type),
360
- )
361
- if (unsupported)
362
- throw new Themes.InvalidError(
363
- 'Static data cannot be mutated or escape through unsupported expressions.',
364
- unsupported,
365
- )
366
-
367
- const write = path.find(
368
- (node) =>
369
- (node.type === 'VariableDeclarator' &&
370
- (node.id.type !== 'Identifier' || !values.has(node.start))) ||
371
- node.type === 'AssignmentExpression' ||
372
- node.type === 'UpdateExpression' ||
373
- (node.type === 'UnaryExpression' && node.operator === 'delete') ||
374
- ((node.type === 'ForInStatement' ||
375
- node.type === 'ForOfStatement') &&
376
- path.some((value) => value === node.left)),
377
- )
378
-
379
- const call = path.find(
380
- (node) =>
381
- node.type === 'CallExpression' || node.type === 'NewExpression',
382
- )
383
- if (write || call)
384
- throw new Themes.InvalidError(
385
- 'Static data cannot be mutated or escape to runtime calls.',
386
- write ?? call!,
387
- )
388
- }
389
- }
390
-
391
- used.add(resolved.start)
392
-
393
- return resolved
394
- }
395
-
396
- if (node.type === 'MemberExpression' && !node.optional) {
397
- const object = resolve(node.object, allowed, active)
398
-
399
- const key =
400
- node.property.type === 'Identifier' && !node.computed
401
- ? node.property.name
402
- : node.property.type === 'Literal'
403
- ? String(node.property.value)
404
- : undefined
405
-
406
- if (key !== undefined && object.type === 'ObjectExpression') {
407
- const entries = properties(object, allowed)
408
- if (
409
- entries.some(
410
- (property) =>
411
- property.type === 'Property' &&
412
- property.computed &&
413
- property.key.type !== 'Literal',
414
- )
415
- )
416
- throw new Themes.InvalidError(
417
- 'Static member reads cannot cross unresolved computed keys.',
418
- node,
419
- )
420
-
421
- const property = entries.find(
422
- (property) =>
423
- property.type === 'Property' &&
424
- (property.key.type === 'Identifier'
425
- ? property.key.name
426
- : property.key.type === 'Literal'
427
- ? String(property.key.value)
428
- : undefined) === key,
429
- )
430
- if (property?.type === 'Property')
431
- return resolve(property.value, allowed, active)
432
- }
433
-
434
- if (
435
- key !== undefined &&
436
- object.type === 'ArrayExpression' &&
437
- /^(?:0|[1-9]\d*)$/.test(key)
438
- ) {
439
- if (
440
- object.elements
441
- .slice(0, Number(key) + 1)
442
- .some((element) => element?.type === 'SpreadElement')
443
- )
444
- throw new Themes.InvalidError(
445
- 'Static array indexes cannot cross spread elements.',
446
- node,
447
- )
448
-
449
- const element = object.elements[Number(key)]
450
- if (element && element.type !== 'SpreadElement')
451
- return resolve(element, allowed, active)
452
- }
453
- }
454
-
455
- used.add(node.start)
456
-
457
- return node
458
- }
459
-
460
- function properties(
461
- node: Ast.ObjectExpression,
462
- allowed: ReadonlySet<number>,
463
- ): readonly Ast.ObjectPropertyKind[] {
464
- const result = new Map<string, Ast.ObjectPropertyKind>()
465
-
466
- for (const property of node.properties) {
467
- const entries =
468
- property.type === 'SpreadElement'
469
- ? (() => {
470
- const value = resolve(property.argument, allowed)
471
- if (value.type !== 'ObjectExpression')
472
- throw new Themes.InvalidError(
473
- 'Static spreads require an immutable object literal.',
474
- property,
475
- )
476
-
477
- return properties(value, allowed)
478
- })()
479
- : [property]
480
-
481
- for (const entry of entries) {
482
- if (entry.type !== 'Property')
483
- throw new Themes.InvalidError(
484
- 'Unsupported static object entry.',
485
- entry,
486
- )
487
-
488
- if (
489
- !entry.computed &&
490
- ((entry.key.type === 'Identifier' &&
491
- entry.key.name === '__proto__') ||
492
- (entry.key.type === 'Literal' && entry.key.value === '__proto__'))
493
- )
494
- throw new Themes.InvalidError(
495
- 'Static object prototypes are unsupported.',
496
- entry,
497
- )
498
-
499
- if (entry.computed && entry.key.type !== 'Literal') {
500
- result.set(`computed:${entry.start}`, entry)
501
- continue
502
- }
503
-
504
- const key =
505
- entry.key.type === 'Identifier'
506
- ? entry.key.name
507
- : entry.key.type === 'Literal'
508
- ? String(entry.key.value)
509
- : undefined
510
- if (key === undefined || entry.method || entry.kind !== 'init')
511
- throw new Themes.InvalidError(
512
- 'Static data requires literal property keys without methods.',
513
- entry,
514
- )
515
-
516
- result.set(
517
- key,
518
- entry.shorthand ? { ...entry, shorthand: false } : entry,
519
- )
520
- }
521
- }
522
-
523
- return [...result.values()]
524
- }
525
-
526
- function type(node: Ast.Node, active = new Set<number>()): Ast.Node {
527
- if (
528
- node.type === 'TSTypeReference' &&
529
- node.typeName.type === 'Identifier'
530
- ) {
531
- const name = typeReferences.get(node.start)
532
- if (name === undefined) return node
533
-
534
- const value = types.get(name)
535
- if (!value) return node
536
-
537
- if (active.has(name))
538
- throw new Themes.InvalidError(
539
- 'Dynamic type aliases must be acyclic.',
540
- node,
541
- )
542
-
543
- active.add(name)
544
-
545
- const result = type(value, active)
546
-
547
- active.delete(name)
548
-
549
- return result
550
- }
551
-
552
- if (node.type === 'TSParenthesizedType')
553
- return type(node.typeAnnotation, active)
554
-
555
- if (node.type === 'TSIntersectionType') {
556
- const parts = node.types.map((value) => type(value, active))
557
- if (parts.every((part) => part.type === 'TSTypeLiteral'))
558
- return {
559
- ...node,
560
- type: 'TSTypeLiteral',
561
- members: parts
562
- .flatMap((part) =>
563
- part.type === 'TSTypeLiteral' ? part.members : [],
564
- )
565
- .reduce<Ast.TSSignature[]>((members, member) => {
566
- if (
567
- member.type !== 'TSPropertySignature' ||
568
- member.computed ||
569
- !member.typeAnnotation
570
- )
571
- return [...members, member]
572
-
573
- const key =
574
- member.key.type === 'Identifier'
575
- ? member.key.name
576
- : member.key.type === 'Literal'
577
- ? member.key.value
578
- : undefined
579
-
580
- const index = members.findIndex(
581
- (value) =>
582
- value.type === 'TSPropertySignature' &&
583
- !value.computed &&
584
- value.typeAnnotation &&
585
- key !== undefined &&
586
- key ===
587
- (value.key.type === 'Identifier'
588
- ? value.key.name
589
- : value.key.type === 'Literal'
590
- ? value.key.value
591
- : undefined),
592
- )
593
-
594
- const previous = members[index]
595
- if (
596
- previous?.type !== 'TSPropertySignature' ||
597
- !previous.typeAnnotation
598
- )
599
- return [...members, member]
600
-
601
- members[index] = {
602
- ...previous,
603
- optional: previous.optional && member.optional,
604
- typeAnnotation: {
605
- ...previous.typeAnnotation,
606
- typeAnnotation: {
607
- type: 'TSIntersectionType',
608
- start: previous.start,
609
- end: member.end,
610
- types: [
611
- previous.typeAnnotation.typeAnnotation,
612
- member.typeAnnotation.typeAnnotation,
613
- ],
614
- },
615
- },
616
- }
617
-
618
- return members
619
- }, []),
620
- } as Ast.TSTypeLiteral
621
-
622
- return { ...node, types: parts } as Ast.TSIntersectionType
623
- }
624
-
625
- if (node.type === 'TSUnionType')
626
- return {
627
- ...node,
628
- types: node.types.map((value) => type(value, active)),
629
- } as Ast.TSUnionType
630
-
631
- if (node.type === 'TSTemplateLiteralType')
632
- return {
633
- ...node,
634
- types: node.types.map((value) => type(value, active)),
635
- } as Ast.TSTemplateLiteralType
636
-
637
- return node
638
- }
639
-
640
- function normalize(
641
- node: Ast.Node,
642
- allowed: ReadonlySet<number>,
643
- opaque: ReadonlySet<number> = new Set(),
644
- omitUndefined = false,
645
- ): Ast.Node {
646
- if (opaque.has(node.start)) return node
647
- node = resolve(node, allowed)
648
-
649
- if (node.type === 'ObjectExpression') {
650
- const expanded = properties(node, allowed).filter((property) => {
651
- if (!omitUndefined || property.type !== 'Property') return true
652
- const value = Expression.unwrap(property.value)
653
- return !(
654
- value.type === 'Identifier' &&
655
- value.name === 'undefined' &&
656
- absent.has(value.start)
657
- )
658
- })
659
-
660
- const normalized = expanded.map((property) =>
661
- property.type === 'Property'
662
- ? (() => {
663
- const value = normalize(
664
- property.value,
665
- allowed,
666
- opaque,
667
- omitUndefined,
668
- )
669
-
670
- return value === property.value
671
- ? property
672
- : { ...property, value }
673
- })()
674
- : property,
675
- )
676
-
677
- return normalized.length === node.properties.length &&
678
- normalized.every(
679
- (property, index) => property === node.properties[index],
680
- )
681
- ? node
682
- : ({ ...node, properties: normalized } as Ast.ObjectExpression)
683
- }
684
-
685
- if (node.type === 'ArrayExpression') {
686
- const elements = node.elements.map((element) =>
687
- element && element.type !== 'SpreadElement'
688
- ? normalize(element, allowed, opaque, omitUndefined)
689
- : element,
690
- )
691
-
692
- return elements.every(
693
- (element, index) => element === node.elements[index],
694
- )
695
- ? node
696
- : ({ ...node, elements } as Ast.ArrayExpression)
697
- }
698
-
699
- if (node.type === 'TemplateLiteral') {
700
- const expressions = node.expressions.map((expression) =>
701
- normalize(expression, allowed, opaque, omitUndefined),
702
- )
703
-
704
- return expressions.every(
705
- (expression, index) => expression === node.expressions[index],
706
- )
707
- ? node
708
- : ({ ...node, expressions } as Ast.TemplateLiteral)
709
- }
710
-
711
- return node
712
- }
713
-
714
- return {
715
- visitor,
716
- /** Recognizes the unshadowed undefined value without evaluating expressions. */
717
- absent(input: Ast.Node): boolean {
718
- const node = Expression.unwrap(input)
719
- return (
720
- node.type === 'Identifier' &&
721
- node.name === 'undefined' &&
722
- absent.has(node.start)
723
- )
724
- },
725
- /** Resolves an exported immutable literal without evaluating module code. */
726
- exported(name: string): Ast.Node | undefined {
727
- for (const statement of program.body) {
728
- const declaration =
729
- statement.type === 'ExportNamedDeclaration'
730
- ? statement.declaration
731
- : statement
732
- if (
733
- declaration?.type !== 'VariableDeclaration' ||
734
- declaration.kind !== 'const'
735
- )
736
- continue
737
- for (const value of declaration.declarations) {
738
- if (
739
- value.id.type !== 'Identifier' ||
740
- value.id.name !== name ||
741
- !value.init
742
- )
743
- continue
744
- const reference = {
745
- ...value.id,
746
- start: program.end + 1,
747
- end: program.end + 1,
748
- }
749
- references.set(reference.start, value.start)
750
- try {
751
- return normalize(reference, new Set(), new Set(), true)
752
- } finally {
753
- references.delete(reference.start)
754
- }
755
- }
756
- }
757
- for (const statement of program.body) {
758
- if (statement.type !== 'ImportDeclaration') continue
759
- const specifier = statement.specifiers.find(
760
- (specifier) => specifier.local.name === name,
761
- )
762
- if (!specifier || !imports[name]) continue
763
- const reference = {
764
- ...specifier.local,
765
- start: program.end + 1,
766
- end: program.end + 1,
767
- }
768
- references.set(reference.start, specifier.start)
769
- try {
770
- return normalize(reference, new Set(), new Set(), true)
771
- } finally {
772
- references.delete(reference.start)
773
- }
774
- }
775
- return undefined
776
- },
777
- resolve,
778
- properties,
779
- type,
780
- used,
781
- normalize,
782
- bindings: new Set(values.keys()),
783
- }
784
- }