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,1028 +0,0 @@
1
- /**
2
- * Serializes validated theme authoring data for independently compiled libraries.
3
- * @module
4
- */
5
- import type * as Binding from '../../internal/Binding.js'
6
- import * as Config from '../../internal/Configuration.js'
7
- import * as Configurations from './Configurations.js'
8
- import * as FunctionSyntax from '../../internal/FunctionSyntax.js'
9
- import * as Identifiers from './Identifiers.js'
10
- import * as PackedStyles from './PackedStyles.js'
11
- import * as Shorthands from '../../internal/Shorthands.js'
12
- import * as Stylesheets from './Stylesheets.js'
13
- import * as Theme from '../../internal/Theme.js'
14
- import * as VariableSets from '../../internal/VariableSets.js'
15
- import * as Vars from '../../Vars.js'
16
- import type * as Themes from './Themes.js'
17
- import * as Token from '../../internal/Token.js'
18
-
19
- /** Reads versioned JSON as validated data; never evaluates package code. */
20
- export function read(
21
- source: string,
22
- identities: Map<string, Token.Contract>,
23
- moduleId = '',
24
- ) {
25
- const data = record(JSON.parse(source))
26
- if (
27
- ![
28
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
29
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
30
- ].includes(data.version as number)
31
- )
32
- throw new Error('Unsupported Zyzz contract version.')
33
-
34
- // Root controls arrived with version 18; older readers must treat them as absent.
35
- const rootControls = (data.version as number) >= 18
36
- const legacyModes = new Map<string, 'atomic' | 'grouped'>()
37
- if ((data.version as number) < 17) {
38
- function collect(value: unknown) {
39
- const entry = record(value)
40
- if (entry.options !== undefined && entry.theme !== undefined) {
41
- const options = record(entry.options)
42
- if (options.cssOutput !== undefined) {
43
- if (options.cssOutput !== 'atomic' && options.cssOutput !== 'grouped')
44
- throw new Error('Invalid packed CSS output mode.')
45
- const theme = record(record(data.themes)[string(entry.theme)])
46
- const identity = string(theme.identity)
47
- const previous = legacyModes.get(identity)
48
- if (previous !== undefined && previous !== options.cssOutput)
49
- throw new Error(
50
- 'Conflicting packed CSS output modes for one theme identity.',
51
- )
52
- legacyModes.set(identity, options.cssOutput)
53
- }
54
- }
55
- for (const member of Object.values(record(entry.members ?? {})))
56
- collect(member)
57
- }
58
- for (const entry of Object.values(record(data.exports))) collect(entry)
59
- }
60
-
61
- function validateVariables(entry: Record<string, unknown>) {
62
- if ((data.version as number) < 31 || entry.variableNaming !== undefined)
63
- throw new Error(
64
- 'Legacy packed variable names are unsupported. Rebuild the library with the current version of Zyzz.',
65
- )
66
- }
67
-
68
- function decode(value: unknown): unknown {
69
- if (!value || typeof value !== 'object') return value
70
- if (Array.isArray(value)) return value.map(decode)
71
- const fields = record(value)
72
- if (Object.hasOwn(fields, '$object'))
73
- return Object.fromEntries(
74
- Object.entries(record(fields.$object)).map(([key, value]) => [
75
- key,
76
- decode(value),
77
- ]),
78
- )
79
- if (Object.hasOwn(fields, '$composition')) {
80
- if ((data.version as number) < 29)
81
- throw new Error(
82
- 'Composed variables require contract version 29 or later.',
83
- )
84
- const composition = record(fields.$composition)
85
- if (
86
- (composition.group !== 'color' && composition.group !== 'spacing') ||
87
- !Array.isArray(composition.parts)
88
- )
89
- throw new Error('Invalid packed variable composition.')
90
- return Vars.compose(
91
- composition.group,
92
- composition.parts.map(decode) as readonly (
93
- | string
94
- | number
95
- | Vars.Reference
96
- )[],
97
- )
98
- }
99
- if (Object.hasOwn(fields, '$variable')) {
100
- const reference = record(fields.$variable)
101
- const identity = string(reference.identity)
102
- validateVariables(reference)
103
- let contract = identities.get(identity)
104
- if (contract && !contract.variableSet)
105
- throw new Error(
106
- 'Conflicting packed variable-set modes for one identity.',
107
- )
108
- if (!contract) {
109
- contract = Object.freeze({
110
- variableSet: true,
111
- [Token.identity]: identity,
112
- })
113
- identities.set(identity, contract)
114
- }
115
- const resolved = decode(reference.value) as Token.Value
116
- return Token.create({
117
- contract,
118
- group: VariableSets.domain(resolved),
119
- path: string(reference.path),
120
- value: resolved,
121
- })
122
- }
123
- return Object.fromEntries(
124
- Object.entries(fields).map(([key, value]) => [key, decode(value)]),
125
- )
126
- }
127
- const themes: Record<string, Theme.Definition> = Object.create(null)
128
- const types: Record<string, string> = Object.create(null)
129
-
130
- for (const [name, value] of Object.entries(record(data.themes))) {
131
- const entry = record(value)
132
- const identity = string(entry.identity)
133
- if (
134
- Object.keys(record(entry.tokens)).length ||
135
- entry.variableNaming !== undefined
136
- )
137
- validateVariables(entry)
138
- if (entry.variableSet === true && (data.version as number) < 28)
139
- throw new Error('Vars contracts require contract version 28 or later.')
140
- const mappings = VariableSets.mappings(entry.mappings)
141
- if (
142
- entry.cssOutput !== undefined &&
143
- entry.cssOutput !== 'atomic' &&
144
- entry.cssOutput !== 'grouped'
145
- )
146
- throw new Error('Invalid packed CSS output mode.')
147
- const cssOutput = (entry.cssOutput ?? legacyModes.get(identity)) as
148
- | 'atomic'
149
- | 'grouped'
150
- | undefined
151
-
152
- if (entry.composition !== undefined) {
153
- if ((data.version as number) < 34)
154
- throw new Error(
155
- 'Composition modes require contract version 34 or later.',
156
- )
157
- if (
158
- entry.composition !== 'independent' &&
159
- entry.composition !== 'ordered'
160
- )
161
- throw new Error('Invalid packed composition mode.')
162
- }
163
- const composition = entry.composition as
164
- | 'independent'
165
- | 'ordered'
166
- | undefined
167
-
168
- if (entry.defaultLayer !== undefined) {
169
- if ((data.version as number) < 27)
170
- throw new Error('Default layers require contract version 27 or later.')
171
- Config.create({ defaultLayer: entry.defaultLayer as string })
172
- }
173
- const defaultLayer = entry.defaultLayer as string | undefined
174
-
175
- const shorthands =
176
- entry.shorthands !== undefined
177
- ? Shorthands.read(entry.shorthands)
178
- : undefined
179
- let contract = identities.get(identity)
180
- if (
181
- contract &&
182
- Boolean(contract.variableSet) !== (entry.variableSet === true)
183
- )
184
- throw new Error('Conflicting packed variable-set modes for one identity.')
185
- if (
186
- contract &&
187
- JSON.stringify(contract.mappings ?? {}) !== JSON.stringify(mappings ?? {})
188
- )
189
- throw new Error('Conflicting packed variable mappings for one identity.')
190
- if (
191
- contract &&
192
- Shorthands.signature(contract.shorthands) !==
193
- Shorthands.signature(shorthands)
194
- )
195
- throw new Error(
196
- 'Conflicting packed shorthand mappings for one theme identity.',
197
- )
198
-
199
- if (
200
- contract &&
201
- (contract.composition ?? 'ordered') !== (composition ?? 'ordered')
202
- )
203
- throw new Error(
204
- 'Conflicting packed composition modes for one theme identity.',
205
- )
206
-
207
- if (
208
- contract &&
209
- (contract.cssOutput ?? 'atomic') !== (cssOutput ?? 'atomic')
210
- )
211
- throw new Error(
212
- 'Conflicting packed CSS output modes for one theme identity.',
213
- )
214
-
215
- if (contract && contract.defaultLayer !== defaultLayer)
216
- throw new Error(
217
- 'Conflicting packed default layers for one theme identity.',
218
- )
219
-
220
- if (!contract) {
221
- contract = Object.freeze({
222
- ...(entry.variableSet === true
223
- ? {
224
- variableSet: true,
225
- mappings,
226
- }
227
- : {}),
228
- ...(entry.shorthands !== undefined
229
- ? { shorthands: Shorthands.read(entry.shorthands) }
230
- : {}),
231
- ...(composition ? { composition } : {}),
232
- ...(cssOutput ? { cssOutput } : {}),
233
- ...(defaultLayer !== undefined ? { defaultLayer } : {}),
234
- [Token.complete]: true,
235
- [Token.identity]: identity,
236
- })
237
- identities.set(identity, contract)
238
- }
239
-
240
- const definition =
241
- entry.variableSet === true
242
- ? VariableSets.theme(
243
- Vars.define(decode(entry.tokens) as Vars.Values),
244
- mappings,
245
- )
246
- : Theme.define(record(entry.tokens) as Theme.Tokens)
247
- if (
248
- (data.version as number) < 24 &&
249
- Object.hasOwn(definition.tokens, 'typography')
250
- )
251
- throw new Error(
252
- 'Packed typography sets require contract version 24 or later.',
253
- )
254
-
255
- if (
256
- (data.version as number) < 25 &&
257
- (definition[Token.definition].paths ||
258
- Object.hasOwn(definition.tokens, 'borderWidth'))
259
- )
260
- throw new Error(
261
- 'Packed responsive typography and border widths require contract version 25 or later.',
262
- )
263
-
264
- themes[name] = Token.bind(
265
- definition,
266
- contract,
267
- entry.cssName === undefined ? undefined : string(entry.cssName),
268
- )
269
- types[name] = type(input(definition))
270
- }
271
-
272
- function link(value: unknown): Themes.Link {
273
- const raw = record(value)
274
- if (raw.nativeProvider !== undefined && (data.version as number) < 32)
275
- throw new Error('Native providers require contract version 32 or later.')
276
- // Contracts before version 19 record style authoring exports as `css`.
277
- const entry =
278
- raw.kind === 'css' && (data.version as number) < 19
279
- ? { ...raw, kind: 'style' }
280
- : raw
281
-
282
- if (entry.kind === 'variables') {
283
- if ((data.version as number) < 14)
284
- throw new Error(
285
- 'Legacy variable contracts require recompilation with variable().',
286
- )
287
- const names = new Set<string>()
288
-
289
- const slots = Object.fromEntries(
290
- Object.entries(record(entry.variables)).map(([key, value]) => {
291
- const slot = record(value)
292
- if (
293
- key === 'set' ||
294
- key === '__proto__' ||
295
- names.has(string(slot.name)) ||
296
- !/^--z-[a-zA-Z0-9_-]+$/.test(string(slot.name)) ||
297
- ![
298
- '*',
299
- 'color',
300
- 'length',
301
- 'number',
302
- 'percentage',
303
- 'signedLength',
304
- 'signedPercentage',
305
- ].includes(String(slot.type))
306
- )
307
- throw new Error('Invalid packed variable contract.')
308
-
309
- names.add(string(slot.name))
310
-
311
- return [
312
- key,
313
- Object.freeze({
314
- name: slot.name as `--${string}`,
315
- type: slot.type as Binding.Domain,
316
- variable: true as const,
317
- }),
318
- ]
319
- }),
320
- )
321
-
322
- const binding = string(entry.binding)
323
-
324
- return {
325
- binding,
326
- kind: 'variables',
327
- ...(entry.members
328
- ? {
329
- members: Object.fromEntries(
330
- Object.entries(record(entry.members)).map(([name, value]) => [
331
- name,
332
- link(value),
333
- ]),
334
- ),
335
- }
336
- : {}),
337
- definition: Theme.define({}),
338
- call: {
339
- start: -1,
340
- end: -1,
341
- name: binding,
342
- tokenType: '{}',
343
- variables: Object.freeze(slots),
344
- ...(entry.source !== undefined
345
- ? {
346
- variableOwner: Stylesheets.resolve(
347
- moduleId,
348
- string(entry.source),
349
- ),
350
- }
351
- : {}),
352
- },
353
- }
354
- }
355
- if (entry.kind === 'rule-reference') {
356
- const name = string(entry.name)
357
- const reference = string(entry.reference)
358
- if (
359
- ![
360
- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
361
- 27, 28, 29, 30, 31, 32, 33, 34,
362
- ].includes(data.version as number) ||
363
- ![
364
- 'cssFunction',
365
- 'customMedia',
366
- 'colorProfile',
367
- 'counterStyle',
368
- 'fontPaletteValues',
369
- 'positionTry',
370
- ].includes(reference) ||
371
- !/^(?:--)?z-[a-zA-Z0-9_-]+$/.test(name) ||
372
- !name.startsWith(
373
- `${reference === 'counterStyle' ? '' : '--'}z-${reference.toLowerCase()}`,
374
- ) ||
375
- entry.binding !== name
376
- )
377
- throw new Error('Invalid named stylesheet identity.')
378
- return {
379
- binding: string(entry.binding),
380
- kind: 'rule-reference',
381
- definition: Theme.define({}),
382
- call: {
383
- start: -1,
384
- end: -1,
385
- name,
386
- tokenType: '{}',
387
- reference: reference as NonNullable<Themes.Call['reference']>,
388
- ...(reference === 'cssFunction'
389
- ? { function: signature(entry.function, data.version as number) }
390
- : {}),
391
- },
392
- }
393
- }
394
-
395
- if (entry.kind === 'animation') {
396
- const name = string(entry.name)
397
- if (!/^z-k[a-zA-Z0-9_-]+$/.test(name))
398
- throw new Error('Invalid animation identity.')
399
-
400
- return {
401
- binding: string(entry.binding),
402
- kind: 'animation',
403
- definition: Theme.define({}),
404
- call: { start: -1, end: -1, name, tokenType: '{}' },
405
- }
406
- }
407
-
408
- if (entry.kind === 'style-reference') {
409
- if (entry.style !== undefined && (data.version as number) < 16)
410
- throw new Error(
411
- 'Packed callable styles require contract version 16 or later.',
412
- )
413
- const binding = string(entry.binding)
414
- if (!/^z-style-[a-zA-Z0-9_-]+$/.test(binding))
415
- throw new Error('Invalid style reference identity.')
416
- const members =
417
- entry.members === undefined
418
- ? undefined
419
- : Object.fromEntries(
420
- Object.entries(record(entry.members)).map(([key, value]) => {
421
- const member = link(value)
422
- if (
423
- member.kind !== 'style-reference' ||
424
- (member.members && (data.version as number) < 22)
425
- )
426
- throw new Error('Invalid style reference member.')
427
- return [key, member]
428
- }),
429
- )
430
- const nativeContext = (() => {
431
- if (entry.nativeContext === undefined) return undefined
432
- if ((data.version as number) < 33)
433
- throw new Error(
434
- 'Native style catalogs require contract version 33 or later.',
435
- )
436
- if (entry.style === undefined)
437
- throw new Error('Native style catalogs require a packed style.')
438
- const context = record(entry.nativeContext)
439
- const vars = Object.fromEntries(
440
- Object.entries(record(context.vars)).map((entry) => {
441
- const [name, value] = entry
442
- const theme = themes[string(value)]
443
- if (!name || !theme)
444
- throw new Error('Unknown packed native style catalog.')
445
- return [name, theme]
446
- }),
447
- )
448
- const defaultVars = string(context.defaultVars)
449
- if (!Object.hasOwn(vars, defaultVars))
450
- throw new Error('Invalid packed native style default.')
451
- const identities = new Set(
452
- Object.values(vars).map((theme) => theme[Token.definition].contract),
453
- )
454
- if (identities.size !== 1)
455
- throw new Error('Incompatible packed native style catalog.')
456
- return { defaultVars, vars }
457
- })()
458
- return {
459
- binding,
460
- call: {
461
- start: -1,
462
- end: -1,
463
- name: members ? '' : binding,
464
- tokenType: '{}',
465
- },
466
- definition: Theme.define({}),
467
- kind: 'style-reference',
468
- ...(entry.style === undefined
469
- ? {}
470
- : {
471
- style: {
472
- ...PackedStyles.read(
473
- entry.style,
474
- themes,
475
- data.version as number,
476
- ),
477
- ...(nativeContext ? { nativeContext } : {}),
478
- },
479
- }),
480
- ...(members ? { members } : {}),
481
- }
482
- }
483
-
484
- if (entry.output !== undefined && entry.output !== 'html')
485
- throw new Error('Invalid theme output.')
486
-
487
- if (
488
- entry.recipe !== undefined &&
489
- (entry.recipe !== true ||
490
- (data.version as number) < 15 ||
491
- entry.kind !== 'style')
492
- )
493
- throw new Error('Invalid bound recipe contract.')
494
-
495
- const theme = string(entry.theme)
496
- const definition = themes[theme]
497
- if (
498
- !definition ||
499
- !['config', 'style', 'theme'].includes(String(entry.kind))
500
- )
501
- throw new Error('Invalid Zyzz contract export.')
502
-
503
- const members =
504
- entry.kind === 'config'
505
- ? Object.fromEntries(
506
- Object.entries(record(entry.members)).map(([key, value]) => [
507
- key,
508
- link(value),
509
- ]),
510
- )
511
- : undefined
512
-
513
- const options =
514
- entry.options === undefined ? undefined : record(decode(entry.options))
515
-
516
- if (options) {
517
- if (
518
- entry.variableConfig === true &&
519
- JSON.stringify(VariableSets.mappings(entry.variableMappings) ?? {}) !==
520
- JSON.stringify(definition[Token.definition].contract.mappings ?? {})
521
- )
522
- throw new Error(
523
- 'Configuration mappings disagree with linked variable metadata.',
524
- )
525
- if (entry.variableConfig === true)
526
- Config.create(
527
- variableOptions(
528
- options,
529
- entry.variableMappings as Vars.Mappings | false | undefined,
530
- ),
531
- )
532
- else Config.create(options as Config.create.Options)
533
- if (
534
- (data.version as number) >= 17 &&
535
- (options.cssOutput ?? 'atomic') !==
536
- (definition[Token.definition].contract.cssOutput ?? 'atomic')
537
- )
538
- throw new Error(
539
- 'Configuration CSS output disagrees with linked theme metadata.',
540
- )
541
-
542
- if (
543
- (options.composition ?? 'ordered') !==
544
- (definition[Token.definition].contract.composition ?? 'ordered')
545
- )
546
- throw new Error(
547
- 'Configuration composition disagrees with linked theme metadata.',
548
- )
549
-
550
- if (
551
- options.defaultLayer !==
552
- definition[Token.definition].contract.defaultLayer
553
- )
554
- throw new Error(
555
- 'Configuration default layer disagrees with linked theme metadata.',
556
- )
557
-
558
- if (
559
- Shorthands.signature(options.shorthands) !==
560
- Shorthands.signature(definition[Token.definition].contract.shorthands)
561
- )
562
- throw new Error(
563
- 'Configuration mappings disagree with linked theme metadata.',
564
- )
565
- }
566
-
567
- const catalogOnly =
568
- !!options?.themes &&
569
- ((data.version as number) < 4 || entry.catalogOnly === true)
570
- const fullConfigType = options
571
- ? entry.nativeProvider === true
572
- ? `import('zyzz/react-native/react').defineConfig.ReturnType<${Configurations.type(entry.variableConfig === true ? variableOptions(options, entry.variableMappings as Vars.Mappings | false | undefined) : options)}>`
573
- : entry.variableConfig === true
574
- ? `import('zyzz').Config.VariableConfig<${Configurations.type(variableOptions(options, entry.variableMappings as Vars.Mappings | false | undefined))}>`
575
- : `import('zyzz').Config.create.ReturnType<${Configurations.type(options)}>`
576
- : ''
577
- // Helpers a legacy library did not compile are hidden from its consumers' types.
578
- const hidden = [
579
- ...(rootControls && entry.appearance === true ? [] : ["'appearance'"]),
580
- ...(entry.script === true ? [] : ["'script'"]),
581
- ]
582
- const configType = hidden.length
583
- ? `{readonly [key in keyof ${fullConfigType} as key extends ${hidden.join(' | ')} ? never : key]:${fullConfigType}[key]}`
584
- : fullConfigType
585
- const outputType = catalogOnly
586
- ? `({readonly [key in keyof ${configType} as key extends 'themes' ? never : key]:${configType}[key]} & {readonly themes:{readonly [key in keyof ${configType}['themes']]:${configType}['themes'][key]}})`
587
- : configType
588
- if (entry.kind === 'config' && !options)
589
- throw new Error('Missing configuration options.')
590
-
591
- return {
592
- binding: string(entry.binding),
593
- call: {
594
- ...(entry.nativeProvider === true ? { nativeProvider: true } : {}),
595
- ...(entry.variableSet === true
596
- ? {
597
- variableSet: true,
598
- type: `import('zyzz').Vars.Definition<${types[theme]!}>`,
599
- }
600
- : {}),
601
- ...(entry.directVariables === true
602
- ? {
603
- directVariables: true,
604
- type: `import('zyzz').Vars.${entry.variableSet === true ? 'Definition' : 'References'}<${types[theme]!}>`,
605
- }
606
- : {}),
607
- ...(entry.variableConfig === true
608
- ? {
609
- variableConfig: true,
610
- variableMappings: entry.variableMappings as
611
- | Vars.Mappings
612
- | false
613
- | undefined,
614
- }
615
- : {}),
616
- ...(entry.recipe === true ? { recipe: true } : {}),
617
- ...(entry.output === 'html' ? { output: 'html' as const } : {}),
618
- ...(catalogOnly ? { catalogOnly: true } : {}),
619
- ...(entry.script === true ? { script: true } : {}),
620
- ...(rootControls && entry.appearance === true
621
- ? { appearance: true }
622
- : {}),
623
- ...(rootControls && entry.root === true ? { root: true } : {}),
624
- end: -1,
625
- name: theme,
626
- start: -1,
627
- tokenType: types[theme]!,
628
- ...(definition[Token.definition].contract.shorthands ||
629
- entry.output === 'html'
630
- ? {
631
- type: `import('zyzz').Config.create.ReturnType<{theme:${types[theme]!};${entry.output === 'html' ? "output:'html';" : ''}shorthands:${Configurations.type(definition[Token.definition].contract.shorthands ?? {})}}>['theme']`,
632
- }
633
- : {}),
634
- ...(entry.selection === true ? { selection: true } : {}),
635
- ...(entry.initialization === true ? { initialization: true } : {}),
636
- ...(options
637
- ? {
638
- options,
639
- type: `${outputType}${entry.initialization === true ? "['script']" : entry.root === true ? "['appearance']" : entry.selection === true ? (entry.variableConfig === true ? "['vars']" : "['themes']") : ''}`,
640
- }
641
- : {}),
642
- ...(members
643
- ? {
644
- members: Object.fromEntries(
645
- Object.entries(members).map(([key, member]) => [
646
- key,
647
- member.call.name,
648
- ]),
649
- ),
650
- }
651
- : {}),
652
- },
653
- definition,
654
- kind: entry.kind as Themes.Link['kind'],
655
- ...(members ? { members } : {}),
656
- }
657
- }
658
-
659
- const links = Object.fromEntries(
660
- Object.entries(record(data.exports)).map(([name, value]) => [
661
- name,
662
- link(value),
663
- ]),
664
- )
665
-
666
- const classRules = Object.fromEntries(
667
- Object.entries(
668
- data.classRules === undefined ? {} : record(data.classRules),
669
- ).map(([name, body]) => {
670
- if (!name || /\s/.test(name))
671
- throw new Error('Invalid packed class name.')
672
- return [name, string(body)]
673
- }),
674
- )
675
-
676
- return {
677
- classRules,
678
- links,
679
- themes,
680
- stylesheets: Stylesheets.read(data.stylesheets),
681
- }
682
- }
683
-
684
- function record(value: unknown): Record<string, unknown> {
685
- if (!value || typeof value !== 'object' || Array.isArray(value))
686
- throw new Error('Expected a Zyzz contract record.')
687
-
688
- return value as Record<string, unknown>
689
- }
690
-
691
- function string(value: unknown): string {
692
- if (typeof value !== 'string' || !value)
693
- throw new Error('Expected a nonempty Zyzz contract identity.')
694
-
695
- return value
696
- }
697
-
698
- function input(theme: Theme.Definition) {
699
- return { ...tokens(theme.tokens), ...theme[Token.definition].queries }
700
- }
701
-
702
- function tokens(tree: Theme.References<Theme.Tokens>): Record<string, unknown> {
703
- return Object.fromEntries(
704
- Object.entries(tree).map(([name, value]) => [
705
- name,
706
- Token.is(value)
707
- ? value.value
708
- : tokens(value as Theme.References<Theme.Tokens>),
709
- ]),
710
- )
711
- }
712
-
713
- function type(value: unknown): string {
714
- if (Token.is(value) || Token.isExpression(value))
715
- return Configurations.type(value)
716
- if (Array.isArray(value)) return `readonly [${value.map(type).join(',')}]`
717
- if (!value || typeof value !== 'object') return JSON.stringify(value)
718
-
719
- return `{${Object.entries(value)
720
- .map(([key, value]) => `readonly ${JSON.stringify(key)}:${type(value)}`)
721
- .join(';')}}`
722
- }
723
-
724
- /** Emits compiler-only metadata without adding it to the runtime module. */
725
- export function write(
726
- links: Readonly<Record<string, Themes.Link>>,
727
- themes: Readonly<Record<string, Theme.Definition>>,
728
- stylesheets: readonly Stylesheets.Section[] = [],
729
- moduleId = '',
730
- configurations: readonly write.Configuration[] = [],
731
- classRules: Readonly<Record<string, string>> = {},
732
- ): string {
733
- function entry(link: Themes.Link): Record<string, unknown> {
734
- if (link.kind === 'variables')
735
- return {
736
- binding: link.binding,
737
- kind: link.kind,
738
- variables: link.call.variables,
739
- ...(link.members
740
- ? {
741
- members: Object.fromEntries(
742
- Object.entries(link.members).map(([name, member]) => [
743
- name,
744
- entry(member),
745
- ]),
746
- ),
747
- }
748
- : {}),
749
- ...(link.call.variableOwner
750
- ? { source: Stylesheets.relative(moduleId, link.call.variableOwner) }
751
- : {}),
752
- }
753
- if (link.kind === 'rule-reference')
754
- return {
755
- binding: link.binding,
756
- kind: link.kind,
757
- name: link.call.name,
758
- reference: link.call.reference,
759
- ...(link.call.function ? { function: link.call.function } : {}),
760
- }
761
-
762
- if (link.kind === 'animation')
763
- return { binding: link.binding, kind: link.kind, name: link.call.name }
764
-
765
- if (link.kind === 'style-reference')
766
- return {
767
- binding: link.binding,
768
- kind: link.kind,
769
- ...(link.style?.nativeContext
770
- ? {
771
- nativeContext: {
772
- defaultVars: link.style.nativeContext.defaultVars,
773
- vars: Object.fromEntries(
774
- Object.entries(link.style.nativeContext.vars).map((entry) => {
775
- const [name, definition] = entry
776
- const theme = Object.entries(themes).find(
777
- (candidate) =>
778
- candidate[1][Token.definition].contract ===
779
- definition[Token.definition].contract &&
780
- JSON.stringify(input(candidate[1])) ===
781
- JSON.stringify(input(definition)),
782
- )
783
- if (!theme)
784
- throw new Error('Missing packed native style catalog.')
785
- return [name, theme[0]]
786
- }),
787
- ),
788
- },
789
- }
790
- : {}),
791
- ...(link.style ? { style: PackedStyles.write(link.style) } : {}),
792
- ...(link.members
793
- ? {
794
- members: Object.fromEntries(
795
- Object.entries(link.members).map(([name, value]) => [
796
- name,
797
- entry(value),
798
- ]),
799
- ),
800
- }
801
- : {}),
802
- }
803
-
804
- return {
805
- ...(link.call.variableSet ? { variableSet: true } : {}),
806
- ...(link.call.nativeProvider ? { nativeProvider: true } : {}),
807
- ...(link.call.directVariables ? { directVariables: true } : {}),
808
- ...(link.call.variableConfig
809
- ? { variableConfig: true, variableMappings: link.call.variableMappings }
810
- : {}),
811
- ...(link.call.recipe ? { recipe: true } : {}),
812
- ...(link.call.output ? { output: link.call.output } : {}),
813
- ...(link.call.script &&
814
- (link.kind === 'config' || link.call.initialization)
815
- ? { script: true }
816
- : {}),
817
- ...(link.call.appearance && (link.kind === 'config' || link.call.root)
818
- ? { appearance: true }
819
- : {}),
820
- binding: link.binding,
821
- kind: link.kind,
822
- theme: link.call.name,
823
- ...(link.call.catalogOnly ? { catalogOnly: true } : {}),
824
- ...(link.call.selection ? { selection: true } : {}),
825
- ...(link.call.initialization ? { initialization: true } : {}),
826
- ...(link.call.root ? { root: true } : {}),
827
- ...(link.call.options ? { options: encode(link.call.options) } : {}),
828
- ...(link.members
829
- ? {
830
- members: Object.fromEntries(
831
- Object.entries(link.members).map(([key, link]) => [
832
- key,
833
- entry(link),
834
- ]),
835
- ),
836
- }
837
- : {}),
838
- }
839
- }
840
-
841
- return JSON.stringify({
842
- ...(Object.keys(classRules).length ? { classRules } : {}),
843
- ...(stylesheets.length
844
- ? { stylesheets: Stylesheets.write(stylesheets) }
845
- : {}),
846
- // Local configurations publish their catalogs so documents restore
847
- // selections for modules that export styles but not the configuration.
848
- ...(configurations.length ? { configurations } : {}),
849
- exports: Object.fromEntries(
850
- Object.entries(links).map(([name, link]) => [name, entry(link)]),
851
- ),
852
- themes: Object.fromEntries(
853
- Object.entries(themes).map(([name, theme]) => [
854
- name,
855
- {
856
- ...(theme[Token.definition].cssName !== undefined
857
- ? { cssName: theme[Token.definition].cssName }
858
- : {}),
859
- ...(theme[Token.definition].contract.shorthands
860
- ? { shorthands: theme[Token.definition].contract.shorthands }
861
- : {}),
862
- ...(theme[Token.definition].contract.defaultLayer !== undefined
863
- ? { defaultLayer: theme[Token.definition].contract.defaultLayer }
864
- : {}),
865
- ...(theme[Token.definition].contract.composition
866
- ? { composition: theme[Token.definition].contract.composition }
867
- : {}),
868
- ...(theme[Token.definition].contract.cssOutput
869
- ? { cssOutput: theme[Token.definition].contract.cssOutput }
870
- : {}),
871
- ...(theme[Token.definition].contract.variableSet
872
- ? {
873
- variableSet: true,
874
- mappings: theme[Token.definition].contract.mappings,
875
- }
876
- : {}),
877
- identity: theme[Token.definition].contract[Token.identity],
878
- tokens: encode(input(theme)),
879
- },
880
- ]),
881
- ),
882
- version: (() => {
883
- if (
884
- Object.values(themes).some(
885
- (theme) => theme[Token.definition].contract.composition,
886
- ) ||
887
- Object.values(links).some(composed)
888
- )
889
- return 34
890
-
891
- if (Object.values(links).some(nativeCatalog)) return 33
892
- if (Object.values(links).some(nativeProvider)) return 32
893
-
894
- return 31
895
- })(),
896
- })
897
-
898
- function composed(link: Themes.Link): boolean {
899
- return (
900
- Boolean(link.style?.style.composition) ||
901
- Object.values(link.members ?? {}).some(composed)
902
- )
903
- }
904
-
905
- function nativeProvider(link: Themes.Link): boolean {
906
- return (
907
- link.call.nativeProvider === true ||
908
- Object.values(link.members ?? {}).some(nativeProvider)
909
- )
910
- }
911
-
912
- function nativeCatalog(link: Themes.Link): boolean {
913
- return (
914
- Boolean(link.style?.nativeContext) ||
915
- Object.values(link.members ?? {}).some(nativeCatalog)
916
- )
917
- }
918
- }
919
-
920
- /** Contract writer contracts. */
921
- export declare namespace write {
922
- /** Catalog of one configuration call, published whether or not the call is exported. */
923
- type Configuration = {
924
- /** Configuration identity that prefixes every theme scope key. */
925
- readonly identity: string
926
- /** localStorage key the configuration's script and root controls share. */
927
- readonly storageKey?: string | undefined
928
- /** Named theme keys of the configuration's catalog. */
929
- readonly themes: readonly string[]
930
- }
931
- }
932
-
933
- function signature(
934
- input: unknown,
935
- version: number,
936
- ): NonNullable<Themes.Call['function']> {
937
- const value = record(input)
938
- if (
939
- !FunctionSyntax.accepts(string(value.returns)) ||
940
- !Array.isArray(value.parameters)
941
- )
942
- throw new Error('Invalid packed CSS function signature.')
943
- if (
944
- version < 12 &&
945
- (/[\\\u0080-\uffff]/.test(String(value.returns)) ||
946
- value.parameters.some((input) => {
947
- const parameter = record(input)
948
- return /[\\\u0080-\uffff]/.test(
949
- string(parameter.name) + string(parameter.syntax ?? '*'),
950
- )
951
- }))
952
- )
953
- throw new Error(
954
- 'Extended CSS function signatures require contract version 12.',
955
- )
956
- const names = new Set<string>()
957
- const parameters = value.parameters.map((input: unknown) => {
958
- const parameter = record(input)
959
- const name = string(parameter.name)
960
- if (
961
- !Identifiers.read(name)?.startsWith('--') ||
962
- Identifiers.read(name) === '--' ||
963
- names.has(Identifiers.read(name)!) ||
964
- (parameter.syntax !== undefined &&
965
- !FunctionSyntax.accepts(string(parameter.syntax))) ||
966
- (parameter.default !== undefined &&
967
- typeof parameter.default !== 'number' &&
968
- typeof parameter.default !== 'string')
969
- )
970
- throw new Error('Invalid packed CSS function parameter.')
971
- names.add(Identifiers.read(name)!)
972
- return {
973
- name: name as `--${string}`,
974
- ...(parameter.syntax !== undefined
975
- ? {
976
- syntax: parameter.syntax as NonNullable<
977
- Themes.Call['function']
978
- >['returns'],
979
- }
980
- : {}),
981
- ...(parameter.default !== undefined
982
- ? { default: parameter.default as string | number }
983
- : {}),
984
- }
985
- })
986
- return {
987
- parameters,
988
- returns: value.returns as NonNullable<Themes.Call['function']>['returns'],
989
- }
990
- }
991
-
992
- function encode(value: unknown): unknown {
993
- if (Token.isExpression(value) && 'group' in value)
994
- return {
995
- $composition: { group: value.group, parts: value.parts.map(encode) },
996
- }
997
- if (Token.is(value))
998
- return {
999
- $variable: {
1000
- identity: value.contract[Token.identity],
1001
- path: value.path,
1002
- value: encode(value.value),
1003
- },
1004
- }
1005
- if (Array.isArray(value)) return value.map(encode)
1006
- if (!value || typeof value !== 'object') return value
1007
- const fields = Object.fromEntries(
1008
- Object.entries(value).map(([key, value]) => [key, encode(value)]),
1009
- )
1010
- return Object.hasOwn(fields, '$composition') ||
1011
- Object.hasOwn(fields, '$variable') ||
1012
- Object.hasOwn(fields, '$object')
1013
- ? { $object: fields }
1014
- : fields
1015
- }
1016
-
1017
- function variableOptions(
1018
- options: Record<string, unknown>,
1019
- mappings?: Vars.Mappings | false,
1020
- ): Config.VariableOptions {
1021
- const { theme, themes, defaultTheme, ...rest } = options
1022
- return {
1023
- ...rest,
1024
- vars: (themes ?? theme) as Vars.Values,
1025
- ...(themes ? { defaultVars: String(defaultTheme) } : {}),
1026
- ...(mappings !== undefined ? { mappings } : {}),
1027
- }
1028
- }