zyzz 0.0.28 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/binding/wasi/wasi-worker.mjs +186 -0
  2. package/binding/wasi/zyzz.wasi.cjs +2302 -0
  3. package/binding/wasi/zyzz.wasm32-wasi.wasm +0 -0
  4. package/binding/zyzz.linux-x64-gnu.node +0 -0
  5. package/dist/babel/index.d.ts.map +1 -1
  6. package/dist/babel/index.js +2 -4
  7. package/dist/babel/index.js.map +1 -1
  8. package/dist/babel/internal/Compilation.d.ts +0 -1
  9. package/dist/babel/internal/Compilation.d.ts.map +1 -1
  10. package/dist/compiler/Graph.d.ts +14 -11
  11. package/dist/compiler/Graph.d.ts.map +1 -1
  12. package/dist/compiler/Graph.js +57 -1442
  13. package/dist/compiler/Graph.js.map +1 -1
  14. package/dist/compiler/Native.d.ts +7 -9
  15. package/dist/compiler/Native.d.ts.map +1 -1
  16. package/dist/compiler/Native.js +12 -716
  17. package/dist/compiler/Native.js.map +1 -1
  18. package/dist/compiler/Source.d.ts +122 -24
  19. package/dist/compiler/Source.d.ts.map +1 -1
  20. package/dist/compiler/Source.js +10 -1267
  21. package/dist/compiler/Source.js.map +1 -1
  22. package/dist/compiler/Transform.d.ts +4 -3
  23. package/dist/compiler/Transform.d.ts.map +1 -1
  24. package/dist/compiler/Transform.js +13 -961
  25. package/dist/compiler/Transform.js.map +1 -1
  26. package/dist/compiler/internal/AtRules.d.ts +5 -1
  27. package/dist/compiler/internal/AtRules.d.ts.map +1 -1
  28. package/dist/compiler/internal/AtRules.js +12 -106
  29. package/dist/compiler/internal/AtRules.js.map +1 -1
  30. package/dist/compiler/internal/Context.d.ts +11 -0
  31. package/dist/compiler/internal/Context.d.ts.map +1 -0
  32. package/dist/compiler/internal/Context.js +11 -0
  33. package/dist/compiler/internal/Context.js.map +1 -0
  34. package/dist/compiler/internal/Results.d.ts +148 -0
  35. package/dist/compiler/internal/Results.d.ts.map +1 -0
  36. package/dist/compiler/internal/Results.js +259 -0
  37. package/dist/compiler/internal/Results.js.map +1 -0
  38. package/dist/compiler/internal/Syntax.d.ts +0 -2
  39. package/dist/compiler/internal/Syntax.d.ts.map +1 -1
  40. package/dist/compiler/internal/Syntax.js +0 -2
  41. package/dist/compiler/internal/Syntax.js.map +1 -1
  42. package/dist/compiler/internal/Wire.d.ts +17 -0
  43. package/dist/compiler/internal/Wire.d.ts.map +1 -0
  44. package/dist/compiler/internal/Wire.js +795 -0
  45. package/dist/compiler/internal/Wire.js.map +1 -0
  46. package/dist/internal/Addon.d.ts +28 -0
  47. package/dist/internal/Addon.d.ts.map +1 -0
  48. package/dist/internal/Addon.js +87 -0
  49. package/dist/internal/Addon.js.map +1 -0
  50. package/dist/internal/Literal.d.ts +4 -1
  51. package/dist/internal/Literal.d.ts.map +1 -1
  52. package/dist/internal/Literal.js +4 -2
  53. package/dist/internal/Literal.js.map +1 -1
  54. package/dist/internal/Token.d.ts +2 -1
  55. package/dist/internal/Token.d.ts.map +1 -1
  56. package/dist/internal/Token.js +2 -2
  57. package/dist/internal/Token.js.map +1 -1
  58. package/dist/internal/Vlq.d.ts +14 -0
  59. package/dist/internal/Vlq.d.ts.map +1 -0
  60. package/dist/internal/Vlq.js +47 -0
  61. package/dist/internal/Vlq.js.map +1 -0
  62. package/dist/internal/Wasm.d.ts +22 -0
  63. package/dist/internal/Wasm.d.ts.map +1 -0
  64. package/dist/internal/Wasm.js +83 -0
  65. package/dist/internal/Wasm.js.map +1 -0
  66. package/dist/metro/Graph.d.ts +0 -1
  67. package/dist/metro/Graph.d.ts.map +1 -1
  68. package/dist/metro/transformer.d.ts.map +1 -1
  69. package/dist/metro/transformer.js +0 -1
  70. package/dist/metro/transformer.js.map +1 -1
  71. package/dist/next/internal/Project.d.ts.map +1 -1
  72. package/dist/next/internal/Project.js +2 -5
  73. package/dist/next/internal/Project.js.map +1 -1
  74. package/dist/node/Host.d.ts.map +1 -1
  75. package/dist/node/Host.js +0 -2
  76. package/dist/node/Host.js.map +1 -1
  77. package/dist/node/internal/Contracts.d.ts.map +1 -1
  78. package/dist/node/internal/Contracts.js +3 -7
  79. package/dist/node/internal/Contracts.js.map +1 -1
  80. package/dist/node/internal/Snapshot.d.ts +0 -1
  81. package/dist/node/internal/Snapshot.d.ts.map +1 -1
  82. package/dist/node/internal/Snapshot.js +0 -6
  83. package/dist/node/internal/Snapshot.js.map +1 -1
  84. package/dist/runtime/Composition.d.ts +2 -3
  85. package/dist/runtime/Composition.d.ts.map +1 -1
  86. package/dist/runtime/Composition.js +51 -30
  87. package/dist/runtime/Composition.js.map +1 -1
  88. package/dist/runtime/Recipe.d.ts.map +1 -1
  89. package/dist/runtime/Recipe.js +16 -12
  90. package/dist/runtime/Recipe.js.map +1 -1
  91. package/dist/unplugin/index.d.ts.map +1 -1
  92. package/dist/unplugin/index.js +3 -6
  93. package/dist/unplugin/index.js.map +1 -1
  94. package/dist/vite/index.d.ts.map +1 -1
  95. package/dist/vite/index.js +696 -201
  96. package/dist/vite/index.js.map +1 -1
  97. package/dist/web/Css.d.ts +8 -3
  98. package/dist/web/Css.d.ts.map +1 -1
  99. package/dist/web/Css.js +5 -721
  100. package/dist/web/Css.js.map +1 -1
  101. package/dist/web/internal/Block.d.ts +0 -2
  102. package/dist/web/internal/Block.d.ts.map +1 -1
  103. package/dist/web/internal/Block.js +1 -12
  104. package/dist/web/internal/Block.js.map +1 -1
  105. package/dist/web/internal/ClassName.d.ts +23 -18
  106. package/dist/web/internal/ClassName.d.ts.map +1 -1
  107. package/dist/web/internal/ClassName.js +26 -55
  108. package/dist/web/internal/ClassName.js.map +1 -1
  109. package/dist/web/internal/Contributions.d.ts +3 -5
  110. package/dist/web/internal/Contributions.d.ts.map +1 -1
  111. package/dist/web/internal/Contributions.js +0 -45
  112. package/dist/web/internal/Contributions.js.map +1 -1
  113. package/dist/web/internal/Engine.browser.d.ts +8 -0
  114. package/dist/web/internal/Engine.browser.d.ts.map +1 -0
  115. package/dist/web/internal/Engine.browser.js +42 -0
  116. package/dist/web/internal/Engine.browser.js.map +1 -0
  117. package/dist/web/internal/Engine.d.ts +9 -0
  118. package/dist/web/internal/Engine.d.ts.map +1 -0
  119. package/dist/web/internal/Engine.js +14 -0
  120. package/dist/web/internal/Engine.js.map +1 -0
  121. package/dist/web/internal/Themes.d.ts +1 -9
  122. package/dist/web/internal/Themes.d.ts.map +1 -1
  123. package/dist/web/internal/Themes.js +3 -221
  124. package/dist/web/internal/Themes.js.map +1 -1
  125. package/dist/web/internal/Wasm.generated.d.ts +4 -0
  126. package/dist/web/internal/Wasm.generated.d.ts.map +1 -0
  127. package/dist/web/internal/Wasm.generated.js +4 -0
  128. package/dist/web/internal/Wasm.generated.js.map +1 -0
  129. package/dist/web/internal/Wire.d.ts +19 -0
  130. package/dist/web/internal/Wire.d.ts.map +1 -0
  131. package/dist/web/internal/Wire.js +387 -0
  132. package/dist/web/internal/Wire.js.map +1 -0
  133. package/package.json +20 -1
  134. package/src/babel/index.ts +2 -5
  135. package/src/babel/internal/Compilation.ts +0 -1
  136. package/src/compiler/Graph.ts +89 -1930
  137. package/src/compiler/Native.ts +18 -871
  138. package/src/compiler/Source.ts +144 -1803
  139. package/src/compiler/Transform.ts +16 -1315
  140. package/src/compiler/internal/AtRules.ts +27 -115
  141. package/src/compiler/internal/Context.ts +11 -0
  142. package/src/compiler/internal/Results.ts +406 -0
  143. package/src/compiler/internal/Syntax.ts +0 -3
  144. package/src/compiler/internal/Wire.ts +1045 -0
  145. package/src/internal/Addon.ts +118 -0
  146. package/src/internal/Literal.ts +4 -2
  147. package/src/internal/Token.ts +2 -2
  148. package/src/internal/Vlq.ts +59 -0
  149. package/src/internal/Wasm.ts +111 -0
  150. package/src/metro/transformer.ts +0 -1
  151. package/src/next/internal/Project.ts +2 -9
  152. package/src/node/Host.ts +0 -2
  153. package/src/node/internal/Contracts.ts +3 -7
  154. package/src/node/internal/Snapshot.ts +0 -8
  155. package/src/runtime/Composition.ts +48 -25
  156. package/src/runtime/Recipe.ts +21 -14
  157. package/src/unplugin/index.ts +6 -6
  158. package/src/vite/index.ts +922 -221
  159. package/src/web/Css.ts +12 -908
  160. package/src/web/internal/Block.ts +0 -14
  161. package/src/web/internal/ClassName.ts +52 -85
  162. package/src/web/internal/Contributions.ts +3 -59
  163. package/src/web/internal/Engine.browser.ts +51 -0
  164. package/src/web/internal/Engine.ts +17 -0
  165. package/src/web/internal/Themes.ts +3 -279
  166. package/src/web/internal/Wasm.generated.ts +3 -0
  167. package/src/web/internal/Wire.ts +466 -0
  168. package/src/web/internal/wasm.d.ts +9 -0
  169. package/dist/compiler/internal/Applications.d.ts +0 -55
  170. package/dist/compiler/internal/Applications.d.ts.map +0 -1
  171. package/dist/compiler/internal/Applications.js +0 -393
  172. package/dist/compiler/internal/Applications.js.map +0 -1
  173. package/dist/compiler/internal/ColorProfiles.d.ts +0 -3
  174. package/dist/compiler/internal/ColorProfiles.d.ts.map +0 -1
  175. package/dist/compiler/internal/ColorProfiles.js +0 -84
  176. package/dist/compiler/internal/ColorProfiles.js.map +0 -1
  177. package/dist/compiler/internal/CompositionBindings.d.ts +0 -16
  178. package/dist/compiler/internal/CompositionBindings.d.ts.map +0 -1
  179. package/dist/compiler/internal/CompositionBindings.js +0 -89
  180. package/dist/compiler/internal/CompositionBindings.js.map +0 -1
  181. package/dist/compiler/internal/Compositions.d.ts +0 -37
  182. package/dist/compiler/internal/Compositions.d.ts.map +0 -1
  183. package/dist/compiler/internal/Compositions.js +0 -494
  184. package/dist/compiler/internal/Compositions.js.map +0 -1
  185. package/dist/compiler/internal/Configurations.d.ts +0 -26
  186. package/dist/compiler/internal/Configurations.d.ts.map +0 -1
  187. package/dist/compiler/internal/Configurations.js +0 -259
  188. package/dist/compiler/internal/Configurations.js.map +0 -1
  189. package/dist/compiler/internal/Contract.d.ts +0 -30
  190. package/dist/compiler/internal/Contract.d.ts.map +0 -1
  191. package/dist/compiler/internal/Contract.js +0 -753
  192. package/dist/compiler/internal/Contract.js.map +0 -1
  193. package/dist/compiler/internal/Contributions.d.ts +0 -54
  194. package/dist/compiler/internal/Contributions.d.ts.map +0 -1
  195. package/dist/compiler/internal/Contributions.js +0 -1151
  196. package/dist/compiler/internal/Contributions.js.map +0 -1
  197. package/dist/compiler/internal/Descriptors.d.ts +0 -15
  198. package/dist/compiler/internal/Descriptors.d.ts.map +0 -1
  199. package/dist/compiler/internal/Descriptors.js +0 -192
  200. package/dist/compiler/internal/Descriptors.js.map +0 -1
  201. package/dist/compiler/internal/Dynamic.d.ts +0 -14
  202. package/dist/compiler/internal/Dynamic.d.ts.map +0 -1
  203. package/dist/compiler/internal/Dynamic.js +0 -175
  204. package/dist/compiler/internal/Dynamic.js.map +0 -1
  205. package/dist/compiler/internal/Expression.d.ts +0 -19
  206. package/dist/compiler/internal/Expression.d.ts.map +0 -1
  207. package/dist/compiler/internal/Expression.js +0 -164
  208. package/dist/compiler/internal/Expression.js.map +0 -1
  209. package/dist/compiler/internal/Functions.d.ts +0 -5
  210. package/dist/compiler/internal/Functions.d.ts.map +0 -1
  211. package/dist/compiler/internal/Functions.js +0 -191
  212. package/dist/compiler/internal/Functions.js.map +0 -1
  213. package/dist/compiler/internal/Keyframes.d.ts +0 -5
  214. package/dist/compiler/internal/Keyframes.d.ts.map +0 -1
  215. package/dist/compiler/internal/Keyframes.js +0 -51
  216. package/dist/compiler/internal/Keyframes.js.map +0 -1
  217. package/dist/compiler/internal/Names.d.ts +0 -5
  218. package/dist/compiler/internal/Names.d.ts.map +0 -1
  219. package/dist/compiler/internal/Names.js +0 -37
  220. package/dist/compiler/internal/Names.js.map +0 -1
  221. package/dist/compiler/internal/NativeBindings.d.ts +0 -72
  222. package/dist/compiler/internal/NativeBindings.d.ts.map +0 -1
  223. package/dist/compiler/internal/NativeBindings.js +0 -171
  224. package/dist/compiler/internal/NativeBindings.js.map +0 -1
  225. package/dist/compiler/internal/NativeMedia.d.ts +0 -14
  226. package/dist/compiler/internal/NativeMedia.d.ts.map +0 -1
  227. package/dist/compiler/internal/NativeMedia.js +0 -287
  228. package/dist/compiler/internal/NativeMedia.js.map +0 -1
  229. package/dist/compiler/internal/NativeVars.d.ts +0 -28
  230. package/dist/compiler/internal/NativeVars.d.ts.map +0 -1
  231. package/dist/compiler/internal/NativeVars.js +0 -160
  232. package/dist/compiler/internal/NativeVars.js.map +0 -1
  233. package/dist/compiler/internal/PackedStyles.d.ts +0 -37
  234. package/dist/compiler/internal/PackedStyles.d.ts.map +0 -1
  235. package/dist/compiler/internal/PackedStyles.js +0 -344
  236. package/dist/compiler/internal/PackedStyles.js.map +0 -1
  237. package/dist/compiler/internal/Properties.d.ts +0 -5
  238. package/dist/compiler/internal/Properties.d.ts.map +0 -1
  239. package/dist/compiler/internal/Properties.js +0 -82
  240. package/dist/compiler/internal/Properties.js.map +0 -1
  241. package/dist/compiler/internal/RecipeConditions.d.ts +0 -41
  242. package/dist/compiler/internal/RecipeConditions.d.ts.map +0 -1
  243. package/dist/compiler/internal/RecipeConditions.js +0 -82
  244. package/dist/compiler/internal/RecipeConditions.js.map +0 -1
  245. package/dist/compiler/internal/RecipePayloads.d.ts +0 -31
  246. package/dist/compiler/internal/RecipePayloads.d.ts.map +0 -1
  247. package/dist/compiler/internal/RecipePayloads.js +0 -99
  248. package/dist/compiler/internal/RecipePayloads.js.map +0 -1
  249. package/dist/compiler/internal/Recipes.d.ts +0 -32
  250. package/dist/compiler/internal/Recipes.d.ts.map +0 -1
  251. package/dist/compiler/internal/Recipes.js +0 -339
  252. package/dist/compiler/internal/Recipes.js.map +0 -1
  253. package/dist/compiler/internal/Selectors.d.ts +0 -13
  254. package/dist/compiler/internal/Selectors.d.ts.map +0 -1
  255. package/dist/compiler/internal/Selectors.js +0 -280
  256. package/dist/compiler/internal/Selectors.js.map +0 -1
  257. package/dist/compiler/internal/Static.d.ts +0 -39
  258. package/dist/compiler/internal/Static.d.ts.map +0 -1
  259. package/dist/compiler/internal/Static.js +0 -534
  260. package/dist/compiler/internal/Static.js.map +0 -1
  261. package/dist/compiler/internal/Themes.d.ts +0 -190
  262. package/dist/compiler/internal/Themes.d.ts.map +0 -1
  263. package/dist/compiler/internal/Themes.js +0 -1577
  264. package/dist/compiler/internal/Themes.js.map +0 -1
  265. package/dist/compiler/internal/Vars.d.ts +0 -33
  266. package/dist/compiler/internal/Vars.d.ts.map +0 -1
  267. package/dist/compiler/internal/Vars.js +0 -387
  268. package/dist/compiler/internal/Vars.js.map +0 -1
  269. package/dist/compiler/internal/ViewTransitions.d.ts +0 -3
  270. package/dist/compiler/internal/ViewTransitions.d.ts.map +0 -1
  271. package/dist/compiler/internal/ViewTransitions.js +0 -68
  272. package/dist/compiler/internal/ViewTransitions.js.map +0 -1
  273. package/dist/internal/Cascade.d.ts +0 -74
  274. package/dist/internal/Cascade.d.ts.map +0 -1
  275. package/dist/internal/Cascade.js +0 -210
  276. package/dist/internal/Cascade.js.map +0 -1
  277. package/src/compiler/internal/Applications.ts +0 -610
  278. package/src/compiler/internal/ColorProfiles.ts +0 -93
  279. package/src/compiler/internal/CompositionBindings.ts +0 -120
  280. package/src/compiler/internal/Compositions.ts +0 -678
  281. package/src/compiler/internal/Configurations.ts +0 -349
  282. package/src/compiler/internal/Contract.ts +0 -1028
  283. package/src/compiler/internal/Contributions.ts +0 -1561
  284. package/src/compiler/internal/Descriptors.ts +0 -242
  285. package/src/compiler/internal/Dynamic.ts +0 -275
  286. package/src/compiler/internal/Expression.ts +0 -218
  287. package/src/compiler/internal/Functions.ts +0 -206
  288. package/src/compiler/internal/Keyframes.ts +0 -62
  289. package/src/compiler/internal/Names.ts +0 -48
  290. package/src/compiler/internal/NativeBindings.ts +0 -235
  291. package/src/compiler/internal/NativeMedia.ts +0 -342
  292. package/src/compiler/internal/NativeVars.ts +0 -231
  293. package/src/compiler/internal/PackedStyles.ts +0 -473
  294. package/src/compiler/internal/Properties.ts +0 -121
  295. package/src/compiler/internal/RecipeConditions.ts +0 -139
  296. package/src/compiler/internal/RecipePayloads.ts +0 -132
  297. package/src/compiler/internal/Recipes.ts +0 -531
  298. package/src/compiler/internal/Selectors.ts +0 -353
  299. package/src/compiler/internal/Static.ts +0 -784
  300. package/src/compiler/internal/Themes.ts +0 -2398
  301. package/src/compiler/internal/Vars.ts +0 -516
  302. package/src/compiler/internal/ViewTransitions.ts +0 -82
