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,1459 +1,74 @@
1
- /**
2
- * Links a closed graph of source modules without executing code or reading files.
3
- * @module
4
- */
5
- import * as Contributions from './internal/Contributions.js';
6
- import * as Stylesheets from './internal/Stylesheets.js';
7
- import * as Css from '../web/Css.js';
1
+ import * as Addon from '../internal/Addon.js';
8
2
  import * as ClassName from '../web/internal/ClassName.js';
9
- import * as Native from './Native.js';
10
- import * as NativeVars from './internal/NativeVars.js';
11
- import * as NativeStyleSheet from '../react-native/StyleSheet.js';
12
- import * as Edits from './internal/Edits.js';
13
- import * as Identity from '../internal/Identity.js';
14
- import * as Parser from 'oxc-parser';
15
- import * as Syntax from './internal/Syntax.js';
16
- import * as Walker from 'oxc-walker';
17
- import * as Token from '../internal/Token.js';
18
- import * as Contract from './internal/Contract.js';
19
- import * as Relative from './internal/Relative.js';
20
3
  import * as ThemeRules from '../web/internal/Themes.js';
21
- import * as Themes from './internal/Themes.js';
22
- import * as Source from './Source.js';
23
- import * as Scope from './internal/Scope.js';
24
- import * as Static from './internal/Static.js';
25
- import * as Transform from './Transform.js';
4
+ import * as Results from './internal/Results.js';
5
+ import * as Stylesheets from './internal/Stylesheets.js';
26
6
  /** Compiles supplied modules with shared theme contracts and dependency metadata. */
27
7
  export function compile(options) {
28
- return build(options).result;
8
+ return Results.graph(Results.call('graph.compile', encode(options)));
29
9
  }