@@ -1,2398 +0,0 @@
1
- /**
2
- * Extracts local theme data and validates its lexical source references.
3
- * @module
4
- */
5
- import type * as Syntax from './Syntax.js'
6
- import * as Identity from '../../internal/Identity.js'
7
- import * as Identifiers from './Identifiers.js'
8
- import type { cssFunction } from '../../web/cssFunction.js'
9
- import type * as RuleReference from '../../internal/RuleReference.js'
10
- import type * as Ast from '@oxc-project/types'
11
- import type * as Walker from 'oxc-walker'
12
- import type * as Binding from '../../internal/Binding.js'
13
- import * as Config from '../../internal/Configuration.js'
14
- import * as Expression from './Expression.js'
15
- import * as Configurations from './Configurations.js'
16
- import * as Token from '../../internal/Token.js'
17
- import * as Theme from '../../internal/Theme.js'
18
- import * as VariableSets from '../../internal/VariableSets.js'
19
- import * as Vars from '../../Vars.js'
20
- import type * as Source from '../Source.js'
21
- import type * as PackedStyles from './PackedStyles.js'
22
-
23
- /** Local bound-authoring initializer replaced while retaining its inferred type. */
24
- export type Alias = Call & {
25
- /** Ordered authoring members replaced in a shared destructuring initializer. */
26
- readonly bindings?: readonly ('style' | 'variants')[] | undefined
27
- /** Whether the initializer supplies destructured authoring bindings. */
28
- readonly destructured: boolean
29
- /** Retains an immutable theme/configuration alias value with an explicit type. */
30
- readonly retained?: boolean | undefined
31
- }
32
-
33
- /** Theme factory span and generated scope key. */
34
- export type Call = {
35
- /** Whether native defineConfig retains a typed React Provider. */
36
- readonly nativeProvider?: boolean | undefined
37
- readonly variableSet?: boolean | undefined
38
- readonly directVariables?: boolean | undefined
39
- readonly variableConfig?: boolean | undefined
40
- readonly variableMappings?: Vars.Mappings | false | undefined
41
- /** Whether this bound authoring alias declares recipes. */
42
- readonly recipe?: boolean | undefined
43
- /** Static CSS function signature shared during extraction and packed serialization. */
44
- readonly function?:
45
- | {
46
- parameters: readonly cssFunction.Parameter[]
47
- returns: cssFunction.Syntax
48
- }
49
- | undefined
50
- /** Named stylesheet identity domain. */
51
- readonly reference?: RuleReference.Kind | undefined
52
- /** Canonical defining module for multi-entry variable contracts. */
53
- readonly variableOwner?: string | undefined
54
- readonly output?: 'html' | undefined
55
- /** Portable explicit variable references. */
56
- readonly variables?: Readonly<Record<string, Binding.Reference>> | undefined
57
- /** Whether the compiled configuration supplies root controls. */
58
- readonly appearance?: boolean | undefined
59
- /** Whether the compiled configuration supplies initialization. */
60
- readonly script?: boolean | undefined
61
- /** Bound root initialization script export. */
62
- readonly initialization?: boolean | undefined
63
- /** Bound root controls export. */
64
- readonly root?: boolean | undefined
65
- /** Config helper represented by this linked binding. */
66
- readonly selection?: boolean | undefined
67
- /** Legacy packed catalogs have static members but are not callable. */
68
- /** Legacy packed catalog exposes members but lacks callable-selection capability. */
69
- readonly catalogOnly?: boolean | undefined
70
- /** Validated inline configuration options retained for packed declarations. */
71
- readonly options?: Readonly<Record<string, unknown>> | undefined
72
- /** JSON-encoded member path tuples and their compiled scope keys. */
73
- readonly members?: Readonly<Record<string, string>> | undefined
74
- /** Complete authoring type retained for configuration declarations. */
75
- readonly type?: string | undefined
76
- /** Exclusive source offset. */
77
- readonly end: number
78
- /** Stable module/binding scope key. */
79
- readonly name: string
80
- /** Inclusive source offset. */
81
- readonly start: number
82
- /** Literal token contract retained in rewritten TypeScript type assertions. */
83
- readonly tokenType: string
84
- }
85
-
86
- /** Internal context passed between graph extraction and module rewriting. */
87
- export const context = Symbol('zyzz.source.graph')
88
-
89
- /** Resolved authoring contract within a supplied source graph. */
90
- export type Link = {
91
- /** Complete callable style and ownership data for cross-module composition. */
92
- readonly style?: PackedStyles.Definition | undefined
93
- readonly binding: string
94
- readonly call: Call
95
- readonly definition: Theme.Definition
96
- readonly kind:
97
- | 'config'
98
- | 'style'
99
- | 'theme'
100
- | 'style-reference'
101
- | 'animation'
102
- | 'rule-reference'
103
- | 'variables'
104
- readonly members?: Readonly<Record<string, Link>> | undefined
105
- }
106
-
107
- /** A readonly variable argument consumed by a native React hook. */
108
- export type VarsRead = {
109
- /** Owning configuration fallback. */
110
- readonly defaultVars: string
111
- /** Exclusive source offset. */
112
- readonly end: number
113
- /** Stable configuration identity for graph-owned native profiles. */
114
- readonly owner: string
115
- /** Inclusive source offset. */
116
- readonly start: number
117
- /** A standalone definition that does not select a named catalog entry. */
118
- readonly unnamed: boolean
119
- /** Complete compatible variable alternatives. */
120
- readonly vars: Readonly<Record<string, Theme.Definition>>
121
- }
122
-
123
- /** Resolves the variable alternatives a linked configuration or variable set exposes to native hooks. */
124
- export function varsRead(
125
- link: Pick<Link, 'call' | 'definition' | 'members'>,
126
- ): Omit<VarsRead, 'end' | 'start'> {
127
- const named = link.call.options?.themes !== undefined
128
- const vars = (() => {
129
- if (!named) return { default: link.definition }
130
- return Object.fromEntries(
131
- Object.entries(link.members ?? {}).flatMap((entry) => {
132
- const [key, member] = entry
133
- const path = JSON.parse(key) as string[]
134
- if (path.length === 1 && link.call.selection)
135
- return [[path[0]!, member.definition]]
136
- if (path.length === 2 && path[0] === 'themes')
137
- return [[path[1]!, member.definition]]
138
- return []
139
- }),
140
- )
141
- })()
142
-
143
- return {
144
- defaultVars: named ? String(link.call.options!.defaultTheme) : 'default',
145
- owner: link.call.name,
146
- unnamed: !named,
147
- vars,
148
- }
149
- }
150
-
151
- /** Shared graph data; no filesystem or runtime evaluation is involved. */
152
- export type Context = {
153
- /** Canonical identifier names collected during graph validation. */
154
- readonly identifiers?: ReadonlySet<string> | undefined
155
- /** Syntax owned by the current graph compilation. */
156
- readonly parsed?: ReturnType<typeof Syntax.parse> | undefined
157
- /** Packed exports indexed by the importing module's source specifier. */
158
- readonly libraries?:
159
- | Readonly<Record<string, Readonly<Record<string, Link>>>>
160
- | undefined
161
- /** Immutable literal imports resolved from supplied source modules. */
162
- readonly constants?: Readonly<Record<string, Ast.Node>> | undefined
163
- /** Published class lists of imported callable definitions. */
164
- readonly styleClasses?: Readonly<Record<string, string>> | undefined
165
- /** Locally imported stylesheet factories resolved through source barrels. */
166
- readonly factories?: Readonly<Record<string, string>> | undefined
167
- readonly extracted?: Source.extract.ReturnType | undefined
168
- readonly links: Readonly<Record<string, Link>>
169
- readonly owners?:
170
- | Readonly<Record<string, { call: Call; moduleId: string; source: string }>>
171
- | undefined
172
- }
173
-
174
- /** Collects immutable module-level themes without evaluating source. */
175
- export function collect(program: Ast.Program, options: collect.Options) {
176
- const staticTokens: Ast.Node[] = []
177
- const aliases: Alias[] = []
178
- const aliasBindings = new Map<number, Alias>()
179
- const aliasReferences = new Set<number>()
180
- const appearances = new Set<string>()
181
- const scopeApplications = new Map<
182
- number,
183
- { end: number; output: 'html' | undefined }
184
- >()
185
- const selections = new Set<string>()
186
- const selectionUses = new Set<string>()
187
- const calls: Call[] = []
188
- const scripts = new Set<string>()
189
- const definitions = new Map<number, Call>()
190
- const factories = new Set<number>()
191
- const imports = new Set<number>()
192
- const variableImports = new Set<number>()
193
- const configImports = new Set<number>()
194
- const factoryImports = new Map<number, 'create' | 'define' | 'extend'>()
195
- const nativeFactories = new Set<string>()
196
- const configs = new Map<string, Link>()
197
- const configBindings = new Map<number, Link>()
198
- const factoryReferences = new Set<number>()
199
- const references: Reference[] = []
200
- const varsReads: VarsRead[] = []
201
-
202
- const styles = new Map<
203
- number,
204
- {
205
- call: Ast.CallExpression
206
- recipe?: boolean | undefined
207
- output?: 'html' | undefined
208
- theme: Theme.Definition
209
- }
210
- >()
211
-
212
- const themes: Record<string, Theme.Definition> = Object.create(null)
213
- const tokens = new Map<number, { end: number; reference: Token.Reference }>()
214
-
215
- for (const node of program.body) {
216
- if (
217
- node.type !== 'ImportDeclaration' ||
218
- !['zyzz', 'zyzz/react-native', 'zyzz/react-native/react'].includes(
219
- node.source.value,
220
- ) ||
221
- node.importKind === 'type'
222
- )
223
- continue
224
-
225
- for (const specifier of node.specifiers) {
226
- if (node.source.value !== 'zyzz') {
227
- if (
228
- specifier.type === 'ImportSpecifier' &&
229
- specifier.importKind !== 'type' &&
230
- (specifier.imported.type === 'Identifier'
231
- ? specifier.imported.name
232
- : specifier.imported.value) === 'defineConfig'
233
- ) {
234
- factoryImports.set(specifier.start, 'create')
235
- nativeFactories.add(specifier.local.name)
236
- }
237
- continue
238
- }
239
-
240
- if (
241
- specifier.type === 'ImportSpecifier' &&
242
- specifier.importKind !== 'type' &&
243
- (specifier.imported.type === 'Identifier'
244
- ? specifier.imported.name
245
- : specifier.imported.value) === 'Vars'
246
- ) {
247
- imports.add(specifier.start)
248
- variableImports.add(specifier.start)
249
- } else if (
250
- specifier.type === 'ImportSpecifier' &&
251
- specifier.importKind !== 'type' &&
252
- (specifier.imported.type === 'Identifier'
253
- ? specifier.imported.name
254
- : specifier.imported.value) === 'Config'
255
- )
256
- configImports.add(specifier.start)
257
- else if (
258
- specifier.type === 'ImportSpecifier' &&
259
- specifier.importKind !== 'type' &&
260
- ['defineConfig', 'defineVars', 'extendVars'].includes(
261
- specifier.imported.type === 'Identifier'
262
- ? specifier.imported.name
263
- : specifier.imported.value,
264
- )
265
- ) {
266
- const name =
267
- specifier.imported.type === 'Identifier'
268
- ? specifier.imported.name
269
- : specifier.imported.value
270
- if (name === 'defineConfig')
271
- factoryImports.set(specifier.start, 'create')
272
- else if (name === 'defineVars')
273
- factoryImports.set(specifier.start, 'define')
274
- else factoryImports.set(specifier.start, 'extend')
275
- }
276
- }
277
- }
278
-
279
- if (
280
- !imports.size &&
281
- !configImports.size &&
282
- !factoryImports.size &&
283
- !Object.keys(options.links ?? {}).length
284
- )
285
- return undefined
286
-
287
- const names = new Map<string, Call>()
288
- const aliasNames = new Map<string, Alias>()
289
- const exports: Record<string, Link> = Object.create(null)
290
-
291
- for (const node of program.body) {
292
- if (node.type !== 'ImportDeclaration' || node.importKind === 'type')
293
- continue
294
-
295
- for (const specifier of node.specifiers) {
296
- const link = options.links?.[specifier.local.name]
297
- if (
298
- !link ||
299
- link.kind === 'style-reference' ||
300
- link.kind === 'animation' ||
301
- link.kind === 'rule-reference' ||
302
- link.kind === 'variables'
303
- )
304
- continue
305
-
306
- const call = { ...link.call, start: -1, end: -1 }
307
-
308
- themes[call.name] = link.definition
309
-
310
- if (link.kind === 'config') {
311
- const imported = {
312
- ...link,
313
- call,
314
- members: Object.fromEntries(
315
- Object.entries(link.members ?? {}).map(([key, member]) => [
316
- key,
317
- { ...member, call: { ...member.call, start: -1, end: -1 } },
318
- ]),
319
- ),
320
- }
321
-
322
- configs.set(specifier.local.name, imported)
323
- configBindings.set(specifier.start, imported)
324
-
325
- for (const member of Object.values(link.members ?? {}))
326
- themes[member.call.name] = member.definition
327
- } else if (link.kind === 'theme') {
328
- definitions.set(specifier.start, call)
329
- names.set(specifier.local.name, call)
330
- } else {
331
- const alias = { ...call, destructured: false }
332
-
333
- aliasBindings.set(specifier.start, alias)
334
- aliasNames.set(specifier.local.name, alias)
335
- }
336
- }
337
- }
338
-
339
- const namespaces = new Set<string>()
340
- const configNamespaces = new Set<string>()
341
- const factoryFunctions = new Map<string, 'create' | 'define' | 'extend'>()
342
- const variableNamespaces = new Set<string>()
343
- for (const node of program.body)
344
- if (node.type === 'ImportDeclaration')
345
- for (const specifier of node.specifiers)
346
- if (variableImports.has(specifier.start))
347
- variableNamespaces.add(specifier.local.name)
348
-
349
- for (const node of program.body)
350
- if (node.type === 'ImportDeclaration')
351
- for (const specifier of node.specifiers)
352
- if (imports.has(specifier.start)) namespaces.add(specifier.local.name)
353
- else if (configImports.has(specifier.start))
354
- configNamespaces.add(specifier.local.name)
355
- else if (factoryImports.has(specifier.start))
356
- factoryFunctions.set(
357
- specifier.local.name,
358
- factoryImports.get(specifier.start)!,
359
- )
360
-
361
- function resolve(node: Ast.Node): Link | undefined {
362
- if (node.type === 'Identifier') {
363
- const config = configs.get(node.name)
364
- if (config) return config
365
-
366
- const call = names.get(node.name)
367
- if (call)
368
- return {
369
- binding: call.name,
370
- call,
371
- definition: themes[call.name]!,
372
- kind: 'theme',
373
- }
374
-
375
- return undefined
376
- }
377
-
378
- if (node.type !== 'MemberExpression' || node.optional) return undefined
379
-
380
- const path: string[] = []
381
- let root: Ast.Node = node
382
-
383
- while (root.type === 'MemberExpression') {
384
- const key = (() => {
385
- if (root.property.type === 'Identifier' && !root.computed) {
386
- return root.property.name
387
- }
388
-
389
- if (
390
- root.property.type === 'Literal' &&
391
- root.computed &&
392
- (typeof root.property.value === 'string' ||
393
- typeof root.property.value === 'number')
394
- ) {
395
- return String(root.property.value)
396
- }
397
-
398
- return undefined
399
- })()
400
- if (root.optional || key === undefined) return undefined
401
-
402
- path.unshift(key)
403
- root = root.object
404
- }
405
-
406
- const config =
407
- root.type === 'Identifier' ? configs.get(root.name) : undefined
408
-
409
- if (
410
- config &&
411
- !config.call.selection &&
412
- !config.call.initialization &&
413
- !config.call.root &&
414
- path.length === 1 &&
415
- ['themes', 'vars', 'script', 'appearance'].includes(path[0]!)
416
- ) {
417
- const key = path[0]!
418
- if (config.call.variableConfig && key === 'themes') return undefined
419
-
420
- if (key === 'script') scripts.add(config.call.name)
421
- if (key === 'appearance') appearances.add(config.call.name)
422
-
423
- if (key === 'themes' && !config.call.options?.themes) return undefined
424
- if (key === 'themes' || key === 'vars') selections.add(config.call.name)
425
-
426
- if (key === 'script' && !config.call.script)
427
- fail(
428
- 'This packed configuration does not provide script(); rebuild its library with initialization support.',
429
- node,
430
- )
431
-
432
- if (key === 'appearance' && !config.call.appearance)
433
- fail(
434
- 'This packed configuration does not provide appearance; rebuild its library with root control support.',
435
- node,
436
- )
437
-
438
- const members = Object.fromEntries(
439
- Object.entries(config.members ?? {}).flatMap(([name, member]) => {
440
- const parts = JSON.parse(name) as string[]
441
-
442
- return (key === 'themes' || key === 'vars') && parts[0] === 'themes'
443
- ? [[JSON.stringify(parts.slice(1)), member]]
444
- : []
445
- }),
446
- )
447
-
448
- return {
449
- ...config,
450
- members,
451
- binding: `${config.binding}:${key}`,
452
- call: {
453
- ...config.call,
454
- members: Object.fromEntries(
455
- Object.entries(members).map(([name, member]) => [
456
- name,
457
- member.call.name,
458
- ]),
459
- ),
460
- ...helper(key),
461
- type: `${config.call.type}['${key}']`,
462
- },
463
- }
464
- }
465
-
466
- return config?.members?.[JSON.stringify(path)]
467
- }
468
-
469
- /** Marks which configuration helper a destructured or member binding represents. */
470
- function helper(key: string) {
471
- if (key === 'script') return { initialization: true }
472
- if (key === 'appearance') return { root: true }
473
- return { selection: true }
474
- }
475
-
476
- type Derived = { name: string; vars: Vars.Definition }
477
-
478
- function readReference(
479
- node: Ast.Node,
480
- derived?: Derived,
481
- ): Token.Reference | undefined {
482
- if (node.type !== 'MemberExpression') return undefined
483
- const path: string[] = []
484
- let root: Ast.Node = node
485
- while (root.type === 'MemberExpression' && !root.optional) {
486
- const key =
487
- !root.computed && root.property.type === 'Identifier'
488
- ? root.property.name
489
- : root.property.type === 'Literal'
490
- ? String(root.property.value)
491
- : undefined
492
- if (key === undefined) return undefined
493
- path.unshift(key)
494
- root = root.object
495
- }
496
- if (root.type !== 'Identifier') return undefined
497
- const name = root.name
498
- let value: unknown = (() => {
499
- if (derived?.name === name) return derived.vars
500
-
501
- const call = names.get(name)
502
- if (call) {
503
- if (
504
- !call.variableSet &&
505
- !call.directVariables &&
506
- !['vars', 'tokens'].includes(path.shift()!)
507
- )
508
- return undefined
509
- return themes[call.name]?.tokens
510
- }
511
-
512
- // Config-bound vars read the configured variables, so they follow set scoping.
513
- const config = configs.get(name)
514
- if (
515
- !config?.call.variableConfig ||
516
- (!config.call.selection && path.shift() !== 'vars')
517
- )
518
- return undefined
519
- return themes[config.call.name]?.tokens
520
- })()
521
- if (value === undefined) return undefined
522
- for (const key of path)
523
- value =
524
- value && typeof value === 'object'
525
- ? Object.getOwnPropertyDescriptor(value, key)?.value
526
- : undefined
527
- return Token.is(value) ? value : undefined
528
- }
529
-
530
- function data(node: Ast.Node, derived?: Derived): unknown {
531
- const reference = readReference(node, derived)
532
- if (reference) {
533
- factoryReferences.add(node.start)
534
- return reference
535
- }
536
-
537
- if (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression')
538
- return data(node.expression, derived)
539
-
540
- if (node.type === 'CallExpression' && !node.optional) {
541
- const callee = node.callee
542
- if (
543
- callee.type === 'MemberExpression' &&
544
- !callee.computed &&
545
- !callee.optional &&
546
- callee.object.type === 'Identifier' &&
547
- variableNamespaces.has(callee.object.name) &&
548
- derived?.name !== callee.object.name &&
549
- callee.property.type === 'Identifier' &&
550
- callee.property.name === 'compose'
551
- ) {
552
- if (node.arguments.length !== 2)
553
- return fail(
554
- 'Vars.compose requires a literal domain and parts array.',
555
- node,
556
- )
557
- const group = data(node.arguments[0]!, derived)
558
- const parts = data(node.arguments[1]!, derived)
559
- if ((group !== 'color' && group !== 'spacing') || !Array.isArray(parts))
560
- return fail(
561
- 'Vars.compose requires a literal domain and parts array.',
562
- node,
563
- )
564
- factoryReferences.add(callee.start)
565
- return Vars.compose(group, parts)
566
- }
567
- }
568
-
569
- if (
570
- node.type === 'Literal' &&
571
- (typeof node.value === 'string' || typeof node.value === 'number')
572
- )
573
- return node.value
574
-
575
- if (
576
- node.type === 'UnaryExpression' &&
577
- (node.operator === '+' || node.operator === '-') &&
578
- node.argument.type === 'Literal' &&
579
- typeof node.argument.value === 'number'
580
- )
581
- return node.operator === '-' ? -node.argument.value : node.argument.value
582
-
583
- if (node.type === 'ArrayExpression')
584
- return node.elements.map((element) => {
585
- if (!element || element.type === 'SpreadElement')
586
- return fail('Theme arrays require dense literal elements.', node)
587
-
588
- return data(element, derived)
589
- })
590
-
591
- if (node.type !== 'ObjectExpression')
592
- return fail(
593
- 'Theme values must be literal data; expressions are not evaluated.',
594
- node,
595
- )
596
-
597
- const result: Record<string, unknown> = Object.create(null)
598
-
599
- for (const property of node.properties) {
600
- if (
601
- property.type !== 'Property' ||
602
- property.computed ||
603
- property.method ||
604
- property.shorthand ||
605
- property.kind !== 'init'
606
- )
607
- return fail(
608
- 'Theme data requires explicit properties without spreads, methods, or computed keys.',
609
- property,
610
- )
611
-
612
- const key = (() => {
613
- if (property.key.type === 'Identifier') {
614
- return property.key.name
615
- }
616
-
617
- if (
618
- property.key.type === 'Literal' &&
619
- (typeof property.key.value === 'string' ||
620
- typeof property.key.value === 'number')
621
- ) {
622
- return String(property.key.value)
623
- }
624
-
625
- return undefined
626
- })()
627
- if (key === undefined || Object.hasOwn(result, key))
628
- return fail('Theme data requires unique literal keys.', property)
629
-
630
- result[key] = data(property.value, derived)
631
- }
632
-
633
- return result
634
- }
635
-
636
- /** Reads a derived-variables callback as one parameter name and a literal body. */
637
- function derivation(argument: Ast.Node | undefined) {
638
- const callback = argument && Expression.unwrap(argument)
639
- if (
640
- callback?.type !== 'ArrowFunctionExpression' &&
641
- callback?.type !== 'FunctionExpression'
642
- )
643
- return undefined
644
-
645
- const parameter = callback.params[0]
646
- const body = (() => {
647
- if (callback.body?.type !== 'BlockStatement') return callback.body
648
- if (
649
- callback.body.body.length === 1 &&
650
- callback.body.body[0]?.type === 'ReturnStatement'
651
- )
652
- return callback.body.body[0].argument
653
- return undefined
654
- })()
655
- if (
656
- callback.async ||
657
- callback.generator ||
658
- callback.params.length !== 1 ||
659
- parameter?.type !== 'Identifier' ||
660
- !body
661
- )
662
- fail(
663
- 'Derived variables require one named parameter and a literal return value.',
664
- callback,
665
- )
666
-
667
- return { body, name: parameter.name }
668
- }
669
-
670
- /** Authored values of an extension, keeping base values at existing paths as `Vars.extend` types do. */
671
- function extendedValues(base: Theme.Definition, extension: Theme.Definition) {
672
- const metadata = extension[Token.definition]
673
- const known = base[Token.definition].values
674
- const tree: Record<string, unknown> = Object.create(null)
675
-
676
- for (const path of Object.keys(metadata.values)) {
677
- const parts = metadata.paths?.[path] ?? path.split('.')
678
- const source = Object.hasOwn(known, path) ? base : extension
679
- let target = tree
680
- let token: unknown = source.tokens
681
-
682
- for (const part of parts.slice(0, -1)) {
683
- target = (target[part] ??= Object.create(null)) as Record<
684
- string,
685
- unknown
686
- >
687
- token = (token as Record<string, unknown>)[part]
688
- }
689
-
690
- const name = parts.at(-1)!
691
- // Every metadata path has a reference in its own token tree.
692
- target[name] = (token as Record<string, Token.Reference>)[name]!.value
693
- }
694
-
695
- return tree
696
- }
697
-
698
- function fail(message: string, node: Pick<Ast.Node, 'end' | 'start'>): never {
699
- throw new InvalidError(message, node)
700
- }
701
-
702
- function type(node: Ast.Node): string {
703
- if (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression')
704
- return type(node.expression)
705
-
706
- if (node.type !== 'ObjectExpression') return Configurations.type(data(node))
707
-
708
- return `{${node.properties
709
- .map((property) => {
710
- if (property.type !== 'Property')
711
- return fail('Expected validated theme properties.', property)
712
-
713
- const key = (() => {
714
- if (property.key.type === 'Identifier') {
715
- return JSON.stringify(property.key.name)
716
- }
717
-
718
- if (property.key.type === 'Literal') {
719
- return JSON.stringify(property.key.value)
720
- }
721
-
722
- return fail('Expected a literal theme key.', property.key)
723
- })()
724
-
725
- return `readonly ${key}:${type(property.value)}`
726
- })
727
- .join(';')}}`
728
- }
729
-
730
- for (const statement of program.body) {
731
- const declaration =
732
- statement.type === 'ExportNamedDeclaration'
733
- ? statement.declaration
734
- : statement
735
- if (declaration?.type !== 'VariableDeclaration') continue
736
-
737
- for (const variable of declaration.declarations) {
738
- registerAlias({ declaration, statement, variable })
739
-
740
- const expression = variable.init
741
- if (expression?.type !== 'CallExpression' || expression.optional) continue
742
-
743
- const member = expression.callee
744
- const directFactory =
745
- member.type === 'Identifier'
746
- ? factoryFunctions.get(member.name)
747
- : undefined
748
- if (
749
- !directFactory &&
750
- (member.type !== 'MemberExpression' ||
751
- member.object.type !== 'Identifier' ||
752
- (!namespaces.has(member.object.name) &&
753
- !configNamespaces.has(member.object.name)) ||
754
- member.computed ||
755
- member.optional ||
756
- member.property.type !== 'Identifier' ||
757
- !(
758
- configNamespaces.has(member.object.name)
759
- ? ['create']
760
- : ['define', 'extend']
761
- ).includes(member.property.name))
762
- )
763
- continue
764
-
765
- const config =
766
- directFactory === 'create' ||
767
- (member.type === 'MemberExpression' &&
768
- member.object.type === 'Identifier' &&
769
- configNamespaces.has(member.object.name))
770
- const method =
771
- member.type === 'MemberExpression' &&
772
- member.property.type === 'Identifier'
773
- ? member.property.name
774
- : directFactory
775
- const variableSet =
776
- directFactory === 'define' ||
777
- directFactory === 'extend' ||
778
- (member.type === 'MemberExpression' &&
779
- member.object.type === 'Identifier' &&
780
- variableNamespaces.has(member.object.name))
781
-
782
- if (
783
- (statement.type === 'ExportNamedDeclaration' && !options.linked) ||
784
- declaration.kind !== 'const' ||
785
- (variable.id.type !== 'Identifier' &&
786
- !(config && variable.id.type === 'ObjectPattern'))
787
- )
788
- fail(
789
- 'Define local themes with a module-level const; exported themes require source linking.',
790
- variable,
791
- )
792
-
793
- const bindings = (() => {
794
- if (variable.id.type !== 'ObjectPattern') return []
795
-
796
- return variable.id.properties.map((property) => {
797
- if (
798
- property.type !== 'Property' ||
799
- property.computed ||
800
- property.key.type !== 'Identifier' ||
801
- property.value.type !== 'Identifier'
802
- )
803
- fail(
804
- 'Configuration destructuring requires named bindings without defaults, rest, or nested patterns.',
805
- property,
806
- )
807
-
808
- return { key: property.key.name, id: property.value }
809
- })
810
- })()
811
-
812
- const binding =
813
- variable.id.type === 'Identifier'
814
- ? variable.id.name
815
- : bindings[0]?.id.name
816
-
817
- if (!binding)
818
- fail('Configuration destructuring requires a binding.', variable)
819
-
820
- let name = `${options.namespace}-${binding}`
821
- if (!config && method === 'define') {
822
- const argument = expression.arguments[1]
823
- const callback = argument && Expression.unwrap(argument)
824
- const id = Identifiers.explicit(
825
- expression,
826
- callback?.type === 'ArrowFunctionExpression' ||
827
- callback?.type === 'FunctionExpression'
828
- ? 2
829
- : 1,
830
- )
831
- if (id !== undefined) name = Identity.requireId(id, 'Vars.define')
832
- }
833
- if (!config && method === 'extend') {
834
- const argument = expression.arguments[2]
835
- const callback = argument && Expression.unwrap(argument)
836
- const id = Identifiers.explicit(
837
- expression,
838
- callback?.type === 'ArrowFunctionExpression' ||
839
- callback?.type === 'FunctionExpression'
840
- ? 3
841
- : 2,
842
- )
843
- if (id !== undefined) name = Identity.requireId(id, 'Vars.extend')
844
- }
845
-
846
- if (config) {
847
- const nativeProvider =
848
- member.type === 'Identifier' && nativeFactories.has(member.name)
849
- if (nativeProvider && !options.native)
850
- fail(
851
- 'Native defineConfig requires a native compilation target.',
852
- expression,
853
- )
854
-
855
- try {
856
- const link = Configurations.collect({
857
- data,
858
- expression,
859
- name,
860
- nativeProvider,
861
- resolve: (node) => {
862
- const link = resolve(node)
863
-
864
- if (link) factoryReferences.add(node.start)
865
-
866
- return link
867
- },
868
- })
869
-
870
- if (variable.id.type === 'Identifier') {
871
- configs.set(variable.id.name, link)
872
- configBindings.set(variable.id.start, link)
873
-
874
- if (statement.type === 'ExportNamedDeclaration')
875
- exports[variable.id.name] = link
876
- }
877
-
878
- calls.push(link.call)
879
- factories.add(expression.start)
880
-
881
- for (const member of Object.values(link.members ?? {}))
882
- themes[member.call.name] = member.definition
883
-
884
- themes[link.call.name] = link.definition
885
-
886
- for (const { key, id } of bindings) {
887
- if (key === 'Provider' && link.call.nativeProvider) continue
888
-
889
- if (
890
- (key === 'style' || key === 'variants') &&
891
- !link.call.selection &&
892
- !link.call.initialization
893
- ) {
894
- const alias = {
895
- ...link.call,
896
- recipe: key === 'variants',
897
- destructured: false,
898
- }
899
-
900
- aliasBindings.set(id.start, alias)
901
- aliasNames.set(id.name, alias)
902
-
903
- if (statement.type === 'ExportNamedDeclaration')
904
- exports[id.name] = {
905
- ...link,
906
- binding: `${options.namespace}-${id.name}`,
907
- call: alias,
908
- kind: 'style',
909
- }
910
-
911
- continue
912
- }
913
-
914
- if (
915
- !link.call.selection &&
916
- !link.call.initialization &&
917
- !link.call.root &&
918
- (key === 'script' ||
919
- key === 'appearance' ||
920
- (key === 'themes' && link.call.options?.themes) ||
921
- (key === 'vars' && link.call.variableConfig))
922
- ) {
923
- if (
924
- (key === 'script' && !link.call.script) ||
925
- (key === 'appearance' && !link.call.appearance) ||
926
- link.call.selection ||
927
- link.call.initialization
928
- )
929
- fail(
930
- 'This configuration helper is not available on the linked contract.',
931
- id,
932
- )
933
-
934
- if (key === 'script') scripts.add(link.call.name)
935
- if (key === 'appearance') appearances.add(link.call.name)
936
- if (key === 'themes' || key === 'vars')
937
- selections.add(link.call.name)
938
-
939
- const members = Object.fromEntries(
940
- Object.entries(link.members ?? {}).flatMap(
941
- ([pathKey, member]) => {
942
- const path = JSON.parse(pathKey) as string[]
943
-
944
- return (key === 'themes' || key === 'vars') &&
945
- (path[0] === 'themes' || path[0] === 'vars')
946
- ? [[JSON.stringify(path.slice(1)), member]]
947
- : []
948
- },
949
- ),
950
- )
951
-
952
- const selection = {
953
- ...link,
954
- members,
955
- call: {
956
- ...link.call,
957
- members: Object.fromEntries(
958
- Object.entries(members).map(([key, member]) => [
959
- key,
960
- member.call.name,
961
- ]),
962
- ),
963
- ...helper(key),
964
- type: `${link.call.type}['${key}']`,
965
- },
966
- }
967
-
968
- configs.set(id.name, selection)
969
- configBindings.set(id.start, selection)
970
-
971
- if (statement.type === 'ExportNamedDeclaration')
972
- exports[id.name] = selection
973
-
974
- continue
975
- }
976
-
977
- if (link.call.variableConfig && ['theme', 'themes'].includes(key))
978
- fail('Use vars for references and scope selection.', id)
979
-
980
- const member = link.members?.[JSON.stringify([key])]
981
-
982
- if (!member)
983
- fail(
984
- 'Destructure only style and the configured single theme; other helpers remain unsupported.',
985
- id,
986
- )
987
-
988
- definitions.set(id.start, member.call)
989
- names.set(id.name, member.call)
990
-
991
- if (statement.type === 'ExportNamedDeclaration')
992
- exports[id.name] = member
993
- }
994
- } catch (error) {
995
- if (
996
- !(error instanceof Config.InvalidError) &&
997
- !(error instanceof Vars.InvalidError)
998
- )
999
- throw error
1000
-
1001
- fail(error.message, expression)
1002
- }
1003
-
1004
- continue
1005
- }
1006
-
1007
- let definition: Theme.Definition
1008
- let tokenType: string
1009
- let output: Call['output']
1010
-
1011
- try {
1012
- if (method === 'define') {
1013
- if (
1014
- expression.arguments.length < 1 ||
1015
- expression.arguments.length > 3
1016
- )
1017
- fail(
1018
- 'Vars.define requires one literal variable object.',
1019
- expression,
1020
- )
1021
-
1022
- let input = data(expression.arguments[0]!)
1023
-
1024
- tokenType = type(expression.arguments[0]!)
1025
-
1026
- const derive = variableSet
1027
- ? derivation(expression.arguments[1])
1028
- : undefined
1029
- if (derive) {
1030
- const base = VariableSets.build(
1031
- input,
1032
- Object.freeze({ variableSet: true, [Token.identity]: name }),
1033
- )
1034
- input = VariableSets.merge(
1035
- input,
1036
- data(derive.body, { name: derive.name, vars: base }),
1037
- )
1038
- tokenType = Configurations.type(input)
1039
- } else if (expression.arguments.length > 2)
1040
- fail(
1041
- 'Vars.define accepts a third argument only with a derived callback.',
1042
- expression,
1043
- )
1044
-
1045
- const original = variableSet
1046
- ? VariableSets.theme(
1047
- VariableSets.build(
1048
- input,
1049
- Object.freeze({ variableSet: true, [Token.identity]: name }),
1050
- ),
1051
- )
1052
- : Theme.define(input as Theme.Tokens)
1053
-
1054
- definition = Token.bind(
1055
- original,
1056
- Object.freeze({
1057
- ...original[Token.definition].contract,
1058
- [Token.identity]: name,
1059
- }),
1060
- )
1061
- } else {
1062
- const base = expression.arguments[0]
1063
- const parent = base ? resolve(base)?.call : undefined
1064
- const derive = variableSet
1065
- ? derivation(expression.arguments[2])
1066
- : undefined
1067
-
1068
- const arity = derive ? 3 : 2
1069
- // A trailing options object names a new set over the base's variables.
1070
- const id =
1071
- expression.arguments.length === arity + 1
1072
- ? Identifiers.explicit(expression, arity)
1073
- : undefined
1074
- const named = id !== undefined
1075
- if (
1076
- (expression.arguments.length !== arity && !named) ||
1077
- !parent
1078
- )
1079
- fail(
1080
- 'Vars.extend requires a preceding variable set and literal overrides.',
1081
- expression,
1082
- )
1083
-
1084
- factoryReferences.add(base!.start)
1085
- tokenType = parent.tokenType
1086
- output = parent.output
1087
-
1088
- if (variableSet) {
1089
- const theme = themes[parent.name]!
1090
- const original = VariableSets.from(theme[Token.definition])
1091
- const extend = Vars.extend as (
1092
- variables: Vars.Definition,
1093
- values: Vars.Values,
1094
- derive: (vars: Vars.References<Vars.Values>) => Vars.Values,
1095
- options: { readonly id?: string | undefined },
1096
- ) => Vars.Definition
1097
- const extended = extend(
1098
- original,
1099
- data(expression.arguments[1]!) as Vars.Values,
1100
- (vars) =>
1101
- derive
1102
- ? (data(derive.body, {
1103
- name: derive.name,
1104
- vars: vars as Vars.Definition,
1105
- }) as Vars.Values)
1106
- : {},
1107
- { id },
1108
- )
1109
- definition = named
1110
- ? Token.bind(
1111
- VariableSets.theme(extended),
1112
- Object.freeze({
1113
- ...extended[Token.definition].contract,
1114
- [Token.identity]: name,
1115
- }),
1116
- )
1117
- : VariableSets.theme(extended)
1118
-
1119
- const metadata = definition[Token.definition]
1120
- // Additions grow the token contract; overridden leaves keep their base types, as in `Vars.extend`.
1121
- if (
1122
- named ||
1123
- Object.keys(metadata.values).length !==
1124
- Object.keys(theme[Token.definition].values).length ||
1125
- JSON.stringify(metadata.queries) !==
1126
- JSON.stringify(theme[Token.definition].queries)
1127
- )
1128
- tokenType = Configurations.type({
1129
- ...extendedValues(theme, definition),
1130
- ...metadata.queries,
1131
- })
1132
- } else
1133
- definition = Theme.extend(
1134
- themes[parent.name]!,
1135
- data(expression.arguments[1]!) as Theme.Overrides<Theme.Tokens>,
1136
- )
1137
-
1138
- // Extensions share their base identity, so the binding keeps sibling sets distinct.
1139
- if (
1140
- !named &&
1141
- definition[Token.definition].contract[Token.identity]?.startsWith(
1142
- 'id-',
1143
- )
1144
- )
1145
- name = `${definition.className.slice('z-theme-'.length)}-${binding}`
1146
- }
1147
- } catch (error) {
1148
- if (error instanceof InvalidError) throw error
1149
- if (
1150
- !(error instanceof Theme.InvalidError) &&
1151
- !(error instanceof Vars.InvalidError)
1152
- )
1153
- throw error
1154
-
1155
- fail(error.message, expression)
1156
- }
1157
-
1158
- const call = Object.freeze({
1159
- ...(variableSet
1160
- ? {
1161
- variableSet: true,
1162
- directVariables: true,
1163
- type: `import('zyzz').Vars.Definition<${tokenType}>`,
1164
- }
1165
- : {}),
1166
- ...(output ? { output } : {}),
1167
- end: expression.end,
1168
- name,
1169
- start: expression.start,
1170
- tokenType,
1171
- ...(definition[Token.definition].contract.shorthands ||
1172
- output === 'html'
1173
- ? {
1174
- type: `import('zyzz').Config.create.ReturnType<{theme:${tokenType};${output === 'html' ? "output:'html';" : ''}shorthands:${Configurations.type(definition[Token.definition].contract.shorthands ?? {})}}>['theme']`,
1175
- }
1176
- : {}),
1177
- })
1178
-
1179
- definition = Token.bind(
1180
- definition,
1181
- definition[Token.definition].contract,
1182
- binding,
1183
- )
1184
- calls.push(call)
1185
- definitions.set(variable.id.start, call)
1186
- factories.add(expression.start)
1187
- names.set(binding, call)
1188
- themes[name] = definition
1189
-
1190
- if (statement.type === 'ExportNamedDeclaration')
1191
- exports[binding] = {
1192
- binding: name,
1193
- call,
1194
- definition,
1195
- kind: 'theme',
1196
- }
1197
- }
1198
- }
1199
-
1200
- function registerAlias(input: {
1201
- declaration: Ast.VariableDeclaration
1202
- statement: Ast.Node
1203
- variable: Ast.VariableDeclarator
1204
- }) {
1205
- const { declaration, statement, variable } = input
1206
- const expression = variable.init
1207
- if (!expression) return
1208
-
1209
- const linked = resolve(expression)
1210
-
1211
- if (linked?.kind === 'config' && variable.id.type === 'ObjectPattern') {
1212
- if (statement.type === 'ExportNamedDeclaration' && !options.linked)
1213
- fail(
1214
- 'Exported configuration destructuring requires source linking.',
1215
- variable,
1216
- )
1217
-
1218
- if (declaration.kind !== 'const')
1219
- fail('Configuration destructuring requires const bindings.', variable)
1220
-
1221
- const link = linked
1222
-
1223
- const bindings = variable.id.properties.map((property) => {
1224
- if (
1225
- property.type !== 'Property' ||
1226
- property.computed ||
1227
- property.key.type !== 'Identifier' ||
1228
- property.value.type !== 'Identifier'
1229
- )
1230
- return fail(
1231
- 'Configuration destructuring requires named bindings without defaults or rest.',
1232
- property,
1233
- )
1234
-
1235
- return { key: property.key.name, id: property.value }
1236
- })
1237
-
1238
- aliasReferences.add(expression.start)
1239
- aliases.push({
1240
- ...link.call,
1241
- start: expression.start,
1242
- end: expression.end,
1243
- destructured: false,
1244
- retained: true,
1245
- })
1246
-
1247
- for (const { key, id } of bindings) {
1248
- if (
1249
- key === 'Provider' &&
1250
- link.call.nativeProvider &&
1251
- !link.call.initialization &&
1252
- !link.call.root &&
1253
- !link.call.selection
1254
- )
1255
- continue
1256
-
1257
- if (
1258
- (key === 'style' || key === 'variants') &&
1259
- !link.call.selection &&
1260
- !link.call.initialization
1261
- ) {
1262
- const alias = {
1263
- ...link.call,
1264
- recipe: key === 'variants',
1265
- destructured: false,
1266
- }
1267
-
1268
- aliasBindings.set(id.start, alias)
1269
- aliasNames.set(id.name, alias)
1270
-
1271
- if (statement.type === 'ExportNamedDeclaration')
1272
- exports[id.name] = {
1273
- ...link,
1274
- binding: `${options.namespace}-${id.name}`,
1275
- call: alias,
1276
- kind: 'style',
1277
- }
1278
-
1279
- continue
1280
- }
1281
-
1282
- if (
1283
- !link.call.selection &&
1284
- !link.call.initialization &&
1285
- !link.call.root &&
1286
- (key === 'script' ||
1287
- key === 'appearance' ||
1288
- (key === 'themes' && link.call.options?.themes) ||
1289
- (key === 'vars' && link.call.variableConfig))
1290
- ) {
1291
- if (
1292
- (key === 'script' && !link.call.script) ||
1293
- (key === 'appearance' && !link.call.appearance) ||
1294
- link.call.selection ||
1295
- link.call.initialization
1296
- )
1297
- fail(
1298
- 'This configuration helper is not available on the linked contract.',
1299
- id,
1300
- )
1301
-
1302
- if (key === 'script') scripts.add(link.call.name)
1303
- if (key === 'appearance') appearances.add(link.call.name)
1304
- if (key === 'themes' || key === 'vars') selections.add(link.call.name)
1305
-
1306
- const members = Object.fromEntries(
1307
- Object.entries(link.members ?? {}).flatMap(([pathKey, member]) => {
1308
- const path = JSON.parse(pathKey) as string[]
1309
-
1310
- return (key === 'themes' || key === 'vars') &&
1311
- (path[0] === 'themes' || path[0] === 'vars')
1312
- ? [[JSON.stringify(path.slice(1)), member]]
1313
- : []
1314
- }),
1315
- )
1316
-
1317
- const selection = {
1318
- ...link,
1319
- members,
1320
- call: {
1321
- ...link.call,
1322
- members: Object.fromEntries(
1323
- Object.entries(members).map(([key, member]) => [
1324
- key,
1325
- member.call.name,
1326
- ]),
1327
- ),
1328
- ...helper(key),
1329
- type: `${link.call.type}['${key}']`,
1330
- },
1331
- }
1332
-
1333
- configs.set(id.name, selection)
1334
- configBindings.set(id.start, selection)
1335
-
1336
- if (statement.type === 'ExportNamedDeclaration')
1337
- exports[id.name] = selection
1338
-
1339
- continue
1340
- }
1341
-
1342
- if (link.call.variableConfig && ['theme', 'themes'].includes(key))
1343
- fail('Use vars for references and scope selection.', id)
1344
-
1345
- const member = link.members?.[JSON.stringify([key])]
1346
-
1347
- if (!member)
1348
- fail(
1349
- 'Destructure only style and the configured single theme; other helpers remain unsupported.',
1350
- id,
1351
- )
1352
-
1353
- definitions.set(id.start, member.call)
1354
- names.set(id.name, member.call)
1355
-
1356
- if (statement.type === 'ExportNamedDeclaration')
1357
- exports[id.name] = member
1358
- }
1359
-
1360
- return
1361
- }
1362
-
1363
- if (linked && variable.id.type === 'Identifier') {
1364
- if (expression.start < linked.call.end)
1365
- fail('Authoring aliases must follow their definition.', expression)
1366
-
1367
- if (
1368
- declaration.kind !== 'const' ||
1369
- (statement.type === 'ExportNamedDeclaration' && !options.linked)
1370
- )
1371
- fail('Authoring aliases require module-level const bindings.', variable)
1372
-
1373
- if (linked.kind === 'config') {
1374
- configs.set(variable.id.name, linked)
1375
- configBindings.set(variable.id.start, linked)
1376
- } else {
1377
- names.set(variable.id.name, linked.call)
1378
- definitions.set(variable.id.start, linked.call)
1379
- }
1380
-
1381
- aliases.push({
1382
- ...linked.call,
1383
- start: expression.start,
1384
- end: expression.end,
1385
- destructured: false,
1386
- retained: true,
1387
- })
1388
- aliasReferences.add(expression.start)
1389
-
1390
- if (statement.type === 'ExportNamedDeclaration')
1391
- exports[variable.id.name] = linked
1392
-
1393
- return
1394
- }
1395
-
1396
- const member = (() => {
1397
- if (
1398
- expression.type === 'MemberExpression' &&
1399
- !expression.computed &&
1400
- !expression.optional &&
1401
- expression.property.type === 'Identifier' &&
1402
- ['style', 'variants'].includes(expression.property.name)
1403
- ) {
1404
- return expression.object
1405
- }
1406
-
1407
- return undefined
1408
- })()
1409
-
1410
- const destructured =
1411
- variable.id.type === 'ObjectPattern' && expression.type === 'Identifier'
1412
- const source =
1413
- member ?? (expression.type === 'Identifier' ? expression : undefined)
1414
- if (!source) return
1415
-
1416
- const theme = (() => {
1417
- if (member || destructured) {
1418
- return resolve(source)?.call
1419
- }
1420
-
1421
- if (source.type === 'Identifier') {
1422
- return aliasNames.get(source.name)
1423
- }
1424
-
1425
- return undefined
1426
- })()
1427
- if (!theme) return
1428
-
1429
- const bindings = (() => {
1430
- if (destructured && variable.id.type === 'ObjectPattern') {
1431
- if (!variable.id.properties.length)
1432
- fail(
1433
- 'Theme destructuring requires an authoring binding.',
1434
- variable.id,
1435
- )
1436
-
1437
- return variable.id.properties.map((property) => {
1438
- if (
1439
- property.type !== 'Property' ||
1440
- property.computed ||
1441
- property.key.type !== 'Identifier' ||
1442
- (property.key.name !== 'style' &&
1443
- property.key.name !== 'variants') ||
1444
- property.value.type !== 'Identifier'
1445
- )
1446
- fail(
1447
- 'Destructure only style or variants into const bindings without defaults or rest properties.',
1448
- property,
1449
- )
1450
-
1451
- return { id: property.value, member: property.key.name } as const
1452
- })
1453
- }
1454
-
1455
- if (variable.id.type !== 'Identifier')
1456
- fail('Theme authoring aliases require named const bindings.', variable)
1457
-
1458
- const recipe =
1459
- expression.type === 'MemberExpression' &&
1460
- expression.property.type === 'Identifier'
1461
- ? expression.property.name === 'variants'
1462
- : theme.recipe
1463
- return [
1464
- {
1465
- id: variable.id,
1466
- member: recipe ? ('variants' as const) : ('style' as const),
1467
- },
1468
- ]
1469
- })()
1470
-
1471
- if (
1472
- declaration.kind !== 'const' ||
1473
- (statement.type === 'ExportNamedDeclaration' && !options.linked)
1474
- )
1475
- fail(
1476
- 'Theme style aliases require a local module-level const binding.',
1477
- variable,
1478
- )
1479
-
1480
- if (expression.start < theme.end)
1481
- fail('Theme style aliases must follow their definition.', expression)
1482
-
1483
- for (const [index, { id, member }] of bindings.entries()) {
1484
- const alias = Object.freeze({
1485
- recipe: member === 'variants',
1486
- destructured,
1487
- end: expression.end,
1488
- name: theme.name,
1489
- start: expression.start,
1490
- tokenType: theme.tokenType,
1491
- type: theme.type,
1492
- options: theme.options,
1493
- variableConfig: theme.variableConfig,
1494
- variableMappings: theme.variableMappings,
1495
- output: theme.output,
1496
- })
1497
-
1498
- // Each local/exported name keeps its own callable identity, while the
1499
- // shared initializer is rewritten once with every destructured member.
1500
- if (index === 0)
1501
- aliases.push({
1502
- ...alias,
1503
- bindings: bindings.map(({ member }) => member),
1504
- })
1505
- aliasBindings.set(id.start, alias)
1506
- aliasNames.set(id.name, alias)
1507
-
1508
- if (statement.type === 'ExportNamedDeclaration')
1509
- exports[id.name] = {
1510
- binding: `${options.namespace}-${id.name}`,
1511
- call: alias,
1512
- definition: themes[alias.name]!,
1513
- kind: 'style',
1514
- }
1515
- }
1516
- aliasReferences.add(source.start)
1517
- }
1518
-
1519
- const exportReferences = new Set<number>()
1520
-
1521
- if (options.linked)
1522
- for (const statement of program.body) {
1523
- if (
1524
- statement.type !== 'ExportNamedDeclaration' ||
1525
- statement.source ||
1526
- statement.exportKind === 'type'
1527
- )
1528
- continue
1529
-
1530
- for (const specifier of statement.specifiers) {
1531
- if (specifier.exportKind === 'type') continue
1532
-
1533
- const name =
1534
- specifier.local.type === 'Identifier'
1535
- ? specifier.local.name
1536
- : specifier.local.value
1537
- const call =
1538
- configs.get(name)?.call ?? names.get(name) ?? aliasNames.get(name)
1539
- if (!call) continue
1540
-
1541
- const exported =
1542
- specifier.exported.type === 'Identifier'
1543
- ? specifier.exported.name
1544
- : specifier.exported.value
1545
-
1546
- exports[exported] = configs.get(name) ??
1547
- options.links?.[name] ?? {
1548
- binding: `${options.namespace}-${name}`,
1549
- call,
1550
- definition: themes[call.name]!,
1551
- kind: names.has(name) ? 'theme' : 'style',
1552
- }
1553
- exportReferences.add(specifier.local.start)
1554
- }
1555
- }
1556
-
1557
- function reference(
1558
- node: Extract<Ast.Node, { type: 'Identifier' | 'JSXIdentifier' }>,
1559
- parent: Ast.Node,
1560
- ancestors: readonly Ast.Node[],
1561
- binding: Walker.ScopeTrackerNode | null,
1562
- lookup: (name: string) => Walker.ScopeTrackerNode | null,
1563
- ): boolean {
1564
- const grandparent = ancestors.at(-3)
1565
-
1566
- if (
1567
- binding?.type === 'Import' &&
1568
- (imports.has(binding.node.start) ||
1569
- configImports.has(binding.node.start) ||
1570
- factoryImports.has(binding.node.start))
1571
- ) {
1572
- if (
1573
- factoryImports.has(binding.node.start) &&
1574
- parent.type === 'CallExpression' &&
1575
- factories.has(parent.start)
1576
- )
1577
- return true
1578
-
1579
- if (
1580
- parent.type === 'MemberExpression' &&
1581
- grandparent?.type === 'CallExpression' &&
1582
- (factories.has(grandparent.start) ||
1583
- factoryReferences.has(parent.start))
1584
- )
1585
- return true
1586
-
1587
- fail(
1588
- 'Theme factories require direct module-level const declarations; aliases and indirect references require source linking.',
1589
- node,
1590
- )
1591
- }
1592
-
1593
- const alias =
1594
- binding?.type === 'Variable' || binding?.type === 'Import'
1595
- ? aliasBindings.get(binding.node.start)
1596
- : undefined
1597
-
1598
- if (alias) {
1599
- if (
1600
- node.start === binding!.node.start ||
1601
- exportReferences.has(node.start)
1602
- )
1603
- return true
1604
-
1605
- if (node.start < alias.end)
1606
- fail('Theme style alias references must follow their definition.', node)
1607
-
1608
- if (aliasReferences.has(node.start)) return true
1609
-
1610
- if (
1611
- parent.type !== 'CallExpression' ||
1612
- parent.callee !== node ||
1613
- parent.optional
1614
- )
1615
- fail(
1616
- 'Theme style aliases support direct calls only; exporting or escaping them requires source linking.',
1617
- node,
1618
- )
1619
-
1620
- styles.set(parent.start, {
1621
- call: parent,
1622
- recipe: alias.recipe,
1623
- theme: themes[alias.name]!,
1624
- output:
1625
- alias.output ??
1626
- (alias.options?.output === 'html' ? 'html' : undefined),
1627
- })
1628
-
1629
- return true
1630
- }
1631
-
1632
- const config =
1633
- binding?.type === 'Variable' || binding?.type === 'Import'
1634
- ? configBindings.get(binding.node.start)
1635
- : undefined
1636
-
1637
- if (config) {
1638
- if (node.start === binding!.node.start) return true
1639
-
1640
- if (exportReferences.has(node.start) || aliasReferences.has(node.start))
1641
- return true
1642
-
1643
- if (
1644
- node.start < config.call.end &&
1645
- config.call.start >= 0 &&
1646
- binding?.type !== 'Import'
1647
- )
1648
- fail('Configuration references must follow their definition.', node)
1649
-
1650
- if (
1651
- config.call.variableConfig &&
1652
- config.call.selection &&
1653
- readVars(node, parent, config, lookup)
1654
- )
1655
- return true
1656
-
1657
- // Root controls are an ordinary runtime object; any read or call is valid.
1658
- if (config.call.root) {
1659
- appearances.add(config.call.name)
1660
-
1661
- return true
1662
- }
1663
-
1664
- if (
1665
- (config.call.selection || config.call.initialization) &&
1666
- parent.type === 'CallExpression' &&
1667
- parent.callee === node &&
1668
- !parent.optional
1669
- ) {
1670
- if (config.call.selection && config.call.catalogOnly)
1671
- fail(
1672
- 'This legacy catalog is not callable; rebuild its library.',
1673
- node,
1674
- )
1675
-
1676
- if (config.call.selection) {
1677
- selections.add(config.call.name)
1678
- selectionUses.add(config.call.name)
1679
- scopeApplications.set(parent.start, {
1680
- end: parent.end,
1681
- output: config.call.options?.output === 'html' ? 'html' : undefined,
1682
- })
1683
- }
1684
- if (config.call.initialization) scripts.add(config.call.name)
1685
-
1686
- return true
1687
- }
1688
-
1689
- let target: Ast.Node = node
1690
- const path: string[] = []
1691
-
1692
- for (let index = ancestors.length - 2; index >= 0; index--) {
1693
- const member = ancestors[index]!
1694
-
1695
- if (
1696
- member.type !== 'MemberExpression' ||
1697
- member.object !== target ||
1698
- member.optional
1699
- )
1700
- break
1701
-
1702
- const key = (() => {
1703
- if (member.property.type === 'Identifier' && !member.computed) {
1704
- return member.property.name
1705
- }
1706
-
1707
- if (
1708
- member.property.type === 'Literal' &&
1709
- member.computed &&
1710
- (typeof member.property.value === 'string' ||
1711
- typeof member.property.value === 'number')
1712
- ) {
1713
- return String(member.property.value)
1714
- }
1715
-
1716
- return undefined
1717
- })()
1718
-
1719
- if (key === undefined) break
1720
-
1721
- path.push(key)
1722
- target = member
1723
-
1724
- if (
1725
- path.length === 1 &&
1726
- path[0] === 'Provider' &&
1727
- config.call.nativeProvider &&
1728
- !config.call.initialization &&
1729
- !config.call.root &&
1730
- !config.call.selection
1731
- )
1732
- return true
1733
-
1734
- if (
1735
- config.call.variableConfig &&
1736
- path.length === 1 &&
1737
- path[0] === 'vars' &&
1738
- readVars(target, ancestors[index - 1]!, config, lookup)
1739
- )
1740
- return true
1741
-
1742
- if (
1743
- aliasReferences.has(target.start) ||
1744
- factoryReferences.has(target.start)
1745
- )
1746
- return true
1747
-
1748
- if (
1749
- path.length === 1 &&
1750
- path[0] === 'appearance' &&
1751
- !config.call.selection &&
1752
- !config.call.initialization
1753
- ) {
1754
- if (!config.call.appearance)
1755
- fail(
1756
- 'This packed configuration does not provide appearance; rebuild its library with root control support.',
1757
- target,
1758
- )
1759
-
1760
- appearances.add(config.call.name)
1761
-
1762
- return true
1763
- }
1764
-
1765
- if (
1766
- path.length === 1 &&
1767
- !config.call.selection &&
1768
- !config.call.initialization &&
1769
- ['script', 'themes', 'vars'].includes(path[0]!) &&
1770
- ancestors[index - 1]?.type === 'CallExpression' &&
1771
- (ancestors[index - 1] as Ast.CallExpression).callee === target &&
1772
- !(ancestors[index - 1] as Ast.CallExpression).optional
1773
- ) {
1774
- if (path[0] === 'vars' && !config.call.variableConfig)
1775
- fail('This configuration has no vars.', target)
1776
- if (path[0] === 'themes' && !config.call.options?.themes)
1777
- fail('Theme selection requires a named catalog.', target)
1778
-
1779
- if (
1780
- (path[0] === 'themes' || path[0] === 'vars') &&
1781
- config.call.catalogOnly
1782
- )
1783
- fail(
1784
- 'This legacy catalog is not callable; rebuild its library.',
1785
- target,
1786
- )
1787
-
1788
- if (path[0] === 'script') {
1789
- if (!config.call.script)
1790
- fail(
1791
- 'This packed configuration does not provide script(); rebuild its library with initialization support.',
1792
- target,
1793
- )
1794
-
1795
- scripts.add(config.call.name)
1796
- }
1797
-
1798
- if (path[0] === 'themes' || path[0] === 'vars') {
1799
- selections.add(config.call.name)
1800
- selectionUses.add(config.call.name)
1801
- const application = ancestors[index - 1]!
1802
- scopeApplications.set(application.start, {
1803
- end: application.end,
1804
- output:
1805
- config.call.options?.output === 'html' ? 'html' : undefined,
1806
- })
1807
- }
1808
-
1809
- return true
1810
- }
1811
-
1812
- if (
1813
- path.length === 1 &&
1814
- (path[0] === 'style' || path[0] === 'variants')
1815
- ) {
1816
- const call = ancestors[index - 1]
1817
-
1818
- if (
1819
- call?.type !== 'CallExpression' ||
1820
- call.callee !== target ||
1821
- call.optional
1822
- )
1823
- break
1824
-
1825
- styles.set(call.start, {
1826
- call,
1827
- recipe: path[0] === 'variants',
1828
- theme: config.definition,
1829
- output: config.call.options?.output === 'html' ? 'html' : undefined,
1830
- })
1831
-
1832
- return true
1833
- }
1834
-
1835
- if (
1836
- config.call.variableConfig &&
1837
- ['theme', 'themes'].includes(path[0]!)
1838
- )
1839
- fail('Use vars for references and scope selection.', target)
1840
- const linked =
1841
- config.call.variableConfig && config.call.selection
1842
- ? undefined
1843
- : config.members?.[JSON.stringify(path)]
1844
- if (linked)
1845
- return themeReference(
1846
- target,
1847
- ancestors[index - 1]!,
1848
- ancestors.slice(0, index + 1),
1849
- linked.call,
1850
- )
1851
- }
1852
-
1853
- if (config.call.selection && config.call.variableConfig && path.length)
1854
- return themeReference(node, parent, ancestors, {
1855
- ...config.call,
1856
- directVariables: true,
1857
- })
1858
-
1859
- // A compiled selector is an ordinary runtime function, so passing or storing it is safe.
1860
- if (config.call.selection && !config.call.catalogOnly && !path.length) {
1861
- selections.add(config.call.name)
1862
- selectionUses.add(config.call.name)
1863
-
1864
- return true
1865
- }
1866
-
1867
- fail(
1868
- 'Use direct configuration style calls or static theme members; configurations cannot escape or be mutated.',
1869
- node,
1870
- )
1871
- }
1872
-
1873
- const theme =
1874
- binding?.type === 'Variable' || binding?.type === 'Import'
1875
- ? definitions.get(binding.node.start)
1876
- : undefined
1877
- if (!theme) return false
1878
- if (node.start === binding!.node.start) return true
1879
-
1880
- if (
1881
- theme.variableSet &&
1882
- readVars(
1883
- node,
1884
- parent,
1885
- {
1886
- call: theme,
1887
- definition: themes[theme.name]!,
1888
- },
1889
- lookup,
1890
- )
1891
- )
1892
- return true
1893
-
1894
- return themeReference(node, parent, ancestors, theme)
1895
- }
1896
-
1897
- function readVars(
1898
- node: Ast.Node,
1899
- parent: Ast.Node,
1900
- link: Pick<Link, 'call' | 'definition' | 'members'>,
1901
- lookup: (name: string) => Walker.ScopeTrackerNode | null,
1902
- ): boolean {
1903
- if (
1904
- !options.native ||
1905
- parent.type !== 'CallExpression' ||
1906
- parent.optional ||
1907
- parent.arguments[0] !== node
1908
- )
1909
- return false
1910
-
1911
- const callee = parent.callee
1912
- const name =
1913
- callee.type === 'Identifier'
1914
- ? callee.name
1915
- : callee.type === 'MemberExpression' &&
1916
- !callee.computed &&
1917
- !callee.optional &&
1918
- callee.object.type === 'Identifier' &&
1919
- callee.property.type === 'Identifier' &&
1920
- ['useAnimatedVars', 'useVars'].includes(callee.property.name)
1921
- ? callee.object.name
1922
- : undefined
1923
- const binding = name === undefined ? undefined : lookup(name)
1924
- if (
1925
- binding?.type !== 'Import' ||
1926
- ![
1927
- 'zyzz/react-native',
1928
- 'zyzz/react-native/reanimated',
1929
- 'zyzz/react-native/react',
1930
- ].includes(binding.importNode.source.value) ||
1931
- binding.importNode.importKind === 'type'
1932
- )
1933
- return false
1934
-
1935
- const specifier = binding.node
1936
- if (
1937
- callee.type === 'Identifier'
1938
- ? specifier.type !== 'ImportSpecifier' ||
1939
- specifier.importKind === 'type' ||
1940
- !['useAnimatedVars', 'useVars'].includes(
1941
- specifier.imported.type === 'Identifier'
1942
- ? specifier.imported.name
1943
- : specifier.imported.value,
1944
- )
1945
- : specifier.type !== 'ImportNamespaceSpecifier'
1946
- )
1947
- return false
1948
-
1949
- varsReads.push({ ...varsRead(link), end: node.end, start: node.start })
1950
- return true
1951
- }
1952
-
1953
- function themeReference(
1954
- node: Ast.Node,
1955
- parent: Ast.Node,
1956
- ancestors: readonly Ast.Node[],
1957
- theme: Call,
1958
- ): boolean {
1959
- const grandparent = ancestors.at(-3)
1960
- if (
1961
- factoryReferences.has(node.start) ||
1962
- ancestors.some((ancestor) => factoryReferences.has(ancestor.start))
1963
- )
1964
- return true
1965
- if (exportReferences.has(node.start)) return true
1966
- if (aliasReferences.has(node.start)) return true
1967
-
1968
- if (node.start < theme.end)
1969
- fail('Theme references must follow their local definition.', node)
1970
-
1971
- if (
1972
- parent.type === 'CallExpression' &&
1973
- factories.has(parent.start) &&
1974
- parent.arguments[0] === node
1975
- )
1976
- return true
1977
-
1978
- if (
1979
- parent.type === 'MemberExpression' &&
1980
- parent.object === node &&
1981
- (theme.directVariables ||
1982
- (parent.property.type === 'Identifier' &&
1983
- !parent.computed &&
1984
- ['tokens', 'vars'].includes(parent.property.name)) ||
1985
- (parent.property.type === 'Literal' &&
1986
- parent.computed &&
1987
- ['tokens', 'vars'].includes(String(parent.property.value))))
1988
- ) {
1989
- if (parent.optional)
1990
- fail('Token references cannot use optional access.', parent)
1991
-
1992
- const variable =
1993
- theme.directVariables ||
1994
- (parent.property.type === 'Identifier'
1995
- ? parent.property.name === 'vars'
1996
- : parent.property.type === 'Literal' &&
1997
- parent.property.value === 'vars')
1998
-
1999
- let value: unknown =
2000
- variable && !theme.directVariables
2001
- ? themes[theme.name]!.vars
2002
- : themes[theme.name]!.tokens
2003
- let target: Ast.Node = theme.directVariables ? node : parent
2004
- let index = ancestors.length - (theme.directVariables ? 2 : 3)
2005
-
2006
- for (; index >= 0; index--) {
2007
- const ancestor = ancestors[index]!
2008
-
2009
- if (ancestor.type !== 'MemberExpression' || ancestor.object !== target)
2010
- break
2011
-
2012
- const key = (() => {
2013
- if (ancestor.property.type === 'Identifier' && !ancestor.computed) {
2014
- return ancestor.property.name
2015
- }
2016
-
2017
- if (
2018
- ancestor.property.type === 'Literal' &&
2019
- ancestor.computed &&
2020
- (typeof ancestor.property.value === 'string' ||
2021
- typeof ancestor.property.value === 'number')
2022
- ) {
2023
- return String(ancestor.property.value)
2024
- }
2025
-
2026
- return undefined
2027
- })()
2028
-
2029
- if (ancestor.optional || key === undefined)
2030
- fail(
2031
- 'Token paths require static property names without optional access.',
2032
- ancestor,
2033
- )
2034
-
2035
- value =
2036
- value && typeof value === 'object' && !Token.is(value)
2037
- ? Object.getOwnPropertyDescriptor(value, key)?.value
2038
- : undefined
2039
-
2040
- if (value === undefined) fail('Unknown theme token path.', ancestor)
2041
-
2042
- target = ancestor
2043
- }
2044
-
2045
- if (!Token.is(value))
2046
- fail('Expected a scalar theme token reference.', target)
2047
-
2048
- const reference = value
2049
-
2050
- for (; index >= 0; index--) {
2051
- const ancestor = ancestors[index]!
2052
-
2053
- if (
2054
- (ancestor.type === 'TSAsExpression' ||
2055
- ancestor.type === 'TSSatisfiesExpression' ||
2056
- ancestor.type === 'TSNonNullExpression' ||
2057
- ancestor.type === 'TSTypeAssertion') &&
2058
- ancestor.expression === target
2059
- )
2060
- target = ancestor
2061
- else break
2062
- }
2063
-
2064
- const valueTarget = target
2065
-
2066
- if (variable) {
2067
- while (index >= 0) {
2068
- const ancestor = ancestors[index]!
2069
-
2070
- if (
2071
- !(
2072
- (ancestor.type === 'TemplateLiteral' &&
2073
- ancestor.expressions.includes(target as Ast.Expression)) ||
2074
- ((ancestor.type === 'TSAsExpression' ||
2075
- ancestor.type === 'TSSatisfiesExpression' ||
2076
- ancestor.type === 'TSNonNullExpression' ||
2077
- ancestor.type === 'TSTypeAssertion') &&
2078
- ancestor.expression === target)
2079
- )
2080
- )
2081
- break
2082
-
2083
- target = ancestor
2084
- index--
2085
- }
2086
- }
2087
-
2088
- const array = ancestors[index]
2089
-
2090
- if (
2091
- array?.type === 'ArrayExpression' &&
2092
- array.elements.includes(target as Ast.Expression)
2093
- ) {
2094
- target = array
2095
- index--
2096
-
2097
- for (; index >= 0; index--) {
2098
- const ancestor = ancestors[index]!
2099
-
2100
- if (
2101
- (ancestor.type === 'TSAsExpression' ||
2102
- ancestor.type === 'TSSatisfiesExpression' ||
2103
- ancestor.type === 'TSNonNullExpression' ||
2104
- ancestor.type === 'TSTypeAssertion') &&
2105
- ancestor.expression === target
2106
- )
2107
- target = ancestor
2108
- else break
2109
- }
2110
- }
2111
-
2112
- const property = ancestors[index]
2113
- const object = ancestors[index - 1]
2114
- let argument: Ast.Node | undefined = object
2115
- let callIndex = index - 2
2116
-
2117
- for (; callIndex >= 0; callIndex--) {
2118
- const ancestor = ancestors[callIndex]!
2119
-
2120
- if (
2121
- ancestor.type === 'Property' &&
2122
- ancestor.value === argument &&
2123
- ancestors[callIndex - 1]?.type === 'ObjectExpression'
2124
- ) {
2125
- argument = ancestors[--callIndex]
2126
- continue
2127
- }
2128
-
2129
- if (
2130
- (ancestor.type === 'TSAsExpression' ||
2131
- ancestor.type === 'TSSatisfiesExpression' ||
2132
- ancestor.type === 'TSNonNullExpression' ||
2133
- ancestor.type === 'TSTypeAssertion') &&
2134
- ancestor.expression === argument
2135
- )
2136
- argument = ancestor
2137
- else break
2138
- }
2139
-
2140
- if (
2141
- ancestors[callIndex]?.type === 'ArrowFunctionExpression' &&
2142
- (ancestors[callIndex] as Ast.ArrowFunctionExpression).body === argument
2143
- ) {
2144
- argument = ancestors[callIndex]
2145
- callIndex--
2146
- }
2147
-
2148
- while (callIndex >= 0) {
2149
- const wrapper = ancestors[callIndex]!
2150
-
2151
- if (
2152
- (wrapper.type === 'TSAsExpression' ||
2153
- wrapper.type === 'TSSatisfiesExpression' ||
2154
- wrapper.type === 'TSNonNullExpression' ||
2155
- wrapper.type === 'TSTypeAssertion') &&
2156
- wrapper.expression === argument
2157
- ) {
2158
- argument = wrapper
2159
- callIndex--
2160
- } else break
2161
- }
2162
-
2163
- const call = ancestors[callIndex]
2164
-
2165
- if (
2166
- property?.type !== 'Property' ||
2167
- property.value !== target ||
2168
- object?.type !== 'ObjectExpression' ||
2169
- call?.type !== 'CallExpression' ||
2170
- call.arguments[0] !== argument ||
2171
- (!styles.has(call.start) && !options.contributionCalls?.has(call.start))
2172
- ) {
2173
- if (
2174
- ancestors.some(
2175
- (node) =>
2176
- node.type === 'VariableDeclarator' &&
2177
- options.staticBindings?.has(node.start),
2178
- )
2179
- )
2180
- staticTokens.push(valueTarget)
2181
- else
2182
- fail(
2183
- 'Token references must be direct property values in bound theme style calls.',
2184
- target,
2185
- )
2186
- }
2187
-
2188
- tokens.set(valueTarget.start, { end: valueTarget.end, reference })
2189
-
2190
- const unwrapped = Expression.unwrap(valueTarget)
2191
-
2192
- tokens.set(unwrapped.start, { end: unwrapped.end, reference })
2193
-
2194
- return true
2195
- }
2196
-
2197
- if (
2198
- parent.type !== 'MemberExpression' ||
2199
- parent.object !== node ||
2200
- parent.computed ||
2201
- parent.optional ||
2202
- parent.property.type !== 'Identifier'
2203
- )
2204
- fail(
2205
- 'Use Config.create or Vars.extend with variable definitions; other references require source linking.',
2206
- node,
2207
- )
2208
-
2209
- if (
2210
- ['style', 'variants'].includes(parent.property.name) &&
2211
- grandparent?.type === 'CallExpression' &&
2212
- grandparent.callee === parent &&
2213
- !grandparent.optional
2214
- ) {
2215
- styles.set(grandparent.start, {
2216
- call: grandparent,
2217
- recipe: parent.property.name === 'variants',
2218
- theme: themes[theme.name]!,
2219
- output: theme.output,
2220
- })
2221
-
2222
- return true
2223
- }
2224
-
2225
- if (parent.property.name !== 'className')
2226
- fail(
2227
- 'Only direct theme.style calls and theme.className reads are supported here.',
2228
- parent,
2229
- )
2230
-
2231
- let target: Ast.Node = parent
2232
-
2233
- for (let index = ancestors.length - 3; index >= 0; index--) {
2234
- const ancestor = ancestors[index]!
2235
-
2236
- if (
2237
- (ancestor.type === 'AssignmentExpression' &&
2238
- ancestor.left === target) ||
2239
- (ancestor.type === 'UpdateExpression' &&
2240
- ancestor.argument === target) ||
2241
- (ancestor.type === 'UnaryExpression' &&
2242
- ancestor.operator === 'delete') ||
2243
- ((ancestor.type === 'ForInStatement' ||
2244
- ancestor.type === 'ForOfStatement') &&
2245
- ancestor.left === target)
2246
- )
2247
- fail('Theme scope properties cannot be reassigned.', ancestor)
2248
-
2249
- if (
2250
- ((ancestor.type === 'TSAsExpression' ||
2251
- ancestor.type === 'TSNonNullExpression' ||
2252
- ancestor.type === 'TSSatisfiesExpression' ||
2253
- ancestor.type === 'TSTypeAssertion') &&
2254
- ancestor.expression === target) ||
2255
- (ancestor.type === 'Property' && ancestor.value === target) ||
2256
- ancestor.type === 'ObjectPattern' ||
2257
- ancestor.type === 'ArrayPattern' ||
2258
- (ancestor.type === 'RestElement' && ancestor.argument === target) ||
2259
- (ancestor.type === 'AssignmentPattern' && ancestor.left === target)
2260
- )
2261
- target = ancestor
2262
- else break
2263
- }
2264
-
2265
- references.push(
2266
- Object.freeze({ end: parent.end, name: theme.name, start: parent.start }),
2267
- )
2268
-
2269
- return true
2270
- }
2271
-
2272
- for (const link of Object.values(exports))
2273
- if (
2274
- link.kind === 'config' &&
2275
- !link.call.selection &&
2276
- !link.call.initialization &&
2277
- !link.call.root
2278
- ) {
2279
- if (link.call.script) scripts.add(link.call.name)
2280
- if (link.call.appearance) appearances.add(link.call.name)
2281
- }
2282
-
2283
- const nativeContexts = new Map<
2284
- Token.Contract,
2285
- NonNullable<Source.Call['nativeContext']>
2286
- >()
2287
- return {
2288
- nativeContext(start: number, end: number) {
2289
- const theme = styles.get(start)?.theme
2290
- const contract =
2291
- theme?.[Token.definition].contract ??
2292
- [...tokens].find(([offset]) => offset >= start && offset < end)?.[1]
2293
- .reference.contract
2294
- if (!contract) return undefined
2295
- const cached = nativeContexts.get(contract)
2296
- if (cached) return cached
2297
- const config = [...configs.values()].find(
2298
- (value) => value.definition[Token.definition].contract === contract,
2299
- )
2300
- if (!config?.call.options?.themes) {
2301
- const alias = [...aliasNames.values()].find(
2302
- (value) =>
2303
- themes[value.name]?.[Token.definition].contract === contract &&
2304
- value.options?.themes,
2305
- )
2306
- if (!alias?.options?.themes) return undefined
2307
- const context = {
2308
- defaultVars: String(alias.options.defaultTheme),
2309
- vars: Object.fromEntries(
2310
- Object.entries(
2311
- alias.options.themes as Record<
2312
- string,
2313
- Parameters<typeof Theme.define>[0]
2314
- >,
2315
- ).map(([name, values]) => [
2316
- name,
2317
- Token.bind(
2318
- contract.variableSet
2319
- ? VariableSets.theme(Vars.define(values as Vars.Values))
2320
- : Theme.define(values),
2321
- contract,
2322
- ),
2323
- ]),
2324
- ),
2325
- }
2326
- Object.freeze(context.vars)
2327
- nativeContexts.set(contract, Object.freeze(context))
2328
- return context
2329
- }
2330
- const entries = Object.entries(config.members ?? {}).flatMap(
2331
- ([key, value]) => {
2332
- const path = JSON.parse(key) as string[]
2333
- if (config.call.selection && path.length === 1)
2334
- return [[path[0]!, value.definition] as const]
2335
- return (path[0] === 'themes' || path[0] === 'vars') &&
2336
- path.length === 2
2337
- ? [[path[1]!, value.definition] as const]
2338
- : []
2339
- },
2340
- )
2341
- const context = Object.freeze({
2342
- defaultVars: String(config.call.options.defaultTheme),
2343
- vars: Object.freeze(Object.fromEntries(entries)),
2344
- })
2345
- nativeContexts.set(contract, context)
2346
- return context
2347
- },
2348
- aliases,
2349
- appearances,
2350
- calls,
2351
- exports: Object.freeze(exports),
2352
- reference,
2353
- references,
2354
- scopeApplications,
2355
- scripts,
2356
- selections,
2357
- selectionUses,
2358
- staticTokens,
2359
- styles,
2360
- themes: Object.freeze(themes),
2361
- tokens,
2362
- varsReads,
2363
- }
2364
- }
2365
-
2366
- /** Inputs supplied by the source adapter. */
2367
- export declare namespace collect {
2368
- /** Stable module namespace, independent of token values and call offsets. */
2369
- type Options = {
2370
- /** Captures readonly variable arguments for native React hooks. */
2371
- readonly native?: boolean | undefined
2372
- /** Encoded package/module identity from the source adapter. */
2373
- readonly staticBindings?: ReadonlySet<number> | undefined
2374
- readonly contributionCalls?: ReadonlySet<number> | undefined
2375
- readonly namespace: string
2376
- readonly linked?: boolean | undefined
2377
- readonly links?: Readonly<Record<string, Link>> | undefined
2378
- }
2379
- }
2380
-
2381
- /** Located failure from unsupported or invalid local theme syntax. */
2382
- export class InvalidError extends Error {
2383
- /** Retains a source span for the public extractor diagnostic. */
2384
- constructor(message: string, node: Pick<Ast.Node, 'end' | 'start'>) {
2385
- super(message)
2386
- this.end = node.end
2387
- this.start = node.start
2388
- }
2389
- /** Exclusive source offset. */
2390
- readonly end: number
2391
- /** Namespaced diagnostic identity. */
2392
- override name = 'Source.ThemeInvalidError'
2393
- /** Inclusive source offset. */
2394
- readonly start: number
2395
- }
2396
-
2397
- /** Scope property read replaced with a compiled constant. */
2398
- export type Reference = Pick<Call, 'end' | 'name' | 'start'>