30
- /** Creates an isolated compiler with bounded extraction reuse across source graphs. */
31
- export function create() {
32
- let previous;
33
- return Object.freeze({
34
- compile(options) {
35
- const next = build(options, previous);
36
- previous = next;
37
- return next.result;
38
- },
39
- });
10
+ /** The engine's answer when a snapshot names a source it no longer holds. */
11
+ const stale = '{"stale":true}';
12
+ /** Names each source equal to the one `previous` held as `0`. */
13
+ function unchanged(sources, previous) {
14
+ if (!sources || !previous)
15
+ return sources;
16
+ const output = {};
17
+ for (const [id, source] of Object.entries(sources))
18
+ output[id] = previous[id] === source ? 0 : source;
19
+ return output;
40
20
  }
41
- function build(options, cache) {
42
- if (!!cache?.native !== !!options.native ||
43
- cache?.native?.[Edits.runtime] !== options.native?.[Edits.runtime] ||
44
- Object.keys(cache?.native ?? {}).length !==
45
- Object.keys(options.native ?? {}).length ||
46
- Object.entries(cache?.native ?? {}).some(([key, value]) => {
47
- const next = Reflect.get(options.native ?? {}, key);
48
- if (key !== 'fonts' && key !== 'vars' && key !== 'units')
49
- return value !== next;
50
- return (!!value !== !!next ||
51
- Object.keys(value ?? {}).length !== Object.keys(next ?? {}).length ||
52
- Object.entries(value ?? {}).some(([name, entry]) => Reflect.get(next ?? {}, name) !== entry));
53
- }))
54
- cache = undefined;
55
- if (options.native && options.reset !== undefined)
56
- throw new Native.CompileError('The CSS reset is only supported by web builds.');
57
- if (options.native && options.compiler === false)
58
- throw new Native.CompileError('Native graph compilation requires source rewriting.');
59
- if (cache?.compiler !== (options.compiler !== false))
60
- cache = undefined;
61
- if (cache?.reset !== options.reset)
62
- cache = undefined;
63
- if (cache?.cssOutput !== options.cssOutput)
64
- cache = undefined;
65
- if (cache?.composition !== options.composition)
66
- cache = undefined;
67
- if (cache?.shared !== options[ThemeRules.shared])
68
- cache = undefined;
69
- if ((cache?.entry === undefined) !==
70
- (options[Stylesheets.entry] === undefined))
71
- cache = undefined;
72
- const ids = Object.keys(options.modules).sort();
73
- const programs = new Map();
74
- function parse(input) {
75
- const cached = programs.get(input.moduleId) ?? options[Syntax.cache]?.get(input.moduleId);
76
- if (cached)
77
- return cached;
78
- const parsed = Syntax.parse(input);
79
- programs.set(input.moduleId, parsed);
80
- return parsed;
81
- }
82
- const contracts = JSON.stringify(Object.entries(options.contracts ?? {}).sort(([a], [b]) => a.localeCompare(b)));
83
- const resolutions = Object.fromEntries([...new Set([...ids, ...Object.keys(options.imports ?? {})])]
84
- .sort()
85
- .map((id) => [
86
- id,
87
- options.imports === undefined
88
- ? 'relative'
89
- : JSON.stringify(Object.entries(options.imports[id] ?? {}).sort(([a], [b]) => a.localeCompare(b))),
90
- ]));
91
- // Host resolutions remain explicit when generated modules enter or leave the graph.
92
- const previous = (() => {
93
- if (cache &&
94
- cache.contracts === contracts &&
95
- cache.development === !!options.development &&
96
- (options.imports !== undefined ||
97
- (ids.length === Object.keys(cache.sources).length &&
98
- ids.every((id) => Object.hasOwn(cache.sources, id))))) {
99
- return cache;
100
- }
101
- return undefined;
102
- })();
103
- if (previous &&
104
- previous.entry === options[Stylesheets.entry] &&
105
- ids.length === Object.keys(previous.sources).length &&
106
- Object.keys(resolutions).length ===
107
- Object.keys(previous.resolutions).length &&
108
- Object.entries(resolutions).every(([id, value]) => value === previous.resolutions[id]) &&
109
- ids.every((id) => options.modules[id] === previous.sources[id] &&
110
- resolutions[id] === previous.resolutions[id]))
111
- return previous;
112
- const retained = new Map(previous?.retained);
113
- const transformed = new Map(previous?.transformed);
114
- const dependencies = Object.create(null);
115
- const extracted = new Map();
116
- const identifiers = new Map();
117
- const owners = Object.create(null);
118
- const themes = Object.create(null);
119
- const visiting = new Set();
120
- const libraries = Object.create(null);
121
- const identities = new Map();
122
- const variableSlots = new Map();
123
- function validateLibraryLink(link, owner) {
124
- const variableOwner = owner.includes('/')
125
- ? (link.call.variableOwner ?? owner)
126
- : owner;
127
- for (const slot of Object.values(link.call.variables ?? {})) {
128
- const previous = variableSlots.get(slot.name);
129
- if (previous &&
130
- (previous.owner !== variableOwner ||
131
- previous.binding !== link.binding ||
132
- previous.type !== slot.type))
133
- throw new Error(`Conflicting packed variable identity: ${slot.name}; supply distinct declaration ids.`);
134
- variableSlots.set(slot.name, {
135
- owner: variableOwner,
136
- binding: link.binding,
137
- type: slot.type,
138
- });
139
- }
140
- for (const member of Object.values(link.members ?? {}))
141
- validateLibraryLink(member, owner);
142
- }
143
- for (const [id, source] of Object.entries(options.contracts ?? {})) {
144
- if (Object.hasOwn(options.modules, id))
145
- fail(id, 'A module cannot supply both source and a library contract.');
146
- try {
147
- const library = previous?.libraries[id] ?? Contract.read(source, identities, id);
148
- for (const link of Object.values(library.links))
149
- validateLibraryLink(link, id);
150
- for (const [name, theme] of Object.entries(library.themes)) {
151
- if (themes[name] &&
152
- Contract.write({}, { [name]: themes[name] }) !==
153
- Contract.write({}, { [name]: theme }))
154
- throw new Error(`Conflicting library theme identity: ${name}`);
155
- themes[name] = theme;
156
- }
157
- libraries[id] = library;
158
- }
159
- catch (error) {
160
- fail(id, `Invalid library contract: ${error.message}`);
161
- }
162
- }
163
- function fail(moduleId, message, node) {
164
- throw new Source.ExtractError([
165
- {
166
- code: 'unsupported_syntax',
167
- end: node?.end ?? 0,
168
- message,
169
- source: moduleId,
170
- start: node?.start ?? 0,
171
- },
172
- ]);
173
- }
174
- function resolve(moduleId, specifier, node = { start: 0, end: 0 }) {
175
- if (options.imports !== undefined) {
176
- const imports = options.imports[moduleId];
177
- if (!imports || !Object.hasOwn(imports, specifier))
178
- fail(moduleId, `Missing host resolution: ${specifier}`, node);
179
- const target = imports[specifier];
180
- if (target === null)
181
- return undefined;
182
- if (target === undefined ||
183
- (!Object.hasOwn(options.modules, target) &&
184
- !Object.hasOwn(libraries, target)))
185
- fail(moduleId, `Missing host source module: ${specifier}`, node);
186
- return target;
187
- }
188
- try {
189
- return Relative.resolve({ moduleId, modules: options.modules, specifier });
190
- }
191
- catch (error) {
192
- fail(moduleId, error.message, node);
193
- }
194
- }
195
- const constants = new Map();
196
- function constant(moduleId, name, active = new Set()) {
197
- const key = JSON.stringify([moduleId, name]);
198
- if (constants.has(key))
199
- return constants.get(key);
200
- if (active.has(key) || !Object.hasOwn(options.modules, moduleId))
201
- return undefined;
202
- const next = new Set(active).add(key);
203
- const program = parse({
204
- moduleId,
205
- source: options.modules[moduleId],
206
- }).program;
207
- const imports = Object.create(null);
208
- let local = name;
209
- let exported = false;
210
- let direct;
211
- const stars = [];
212
- for (const statement of program.body) {
213
- if (statement.type === 'ExportDefaultDeclaration' && name === 'default') {
214
- direct = statement.declaration;
215
- exported = true;
216
- }
217
- if (statement.type === 'ExportAllDeclaration' &&
218
- statement.exportKind !== 'type' &&
219
- !statement.exported &&
220
- name !== 'default') {
221
- const target = resolve(moduleId, statement.source.value, statement);
222
- if (target)
223
- stars.push(target);
224
- }
225
- if (statement.type !== 'ExportNamedDeclaration' ||
226
- statement.exportKind === 'type')
227
- continue;
228
- if (statement.declaration?.type === 'VariableDeclaration')
229
- exported ||= statement.declaration.declarations.some((value) => value.id.type === 'Identifier' && value.id.name === name);
230
- for (const specifier of statement.specifiers) {
231
- if (specifier.exportKind === 'type')
232
- continue;
233
- const alias = specifier.exported.type === 'Identifier'
234
- ? specifier.exported.name
235
- : specifier.exported.value;
236
- if (alias !== name)
237
- continue;
238
- local =
239
- specifier.local.type === 'Identifier'
240
- ? specifier.local.name
241
- : specifier.local.value;
242
- if (statement.source) {
243
- const target = resolve(moduleId, statement.source.value, statement);
244
- return target ? constant(target, local, next) : undefined;
245
- }
246
- exported = true;
247
- }
248
- }
249
- if (!exported) {
250
- const candidates = [
251
- ...new Set(stars
252
- .map((target) => constant(target, name, next))
253
- .filter((value) => value !== undefined)),
254
- ];
255
- const value = candidates.length === 1 ? candidates[0] : undefined;
256
- if (value || !stars.length)
257
- constants.set(key, value);
258
- return value;
259
- }
260
- if (direct &&
261
- [
262
- 'FunctionDeclaration',
263
- 'FunctionExpression',
264
- 'ArrowFunctionExpression',
265
- 'ClassDeclaration',
266
- 'ClassExpression',
267
- ].includes(direct.type)) {
268
- constants.set(key, undefined);
269
- return undefined;
270
- }
271
- for (const statement of program.body) {
272
- if (statement.type === 'ImportDeclaration' &&
273
- statement.importKind !== 'type') {
274
- const target = resolve(moduleId, statement.source.value, statement);
275
- if (!target)
276
- continue;
277
- for (const specifier of statement.specifiers) {
278
- if (specifier.type === 'ImportNamespaceSpecifier' ||
279
- (specifier.type === 'ImportSpecifier' &&
280
- specifier.importKind === 'type'))
281
- continue;
282
- const imported = specifier.type === 'ImportDefaultSpecifier'
283
- ? 'default'
284
- : specifier.imported.type === 'Identifier'
285
- ? specifier.imported.name
286
- : specifier.imported.value;
287
- const value = constant(target, imported, next);
288
- if (value)
289
- imports[specifier.local.name] = relocate(value, specifier);
290
- }
291
- }
292
- }
293
- const scope = new Scope.Tracker({ preserveExitedScopes: true });
294
- Walker.walk(program, { scopeTracker: scope });
295
- scope.freeze();
296
- let value;
297
- try {
298
- const data = Static.collect(program, scope, imports);
299
- value = direct
300
- ? data.normalize(direct, new Set(), new Set(), true)
301
- : data.exported(local);
302
- }
303
- catch {
304
- return undefined;
305
- }
306
- if (value && !literal(value))
307
- value = undefined;
308
- constants.set(key, value);
309
- return value;
310
- }
311
- function literal(node, depth = 0) {
312
- if (depth > 64)
313
- return false;
314
- if (node.type === 'Literal')
315
- return (node.value === null ||
316
- ['string', 'number', 'boolean'].includes(typeof node.value));
317
- if (node.type === 'UnaryExpression')
318
- return (['+', '-'].includes(node.operator) &&
319
- node.argument.type === 'Literal' &&
320
- typeof node.argument.value === 'number');
321
- if (node.type === 'TemplateLiteral')
322
- return !node.expressions.length;
323
- if (node.type === 'ArrayExpression')
324
- return node.elements.every((value) => value && literal(value, depth + 1));
325
- return (node.type === 'ObjectExpression' &&
326
- node.properties.every((property) => property.type === 'Property' &&
327
- !property.method &&
328
- property.kind === 'init' &&
329
- (!property.computed || property.key.type === 'Literal') &&
330
- literal(property.value, depth + 1)));
331
- }
332
- function relocate(node, span) {
333
- const copy = structuredClone(node);
334
- Walker.walk(copy, {
335
- enter(node) {
336
- node.start = span.start;
337
- node.end = span.end;
338
- },
339
- });
340
- return copy;
341
- }
342
- const factoryPrograms = new Map();
343
- function factory(moduleId, name, seen = new Set()) {
344
- if (moduleId === 'zyzz/web')
345
- return Contributions.factories.includes(name) ? name : undefined;
346
- const key = `${moduleId}#${name}`;
347
- if (seen.has(key) || !Object.hasOwn(options.modules, moduleId))
348
- return undefined;
349
- const next = new Set(seen).add(key);
350
- const program = factoryPrograms.get(moduleId) ??
351
- Parser.parseSync('barrel.ts', options.modules[moduleId], {
352
- sourceType: 'module',
353
- }).program;
354
- factoryPrograms.set(moduleId, program);
355
- const target = (specifier, node) => specifier === 'zyzz/web' ? specifier : resolve(moduleId, specifier, node);
356
- for (const node of program.body) {
357
- if (node.type !== 'ExportNamedDeclaration' || node.exportKind === 'type')
358
- continue;
359
- const declaration = node.declaration;
360
- if (declaration?.type === 'VariableDeclaration' &&
361
- declaration.declarations.some((item) => item.id.type === 'Identifier' && item.id.name === name))
362
- return undefined;
363
- if ((declaration?.type === 'FunctionDeclaration' ||
364
- declaration?.type === 'ClassDeclaration') &&
365
- declaration.id?.name === name)
366
- return undefined;
367
- for (const specifier of node.specifiers) {
368
- if (specifier.exportKind === 'type')
369
- continue;
370
- const exported = specifier.exported.type === 'Identifier'
371
- ? specifier.exported.name
372
- : specifier.exported.value;
373
- if (exported !== name)
374
- continue;
375
- const local = specifier.local.type === 'Identifier'
376
- ? specifier.local.name
377
- : specifier.local.value;
378
- if (node.source) {
379
- const id = target(node.source.value, node);
380
- return id ? factory(id, local, next) : undefined;
381
- }
382
- for (const declaration of program.body) {
383
- if (declaration.type !== 'ImportDeclaration' ||
384
- declaration.importKind === 'type')
385
- continue;
386
- for (const imported of declaration.specifiers) {
387
- if (imported.type !== 'ImportSpecifier' ||
388
- imported.importKind === 'type' ||
389
- imported.local.name !== local)
390
- continue;
391
- const id = target(declaration.source.value, declaration);
392
- return id
393
- ? factory(id, imported.imported.type === 'Identifier'
394
- ? imported.imported.name
395
- : imported.imported.value, next)
396
- : undefined;
397
- }
398
- }
399
- return undefined;
400
- }
401
- }
402
- for (const node of program.body) {
403
- if (node.type === 'ExportAllDeclaration' &&
404
- node.exportKind !== 'type' &&
405
- !node.exported) {
406
- const id = target(node.source.value, node);
407
- const found = id ? factory(id, name, next) : undefined;
408
- if (found)
409
- return found;
410
- }
411
- }
412
- return undefined;
413
- }
414
- function visit(moduleId) {
415
- const cached = extracted.get(moduleId);
416
- if (cached)
417
- return cached;
418
- if (visiting.has(moduleId))
419
- fail(moduleId, 'Circular source dependencies are not supported yet.');
420
- visiting.add(moduleId);
421
- const source = options.modules[moduleId];
422
- const snapshot = previous?.retained.get(moduleId) ??
423
- (previous && Object.hasOwn(previous.sources, moduleId)
424
- ? {
425
- dependencies: previous.result.dependencies[moduleId],
426
- extracted: previous.extracted.get(moduleId),
427
- inputs: new Map(previous.result.dependencies[moduleId].map((target) => [
428
- target,
429
- previous.libraries[target] ?? previous.extracted.get(target),
430
- ])),
431
- resolution: previous.resolutions[moduleId],
432
- source: previous.sources[moduleId],
433
- }
434
- : undefined);
435
- if (snapshot &&
436
- source === snapshot.source &&
437
- resolutions[moduleId] === snapshot.resolution &&
438
- snapshot.dependencies.every((target) => Object.hasOwn(libraries, target)
439
- ? libraries[target] === snapshot.inputs.get(target)
440
- : Object.hasOwn(options.modules, target) &&
441
- visit(target) === snapshot.inputs.get(target))) {
442
- return retain(moduleId, snapshot.extracted, snapshot.dependencies);
443
- }
444
- // Validate identity and syntax through the public source boundary before linking.
445
- Source.extract({ moduleId, source: '' });
446
- const parsed = parse({ moduleId, source });
447
- if (parsed.errors.length)
448
- Source.extract({ moduleId, source });
449
- factoryPrograms.set(moduleId, parsed.program);
450
- const names = new Set();
451
- identifiers.set(moduleId, names);
452
- Walker.walk(parsed.program, {
453
- enter(node) {
454
- if (node.type === 'Identifier')
455
- names.add(node.name);
456
- if (options.imports === undefined &&
457
- node.type === 'ImportExpression' &&
458
- (node.source.type !== 'Literal' ||
459
- typeof node.source.value !== 'string' ||
460
- node.source.value.startsWith('.')))
461
- fail(moduleId, 'Source graph dependencies require static imports.', node);
462
- },
463
- });
464
- const values = Object.create(null);
465
- const links = Object.create(null);
466
- const forwarded = Object.create(null);
467
- const explicit = new Set();
468
- const stars = [];
469
- const imports = new Set();
470
- function exportedBindings(node) {
471
- if (node.type === 'Identifier')
472
- explicit.add(node.name);
473
- else if (node.type === 'ObjectPattern')
474
- for (const property of node.properties)
475
- exportedBindings(property.type === 'Property' ? property.value : property.argument);
476
- else if (node.type === 'ArrayPattern')
477
- for (const element of node.elements) {
478
- if (element)
479
- exportedBindings(element);
480
- }
481
- else if (node.type === 'AssignmentPattern')
482
- exportedBindings(node.left);
483
- else if (node.type === 'RestElement')
484
- exportedBindings(node.argument);
485
- }
486
- for (const node of parsed.program.body) {
487
- if (node.type === 'ExportNamedDeclaration' &&
488
- !node.source &&
489
- node.exportKind !== 'type') {
490
- for (const specifier of node.specifiers)
491
- if (specifier.exportKind !== 'type')
492
- explicit.add(specifier.exported.type === 'Identifier'
493
- ? specifier.exported.name
494
- : specifier.exported.value);
495
- if (node.declaration?.type === 'VariableDeclaration')
496
- for (const declaration of node.declaration.declarations)
497
- exportedBindings(declaration.id);
498
- else if ((node.declaration?.type === 'FunctionDeclaration' ||
499
- node.declaration?.type === 'ClassDeclaration') &&
500
- node.declaration.id)
501
- explicit.add(node.declaration.id.name);
502
- }
503
- if ((node.type !== 'ImportDeclaration' &&
504
- node.type !== 'ExportNamedDeclaration' &&
505
- node.type !== 'ExportAllDeclaration') ||
506
- !node.source)
507
- continue;
508
- if (node.type === 'ImportDeclaration'
509
- ? node.importKind === 'type'
510
- : node.exportKind === 'type')
511
- continue;
512
- if ('specifiers' in node &&
513
- node.specifiers.length &&
514
- node.specifiers.every((specifier) => specifier.type === 'ImportSpecifier'
515
- ? specifier.importKind === 'type'
516
- : specifier.type === 'ExportSpecifier' &&
517
- specifier.exportKind === 'type'))
518
- continue;
519
- const target = resolve(moduleId, node.source.value, node);
520
- if (!target)
521
- continue;
522
- imports.add(target);
523
- const contracts = libraries[target]?.links ?? visit(target).themeExports ?? {};
524
- function namespace(name) {
525
- const first = Object.values(contracts)[0];
526
- if (!first)
527
- return undefined;
528
- return {
529
- binding: `z-style-${Identity.hash(JSON.stringify([moduleId, name]))}-namespace`,
530
- call: { start: -1, end: -1, name: '', tokenType: '{}' },
531
- definition: first.definition,
532
- kind: 'style-reference',
533
- members: contracts,
534
- };
535
- }
536
- if (node.type === 'ImportDeclaration') {
537
- for (const specifier of node.specifiers) {
538
- if (specifier.type === 'ImportNamespaceSpecifier') {
539
- if (Object.values(contracts).some((link) => link.kind !== 'style-reference'))
540
- fail(moduleId, 'Import theme contracts by name; namespace imports are not supported.', specifier);
541
- const link = namespace(specifier.local.name);
542
- if (link)
543
- links[specifier.local.name] = link;
544
- continue;
545
- }
546
- if (specifier.type === 'ImportSpecifier' &&
547
- specifier.importKind === 'type')
548
- continue;
549
- const name = (() => {
550
- if (specifier.type === 'ImportDefaultSpecifier') {
551
- return 'default';
552
- }
553
- if (specifier.imported.type === 'Identifier') {
554
- return specifier.imported.name;
555
- }
556
- return specifier.imported.value;
557
- })();
558
- if (Object.hasOwn(contracts, name))
559
- links[specifier.local.name] = contracts[name];
560
- else {
561
- const value = constant(target, name);
562
- if (value)
563
- values[specifier.local.name] = relocate(value, specifier);
564
- }
565
- }
566
- }
567
- else if (node.type === 'ExportAllDeclaration') {
568
- if (node.exported) {
569
- if (Object.values(contracts).some((link) => link.kind !== 'style-reference'))
570
- fail(moduleId, 'Namespace theme re-exports are not supported.', node);
571
- const name = node.exported.type === 'Identifier'
572
- ? node.exported.name
573
- : node.exported.value;
574
- explicit.add(name);
575
- const link = namespace(name);
576
- if (link)
577
- forwarded[name] = link;
578
- }
579
- else
580
- stars.push(contracts);
581
- }
582
- else {
583
- for (const specifier of node.specifiers) {
584
- if (specifier.exportKind === 'type')
585
- continue;
586
- const name = specifier.local.type === 'Identifier'
587
- ? specifier.local.name
588
- : specifier.local.value;
589
- const exported = specifier.exported.type === 'Identifier'
590
- ? specifier.exported.name
591
- : specifier.exported.value;
592
- explicit.add(exported);
593
- if (Object.hasOwn(contracts, name))
594
- forwarded[exported] = contracts[name];
595
- }
596
- }
597
- }
598
- const factories = Object.create(null);
599
- for (const node of parsed.program.body) {
600
- if (node.type !== 'ImportDeclaration' ||
601
- node.importKind === 'type' ||
602
- node.specifiers.every((specifier) => specifier.type === 'ImportSpecifier' &&
603
- specifier.importKind === 'type') ||
604
- ['zyzz', 'zyzz/web'].includes(node.source.value))
605
- continue;
606
- const target = resolve(moduleId, node.source.value, node);
607
- if (!target)
608
- continue;
609
- for (const specifier of node.specifiers) {
610
- if (specifier.type !== 'ImportSpecifier' ||
611
- specifier.importKind === 'type')
612
- continue;
613
- const name = specifier.imported.type === 'Identifier'
614
- ? specifier.imported.name
615
- : specifier.imported.value;
616
- const found = factory(target, name);
617
- if (found)
618
- factories[specifier.local.name] = found;
619
- }
620
- }
621
- const result = Source.extract({
622
- target: options.native ? 'native' : 'web',
623
- compiler: options.compiler,
624
- moduleId,
625
- source,
626
- [Themes.context]: { constants: values, factories, links, parsed },
627
- });
628
- function outputLink(link) {
629
- return {
630
- ...link,
631
- ...(link.style
632
- ? {
633
- style: {
634
- ...link.style,
635
- style: {
636
- ...link.style.style,
637
- cssOutput: link.style.style.cssOutput ?? options.cssOutput ?? 'atomic',
638
- },
639
- },
640
- }
641
- : {}),
642
- ...(link.members
643
- ? {
644
- members: Object.fromEntries(Object.entries(link.members).map(([name, member]) => [
645
- name,
646
- outputLink(member),
647
- ])),
648
- }
649
- : {}),
650
- };
651
- }
652
- const exports = Object.assign(Object.create(null), forwarded, Object.fromEntries(Object.entries(result.themeExports ?? {}).map(([name, link]) => [
653
- name,
654
- outputLink(link),
655
- ])));
656
- for (const name of Object.keys(result.themeExports ?? {}))
657
- explicit.add(name);
658
- for (const contracts of stars)
659
- for (const [name, link] of Object.entries(contracts)) {
660
- if (name === 'default' || explicit.has(name))
661
- continue;
662
- const previous = exports[name];
663
- if (previous &&
664
- (previous.binding !== link.binding || previous.kind !== link.kind))
665
- fail(moduleId, `Ambiguous theme re-export: ${name}`);
666
- exports[name] = link;
667
- }
668
- const linked = Object.freeze({
669
- ...result,
670
- themeExports: Object.freeze(exports),
671
- });
672
- return retain(moduleId, linked, Object.freeze([...imports]));
673
- }
674
- function retain(moduleId, result, imports) {
675
- for (const call of result.variableCalls ?? [])
676
- for (const slot of Object.values(call.slots)) {
677
- const owner = moduleId.replace(/\.[cm]?[jt]sx?$/, '');
678
- const previous = variableSlots.get(slot.name);
679
- if (previous &&
680
- (previous.owner !== owner || previous.type !== slot.type))
681
- fail(moduleId, `Conflicting variable identity: ${slot.name}; supply distinct declaration ids.`, call);
682
- variableSlots.set(slot.name, {
683
- owner,
684
- binding: `source:${call.start}`,
685
- type: slot.type,
686
- });
687
- }
688
- extracted.set(moduleId, result);
689
- dependencies[moduleId] = imports;
690
- retained.delete(moduleId);
691
- retained.set(moduleId, {
692
- dependencies: imports,
693
- extracted: result,
694
- inputs: new Map(imports.map((target) => [
695
- target,
696
- libraries[target] ?? extracted.get(target),
697
- ])),
698
- resolution: resolutions[moduleId],
699
- source: options.modules[moduleId],
700
- });
701
- if (retained.size > 256)
702
- retained.delete(retained.keys().next().value);
703
- for (const call of result.themeCalls)
704
- for (const name of new Set([
705
- call.name,
706
- ...Object.values(call.members ?? {}),
707
- ]))
708
- owners[name] = {
709
- call: { ...call, name },
710
- moduleId,
711
- source: options.modules[moduleId],
712
- };
713
- Object.assign(themes, result.vars);
714
- visiting.delete(moduleId);
715
- return result;
716
- }
717
- for (const moduleId of ids)
718
- visit(moduleId);
719
- if (options.native) {
720
- const native = options.native;
721
- function packedLink(link) {
722
- return {
723
- ...link,
724
- ...(link.style
725
- ? { style: { ...link.style, className: link.style.className ?? '' } }
726
- : {}),
727
- ...(link.members
728
- ? {
729
- members: Object.fromEntries(Object.entries(link.members).map(([name, link]) => [
730
- name,
731
- packedLink(link),
732
- ])),
733
- }
734
- : {}),
735
- };
736
- }
737
- const profiles = new Map();
738
- const reserved = new Set([...identifiers.values()].flatMap((names) => [...names]));
739
- function profile(moduleId) {
740
- let value = profiles.get(moduleId);
741
- if (!value) {
742
- value = { definitions: new Map(), reads: new Map() };
743
- profiles.set(moduleId, value);
744
- }
745
- return value;
746
- }
747
- function encode(read) {
748
- try {
749
- return JSON.stringify(NativeVars.compile({
750
- ...read,
751
- fonts: native.fonts,
752
- units: native.units,
753
- }));
754
- }
755
- catch (error) {
756
- throw new Native.CompileError(error.message);
757
- }
758
- }
759
- function define(owner, value) {
760
- const definitions = profile(owner).definitions;
761
- let name = definitions.get(value);
762
- if (!name) {
763
- // Hashing the owner keeps names independent of which modules share the graph.
764
- name = `__zyzzProfile${Identity.hash(owner + value)}`;
765
- while (reserved.has(name))
766
- name += '_';
767
- reserved.add(name);
768
- definitions.set(value, name);
769
- }
770
- return name;
771
- }
772
- if (ids.some((id) => extracted.get(id).nativeVars?.length))
773
- NativeStyleSheet.compile({
774
- fonts: native.fonts,
775
- platform: native.platform,
776
- units: native.units,
777
- styles: { styles: [] },
778
- });
779
- // Single-file adapters compile each owner without its consumers, so owners publish every exported profile.
780
- if (native[Edits.runtime])
781
- for (const moduleId of ids)
782
- for (const link of Object.values(extracted.get(moduleId).themeExports ?? {})) {
783
- if (owners[link.call.name]?.moduleId !== moduleId ||
784
- !(link.call.variableSet ||
785
- (link.kind === 'config' &&
786
- link.call.variableConfig &&
787
- !link.call.initialization &&
788
- !link.call.root)))
789
- continue;
790
- const value = (() => {
791
- try {
792
- return encode(Themes.varsRead(link));
793
- }
794
- catch {
795
- // Consumers that read this profile report the same error.
796
- return undefined;
797
- }
798
- })();
799
- if (value !== undefined)
800
- define(moduleId, value);
801
- }
802
- for (const moduleId of ids) {
803
- for (const read of extracted.get(moduleId).nativeVars ?? []) {
804
- const owner = owners[read.owner]?.moduleId;
805
- // Packed catalogs without source retain their local fallback.
806
- if (!owner || !Object.hasOwn(options.modules, owner))
807
- continue;
808
- const value = encode(read);
809
- const name = native[Edits.runtime]
810
- ? profiles.get(owner)?.definitions.get(value)
811
- : define(owner, value);
812
- if (!name)
813
- continue;
814
- const source = (() => {
815
- if (owner === moduleId)
816
- return undefined;
817
- // Host identities are opaque, so reuse the consumer's own resolved specifier.
818
- if (native[Edits.runtime] && options.imports) {
819
- const imports = options.imports[moduleId] ?? {};
820
- return Object.keys(imports).find((key) => imports[key] === owner);
821
- }
822
- const from = moduleId.split('/').slice(0, -1);
823
- const to = owner.split('/');
824
- while (from.length && from[0] === to[0]) {
825
- from.shift();
826
- to.shift();
827
- }
828
- return ((from.length ? '../'.repeat(from.length) : './') +
829
- to.join('/').replace(/\.([cm]?)tsx?$/, '.$1js'));
830
- })();
831
- if (owner !== moduleId && !source)
832
- continue;
833
- profile(moduleId).reads.set(read.start, {
834
- name,
835
- ...(source ? { source } : {}),
836
- });
837
- }
838
- }
839
- const modules = Object.fromEntries(ids.map((moduleId) => {
840
- // Single-file profiles derive only from this module's extraction and its dependencies.
841
- if (previous &&
842
- (native[Edits.runtime] || !profiles.size) &&
843
- extracted.get(moduleId) === previous.extracted.get(moduleId))
844
- return [moduleId, previous.result.modules[moduleId]];
845
- const imported = Object.create(null);
846
- for (const statement of parse({
847
- moduleId,
848
- source: options.modules[moduleId],
849
- }).program.body) {
850
- if ((statement.type !== 'ImportDeclaration' &&
851
- statement.type !== 'ExportNamedDeclaration' &&
852
- statement.type !== 'ExportAllDeclaration') ||
853
- !statement.source)
854
- continue;
855
- if ((statement.type === 'ImportDeclaration' &&
856
- statement.importKind === 'type') ||
857
- (statement.type !== 'ImportDeclaration' &&
858
- statement.exportKind === 'type'))
859
- continue;
860
- if ('specifiers' in statement &&
861
- statement.specifiers.length &&
862
- statement.specifiers.every((specifier) => specifier.type === 'ImportSpecifier'
863
- ? specifier.importKind === 'type'
864
- : specifier.type === 'ExportSpecifier' &&
865
- specifier.exportKind === 'type'))
866
- continue;
867
- const target = resolve(moduleId, statement.source.value, statement);
868
- if (target && libraries[target])
869
- imported[statement.source.value] = libraries[target].links;
870
- }
871
- const output = Native.compile({
872
- ...native,
873
- [NativeVars.shared]: profiles.get(moduleId),
874
- moduleId,
875
- source: options.modules[moduleId],
876
- [Themes.context]: {
877
- parsed: parse({ moduleId, source: options.modules[moduleId] }),
878
- identifiers: identifiers.get(moduleId),
879
- extracted: extracted.get(moduleId),
880
- libraries: imported,
881
- links: {},
882
- },
883
- });
884
- return [moduleId, nativeOutput(output)];
885
- }));
886
- return {
887
- compiler: true,
888
- composition: options.composition,
889
- contracts,
890
- cssOutput: options.cssOutput,
891
- development: !!options.development,
892
- extracted,
893
- libraries: Object.freeze(libraries),
894
- native: {
895
- ...options.native,
896
- ...(options.native.fonts && { fonts: { ...options.native.fonts } }),
897
- ...(options.native.vars && { vars: { ...options.native.vars } }),
898
- ...(options.native.units && { units: { ...options.native.units } }),
899
- },
900
- reset: options.reset,
901
- entry: options[Stylesheets.entry],
902
- retained,
903
- transformed,
904
- resolutions: Object.freeze(resolutions),
905
- result: Object.freeze({
906
- contracts: Object.freeze(Object.fromEntries(ids
907
- .filter((id) => Object.keys(extracted.get(id).themeExports ?? {}).length)
908
- .map((id) => [
909
- id,
910
- Contract.write(Object.fromEntries(Object.entries(extracted.get(id).themeExports ?? {}).map(([name, link]) => [name, packedLink(link)])), themes, [], id),
911
- ]))),
912
- dependencies: Object.freeze(dependencies),
913
- modules: Object.freeze(modules),
914
- }),
915
- schemes: false,
916
- sources: Object.freeze({ ...options.modules }),
917
- themes: Object.freeze(themes),
918
- };
919
- }
920
- const modules = Object.create(null);
921
- const sharedThemes = Object.freeze(themes);
922
- const sections = new Map();
923
- for (const id of ids) {
924
- const extractedModule = extracted.get(id);
925
- const contributions = extractedModule.contributions ?? [];
926
- if (!contributions.length) {
927
- sections.set(id, []);
928
- continue;
929
- }
930
- sections.set(id, contributions.map((contribution, index) => ({
931
- source: id,
932
- namespaces: extractedModule.namespaces,
933
- key: String(index),
934
- css: contribution.kind === 'layers'
935
- ? ''
936
- : (Css.compile({
937
- styles: { styles: [] },
938
- vars: sharedThemes,
939
- contributions: [contribution],
940
- }).contributionCss ?? ''),
941
- layers: contribution.kind === 'layers' ? [contribution.names] : [],
942
- content: options.modules[id],
943
- start: extractedModule.contributionStarts?.[index] ?? 0,
944
- })));
945
- }
946
- for (const [id, library] of Object.entries(libraries))
947
- sections.set(id, library.stylesheets.map((section) => {
948
- let owner = id;
949
- for (const specifier of section.dependency ?? []) {
950
- const target = resolve(owner, specifier);
951
- if (!target || !Object.hasOwn(libraries, target))
952
- fail(id, 'Repacked stylesheet dependencies require supplied library contracts.');
953
- owner = target;
954
- }
955
- return {
956
- ...section,
957
- owner,
958
- source: Stylesheets.resolve(owner, section.source),
959
- };
960
- }));
961
- const resetOwners = ids.filter((id) => options.modules[id].includes('zyzz/reset.css') &&
962
- parse({
963
- moduleId: id,
964
- source: options.modules[id],
965
- }).program.body.some((node) => node.type === 'ImportDeclaration' &&
966
- node.source.value === 'zyzz/reset.css'));
967
- const layerNames = [
968
- ...new Set(ids.flatMap((id) => reachable(id).flatMap((section) => section.layers.flat()))),
969
- ].filter((name) => name !== 'reset');
970
- for (const resetOwner of resetOwners) {
971
- const entryLayers = [
972
- ...new Set(reachable(resetOwner).flatMap((section) => section.layers.flat())),
973
- ].filter((name) => name !== 'reset');
974
- sections.set(resetOwner, [
975
- {
976
- source: resetOwner,
977
- key: 'optional-reset-order',
978
- css: '',
979
- layers: entryLayers.length
980
- ? entryLayers.map((name) => ['reset', name])
981
- : [['reset']],
982
- },
983
- ...(sections.get(resetOwner) ?? []),
984
- ]);
985
- }
986
- function dependencyPath(from, to) {
987
- const queue = [{ id: from, path: [] }];
988
- const seen = new Set();
989
- while (queue.length) {
990
- const current = queue.shift();
991
- if (current.id === to)
992
- return current.path;
993
- if (seen.has(current.id))
994
- continue;
995
- seen.add(current.id);
996
- for (const [specifier, target] of Object.entries(options.imports?.[current.id] ?? {}))
997
- if (target)
998
- queue.push({ id: target, path: [...current.path, specifier] });
999
- }
1000
- fail(from, 'Repacked stylesheet ownership requires a resolved dependency path.');
1001
- }
1002
- function reachable(id, visited = new Set()) {
1003
- if (visited.has(id))
1004
- return [];
1005
- visited.add(id);
1006
- return [
1007
- ...(dependencies[id] ?? []).flatMap((dependency) => reachable(dependency, visited)),
1008
- ...(sections.get(id) ?? []),
1009
- ];
1010
- }
1011
- const sharedVisited = new Set();
1012
- const packed = [];
1013
- const sharedSections = (() => {
1014
- try {
1015
- const entry = options[Stylesheets.entry];
1016
- const packedSections = entry === undefined
1017
- ? []
1018
- : (dependencies[entry] ?? [])
1019
- .filter((id) => Object.hasOwn(libraries, id))
1020
- .flatMap((id) => reachable(id, sharedVisited));
1021
- const sharedSections = entry === undefined
1022
- ? ids.flatMap((id) => reachable(id, sharedVisited))
1023
- : (sections.get(entry) ?? []);
1024
- if (packedSections.length) {
1025
- // Validate combined ownership and ordering before splitting independently loaded resources.
1026
- Stylesheets.render([...packedSections, ...sharedSections]);
1027
- for (const section of packedSections) {
1028
- packed.push({
1029
- id: JSON.stringify([section.owner, section.source, section.key]),
1030
- ...Stylesheets.render([section]),
1031
- });
1032
- }
1033
- }
1034
- const resetSource = (options.reset === undefined ? undefined : 'zyzz/reset.css') ??
1035
- resetOwners[0] ??
1036
- sharedSections.find((section) => section.key === 'optional-reset-order')
1037
- ?.source;
1038
- if (packed.length) {
1039
- const order = Stylesheets.render([
1040
- ...(resetSource === undefined
1041
- ? []
1042
- : [
1043
- {
1044
- source: resetSource,
1045
- css: '',
1046
- layers: layerNames.length
1047
- ? layerNames.map((name) => ['reset', name])
1048
- : [['reset']],
1049
- },
1050
- ]),
1051
- ...[...packedSections, ...sharedSections].map((section) => ({
1052
- ...section,
1053
- css: '',
1054
- })),
1055
- ]);
1056
- if (order.css)
1057
- packed.unshift({ ...order, id: order.css });
1058
- }
1059
- return [
1060
- ...(resetSource === undefined
1061
- ? []
1062
- : [
1063
- {
1064
- source: resetSource,
1065
- key: 'optional-reset-graph-order',
1066
- css: '',
1067
- layers: layerNames.length
1068
- ? layerNames.map((name) => ['reset', name])
1069
- : [['reset']],
1070
- },
1071
- ]),
1072
- ...sharedSections,
1073
- ...(options.reset === undefined || entry !== undefined
1074
- ? []
1075
- : [
1076
- {
1077
- source: 'zyzz/reset.css',
1078
- key: 'optional-reset',
1079
- css: options.reset,
1080
- content: options.reset,
1081
- layers: [['reset']],
1082
- },
1083
- ]),
1084
- ];
1085
- }
1086
- catch (error) {
1087
- return fail(error instanceof Stylesheets.ConflictError ? error.source : ids[0], error.message);
1088
- }
1089
- })();
1090
- function renderShared(sections) {
1091
- try {
1092
- return Stylesheets.render(sections);
1093
- }
1094
- catch (error) {
1095
- return fail(error instanceof Stylesheets.ConflictError ? error.source : ids[0], error.message);
1096
- }
1097
- }
1098
- const contributions = renderShared(sharedSections);
1099
- // Every stylesheet includes all graph scopes, including unimported alternatives.
1100
- const names = Object.keys(themes);
1101
- const previousNames = Object.keys(previous?.themes ?? {});
1102
- const sameThemes = previous &&
1103
- names.length === previousNames.length &&
1104
- names.every((name, index) => name === previousNames[index] && previous.themes[name] === themes[name]);
1105
- const styleClasses = Object.create(null);
1106
- function published(link) {
1107
- if (link.style?.className !== undefined)
1108
- styleClasses[link.binding] = link.style.className;
1109
- for (const member of Object.values(link.members ?? {}))
1110
- published(member);
1111
- }
1112
- for (const library of Object.values(libraries))
1113
- for (const link of Object.values(library.links))
1114
- published(link);
1115
- const emittedRules = new Map();
1116
- function registerRules(classRules, moduleId) {
1117
- for (const [name, body] of Object.entries(classRules)) {
1118
- const previous = emittedRules.get(name);
1119
- if (previous && previous.body !== body)
1120
- throw new Css.CompileError([
1121
- {
1122
- code: 'identity_collision',
1123
- message: `Generated ${name.startsWith('@scope:') ? `scope ${name.split(':')[1]}` : `class ${name}`} conflicts with module ${previous.moduleId}. Supply distinct config or style ids.`,
1124
- path: [moduleId],
1125
- },
1126
- ]);
1127
- emittedRules.set(name, { body, moduleId });
1128
- }
1129
- }
1130
- for (const [moduleId, library] of Object.entries(libraries))
1131
- registerRules(library.classRules, moduleId);
1132
- if (options.compiler === false) {
1133
- const identities = new Map();
1134
- for (const [moduleId, library] of Object.entries(libraries)) {
1135
- function register(name, signature) {
1136
- const previous = identities.get(name);
1137
- if (previous !== undefined && previous !== signature)
1138
- fail(moduleId, 'The same explicit identity is used for different definitions.');
1139
- identities.set(name, signature);
1140
- }
1141
- for (const [name, theme] of Object.entries(library.themes)) {
1142
- const data = theme[Token.definition];
1143
- if (data.contract[Token.identity]?.startsWith('id-'))
1144
- register(`theme:${name}`, JSON.stringify(data.values));
1145
- }
1146
- function styles(link) {
1147
- for (const name of link.style?.className?.split(' ') ?? [])
1148
- if (name.startsWith('z-style-id-'))
1149
- register(name, Identity.style(link.style.style));
1150
- for (const member of Object.values(link.members ?? {}))
1151
- styles(member);
1152
- }
1153
- for (const link of Object.values(library.links))
1154
- styles(link);
1155
- }
1156
- for (const [moduleId, module] of extracted) {
1157
- function register(name, signature) {
1158
- const previous = identities.get(name);
1159
- if (previous !== undefined && previous !== signature)
1160
- return fail(moduleId, 'The same explicit identity is used for different definitions.');
1161
- identities.set(name, signature);
1162
- }
1163
- for (const [name, theme] of Object.entries(module.vars)) {
1164
- const data = theme[Token.definition];
1165
- if (data.contract[Token.identity]?.startsWith('id-'))
1166
- register(`theme:${name}`, JSON.stringify(data.values));
1167
- }
1168
- for (const contribution of module.contributions ?? [])
1169
- if ('name' in contribution)
1170
- register(`${contribution.kind}:${contribution.name}`, Css.compile({
1171
- styles: { styles: [] },
1172
- contributions: [contribution],
1173
- }).css);
1174
- for (const call of module.calls) {
1175
- if (!call.portable?.startsWith('z-style-id-'))
1176
- continue;
1177
- const signature = Identity.style(module.styles.styles.find((style) => style.name === call.name));
1178
- const previous = identities.get(call.portable);
1179
- if (previous !== undefined && previous !== signature)
1180
- return fail(moduleId, 'The same explicit style id is used for different declarations.');
1181
- identities.set(call.portable, signature);
1182
- }
1183
- }
1184
- }
1185
- // Selection anywhere in the graph applies scheme classes beside scopes every
1186
- // stylesheet carries, so each stylesheet declares the matching color-scheme.
1187
- const schemes = [...extracted.values()].some((module) => Boolean(module.themeAppearances?.length ||
1188
- module.themeScripts?.length ||
1189
- module.themeSelections?.length));
1190
- const ownerSignature = JSON.stringify(owners);
1191
- const units = ClassName.registry();
1192
- const closures = new Map();
1193
- function closure(moduleId) {
1194
- const cached = closures.get(moduleId);
1195
- if (cached)
1196
- return cached;
1197
- const result = new Set();
1198
- closures.set(moduleId, result);
1199
- for (const dependency of dependencies[moduleId] ?? []) {
1200
- result.add(dependency);
1201
- for (const nested of closure(dependency))
1202
- result.add(nested);
1203
- }
1204
- return result;
1205
- }
1206
- // Hosts that compile a module within several graphs must name it the same in
1207
- // each, so it may reuse only names its dependencies introduce.
1208
- function visible(moduleId) {
1209
- if (options[ClassName.complete])
1210
- return undefined;
1211
- return (owner) => closure(moduleId).has(owner);
1212
- }
1213
- function restore(moduleId, output) {
1214
- return units.restore({
1215
- owner: moduleId,
1216
- used: output[ClassName.units] ?? new Map(),
1217
- visible: visible(moduleId),
1218
- });
1219
- }
1220
- // Extraction visits dependencies first; their emitted classes must precede consumers.
1221
- for (const moduleId of extracted.keys()) {
1222
- const cached = transformed.get(moduleId);
1223
- const reusable = cached &&
1224
- cached.extracted === extracted.get(moduleId) &&
1225
- cached.schemes === schemes &&
1226
- Object.keys(cached.themes).length === names.length &&
1227
- names.every((name) => cached.themes[name] === themes[name]) &&
1228
- Object.entries(cached.classes).every(([name, value]) => styleClasses[name] === value) &&
1229
- cached.owners === ownerSignature &&
1230
- restore(moduleId, cached.output);
1231
- modules[moduleId] = reusable
1232
- ? cached.output
1233
- : sameThemes &&
1234
- previous.schemes === schemes &&
1235
- extracted.get(moduleId) === previous.extracted.get(moduleId) &&
1236
- restore(moduleId, previous.result.modules[moduleId])
1237
- ? previous.result.modules[moduleId]
1238
- : Transform.compile({
1239
- [ClassName.units]: units.scope({
1240
- owner: moduleId,
1241
- qualifier: Identity.compact(moduleId).slice(-6),
1242
- visible: visible(moduleId),
1243
- }),
1244
- [ThemeRules.shared]: options[Stylesheets.entry] === undefined
1245
- ? (options[ThemeRules.shared] ?? 'defaults')
1246
- : 'all',
1247
- compiler: options.compiler,
1248
- development: options.development,
1249
- composition: options.composition,
1250
- cssOutput: options.cssOutput,
1251
- moduleId,
1252
- schemes,
1253
- source: options.modules[moduleId],
1254
- [Themes.context]: {
1255
- parsed: parse({ moduleId, source: options.modules[moduleId] }),
1256
- extracted: Object.freeze({
1257
- ...extracted.get(moduleId),
1258
- vars: sharedThemes,
1259
- contributions: undefined,
1260
- }),
1261
- links: {},
1262
- owners,
1263
- styleClasses,
1264
- },
1265
- });
1266
- transformed.delete(moduleId);
1267
- transformed.set(moduleId, {
1268
- classes: Object.fromEntries(extracted
1269
- .get(moduleId)
1270
- .calls.flatMap((call) => (call.runtimeComposition ?? []).map((input) => [
1271
- input.name,
1272
- styleClasses[input.name],
1273
- ]))),
1274
- extracted: extracted.get(moduleId),
1275
- owners: ownerSignature,
1276
- output: modules[moduleId],
1277
- schemes,
1278
- themes: sharedThemes,
1279
- });
1280
- if (transformed.size > 256)
1281
- transformed.delete(transformed.keys().next().value);
1282
- registerRules(modules[moduleId][ClassName.rules], moduleId);
1283
- for (const call of extracted.get(moduleId).calls)
1284
- if (call.identity &&
1285
- !call.composition &&
1286
- !call.runtimeComposition &&
1287
- !call.compositionCase)
1288
- styleClasses[call.identity] = modules[moduleId].classes[call.name];
1289
- }
1290
- const defaults = new Set();
1291
- const defaultRules = new Map();
1292
- const defaultSections = [];
1293
- if (options[Stylesheets.entry] === undefined)
1294
- for (const [source, output] of Object.entries(modules))
1295
- for (const resource of output[ThemeRules.shared] ?? []) {
1296
- if (defaults.has(resource.id))
1297
- continue;
1298
- defaults.add(resource.id);
1299
- if (!resource.rules) {
1300
- defaultSections.push({
1301
- css: resource.css,
1302
- key: resource.id,
1303
- layers: [],
1304
- source,
1305
- });
1306
- continue;
1307
- }
1308
- const rules = defaultRules.get(source) ?? [];
1309
- rules.push(...resource.rules);
1310
- defaultRules.set(source, rules);
1311
- }
1312
- const shared = defaults.size
1313
- ? renderShared([
1314
- ...sharedSections,
1315
- ...defaultSections,
1316
- ...[...defaultRules].map(([source, rules]) => ({
1317
- css: ThemeRules.render(rules),
1318
- key: 'theme-defaults',
1319
- layers: [],
1320
- source,
1321
- })),
1322
- ])
1323
- : contributions;
1324
- const sharedCss = shared.css;
1325
- function publishedRules(id, visited = new Set()) {
1326
- if (visited.has(id))
1327
- return {};
1328
- visited.add(id);
1329
- return Object.assign({}, ...(dependencies[id] ?? []).map((dependency) => publishedRules(dependency, visited)), libraries[id]?.classRules, modules[id]?.[ClassName.rules]);
1330
- }
1331
- function publishedStyle(link) {
1332
- return {
1333
- ...link,
1334
- ...(link.style
1335
- ? {
1336
- style: {
1337
- ...link.style,
1338
- className: styleClasses[link.binding] ?? link.style.className,
1339
- },
1340
- }
1341
- : {}),
1342
- ...(link.members
1343
- ? {
1344
- members: Object.fromEntries(Object.entries(link.members).map(([name, member]) => [
1345
- name,
1346
- publishedStyle(member),
1347
- ])),
1348
- }
1349
- : {}),
1350
- };
1351
- }
1352
- // A configuration whose module uses root controls or the script publishes its
1353
- // catalog, exported or not, so initialization restores selections it persists.
1354
- function configurations(id) {
1355
- const module = extracted.get(id);
1356
- return module.themeCalls
1357
- .filter((call) => call.appearance &&
1358
- call.options &&
1359
- (module.themeAppearances?.includes(call.name) ||
1360
- module.themeScripts?.includes(call.name)))
1361
- .map((call) => {
1362
- const themeNames = call.options?.themes;
1363
- return {
1364
- identity: sharedThemes[call.name]?.[Token.definition].contract[Token.identity] ?? call.name,
1365
- ...(typeof call.options?.storageKey === 'string'
1366
- ? { storageKey: call.options.storageKey }
1367
- : {}),
1368
- themes: themeNames && typeof themeNames === 'object'
1369
- ? Object.keys(themeNames)
1370
- : [],
1371
- };
1372
- });
1373
- }
21
+ /** The engine's graph input. */
22
+ function encode(options) {
1374
23
  return {
1375
- compiler: options.compiler !== false,
1376
- shared: options[ThemeRules.shared],
24
+ complete: options[ClassName.complete],
25
+ compiler: options.compiler,
1377
26
  composition: options.composition,
27
+ contracts: options.contracts,
1378
28
  cssOutput: options.cssOutput,
1379
- contracts,
1380
- development: !!options.development,
1381
- extracted,
1382
- libraries: Object.freeze(libraries),
1383
- native: undefined,
1384
- reset: options.reset,
29
+ development: options.development,
1385
30
  entry: options[Stylesheets.entry],
1386
- retained,
1387
- transformed,
1388
- resolutions: Object.freeze(resolutions),
1389
- result: Object.freeze({
1390
- ...(options[Stylesheets.entry] !== undefined &&
1391
- options.reset !== undefined
1392
- ? {
1393
- [Stylesheets.reset]: {
1394
- id: 'zyzz/reset.css',
1395
- ...Stylesheets.render([
1396
- {
1397
- content: options.reset,
1398
- css: options.reset,
1399
- layers: [['reset']],
1400
- source: 'zyzz/reset.css',
1401
- },
1402
- ]),
1403
- },
1404
- }
1405
- : {}),
1406
- ...(packed.length ? { [Stylesheets.packed]: packed } : {}),
1407
- ...(sharedCss
1408
- ? {
1409
- sharedCss,
1410
- sharedCssMap: shared.map,
1411
- sharedAssets: shared.assets,
1412
- sharedAssetOwners: shared.owners,
1413
- }
1414
- : {}),
1415
- contracts: Object.freeze(Object.fromEntries((options[Stylesheets.entry] === undefined ? ids : [])
1416
- .filter((id) => Object.keys(extracted.get(id).themeExports ?? {}).length ||
1417
- reachable(id).length ||
1418
- configurations(id).length)
1419
- .map((id) => [
1420
- id,
1421
- Contract.write(Object.fromEntries(Object.entries(extracted.get(id).themeExports ?? {}).map(([name, link]) => [name, publishedStyle(link)])), sharedThemes, reachable(id).map((section) => ({
1422
- ...section,
1423
- owner: undefined,
1424
- dependency: section.owner && section.owner !== id
1425
- ? dependencyPath(id, section.owner)
1426
- : undefined,
1427
- source: Stylesheets.relative(section.owner ?? id, section.source),
1428
- })), id, configurations(id), publishedRules(id)),
1429
- ]))),
1430
- dependencies: Object.freeze(dependencies),
1431
- modules: Object.freeze(Object.fromEntries(ids.map((id) => [id, modules[id]]))),
1432
- }),
1433
- schemes,
1434
- sources: Object.freeze({ ...options.modules }),
1435
- themes: sharedThemes,
31
+ imports: options.imports,
32
+ lean: options[Results.lean],
33
+ modules: options.modules,
34
+ native: options.native && Results.native(options.native),
35
+ reset: options.reset,
36
+ shared: options[ThemeRules.shared],
1436
37
  };
1437
38
  }
1438
- // A returned lazy map must not retain the graph compilation context.
1439
- function nativeOutput(output) {
1440
- let sourceMap;
39
+ /** Creates an isolated compiler with bounded extraction reuse across source graphs. */
40
+ export function create() {
41
+ const decoded = new Map();
42
+ // The engine compiler owns the caches, and collecting this object releases them.
43
+ let engine;
44
+ let result;
45
+ // The engine holds the sources of its last decoded snapshot, so a source equal to the one sent
46
+ // last crosses the boundary as `0`. A failed call leaves nothing sent, which resends every source.
47
+ let sent;
1441
48
  return Object.freeze({
1442
- [ClassName.rules]: Object.freeze({}),
1443
- classes: Object.freeze({}),
1444
- [Edits.key]: output[Edits.key],
1445
- code: output.code,
1446
- css: '',
1447
- cssMap: {
1448
- version: 3,
1449
- names: [],
1450
- sources: [],
1451
- mappings: '',
1452
- },
1453
- get map() {
1454
- return (sourceMap ??= JSON.parse(output.map));
49
+ compile(options) {
50
+ engine ??= new (Addon.load().Graph)();
51
+ const input = encode(options);
52
+ const previous = sent;
53
+ sent = undefined;
54
+ const text = (() => {
55
+ if (!previous)
56
+ return engine.compile(JSON.stringify(input));
57
+ const output = engine.compile(JSON.stringify({
58
+ ...input,
59
+ contracts: unchanged(input.contracts, previous.contracts),
60
+ modules: unchanged(input.modules, previous.modules),
61
+ }));
62
+ return output === stale ? engine.compile(JSON.stringify(input)) : output;
63
+ })();
64
+ result = Results.graph(Results.decode(text), result, decoded);
65
+ // Hosts may update their records in place, so the sent text is copied.
66
+ sent = {
67
+ contracts: input.contracts && { ...input.contracts },
68
+ modules: { ...input.modules },
69
+ };
70
+ return result;
1455
71
  },
1456
- vars: Object.freeze({}),
1457
72
  });
1458
73
  }
1459
74
  //# sourceMappingURL=Graph.js.map