@czap/core 0.1.0

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 (372) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/addressed-digest.d.ts +15 -0
  4. package/dist/addressed-digest.d.ts.map +1 -0
  5. package/dist/addressed-digest.js +35 -0
  6. package/dist/addressed-digest.js.map +1 -0
  7. package/dist/animation.d.ts +46 -0
  8. package/dist/animation.d.ts.map +1 -0
  9. package/dist/animation.js +70 -0
  10. package/dist/animation.js.map +1 -0
  11. package/dist/assembly.d.ts +25 -0
  12. package/dist/assembly.d.ts.map +1 -0
  13. package/dist/assembly.js +58 -0
  14. package/dist/assembly.js.map +1 -0
  15. package/dist/av-bridge.d.ts +74 -0
  16. package/dist/av-bridge.d.ts.map +1 -0
  17. package/dist/av-bridge.js +107 -0
  18. package/dist/av-bridge.js.map +1 -0
  19. package/dist/av-renderer.d.ts +56 -0
  20. package/dist/av-renderer.d.ts.map +1 -0
  21. package/dist/av-renderer.js +65 -0
  22. package/dist/av-renderer.js.map +1 -0
  23. package/dist/blend.d.ts +61 -0
  24. package/dist/blend.d.ts.map +1 -0
  25. package/dist/blend.js +100 -0
  26. package/dist/blend.js.map +1 -0
  27. package/dist/boundary.d.ts +154 -0
  28. package/dist/boundary.d.ts.map +1 -0
  29. package/dist/boundary.js +269 -0
  30. package/dist/boundary.js.map +1 -0
  31. package/dist/brands.d.ts +63 -0
  32. package/dist/brands.d.ts.map +1 -0
  33. package/dist/brands.js +31 -0
  34. package/dist/brands.js.map +1 -0
  35. package/dist/caps.d.ts +49 -0
  36. package/dist/caps.d.ts.map +1 -0
  37. package/dist/caps.js +73 -0
  38. package/dist/caps.js.map +1 -0
  39. package/dist/capsule.d.ts +77 -0
  40. package/dist/capsule.d.ts.map +1 -0
  41. package/dist/capsule.js +18 -0
  42. package/dist/capsule.js.map +1 -0
  43. package/dist/capsules/boundary-evaluate.d.ts +28 -0
  44. package/dist/capsules/boundary-evaluate.d.ts.map +1 -0
  45. package/dist/capsules/boundary-evaluate.js +117 -0
  46. package/dist/capsules/boundary-evaluate.js.map +1 -0
  47. package/dist/capsules/canonical-cbor.d.ts +13 -0
  48. package/dist/capsules/canonical-cbor.d.ts.map +1 -0
  49. package/dist/capsules/canonical-cbor.js +60 -0
  50. package/dist/capsules/canonical-cbor.js.map +1 -0
  51. package/dist/capsules/token-buffer.d.ts +24 -0
  52. package/dist/capsules/token-buffer.d.ts.map +1 -0
  53. package/dist/capsules/token-buffer.js +53 -0
  54. package/dist/capsules/token-buffer.js.map +1 -0
  55. package/dist/capture.d.ts +40 -0
  56. package/dist/capture.d.ts.map +1 -0
  57. package/dist/capture.js +10 -0
  58. package/dist/capture.js.map +1 -0
  59. package/dist/cbor.d.ts +33 -0
  60. package/dist/cbor.d.ts.map +1 -0
  61. package/dist/cbor.js +179 -0
  62. package/dist/cbor.js.map +1 -0
  63. package/dist/cell.d.ts +53 -0
  64. package/dist/cell.d.ts.map +1 -0
  65. package/dist/cell.js +83 -0
  66. package/dist/cell.js.map +1 -0
  67. package/dist/codec.d.ts +30 -0
  68. package/dist/codec.d.ts.map +1 -0
  69. package/dist/codec.js +25 -0
  70. package/dist/codec.js.map +1 -0
  71. package/dist/component.d.ts +52 -0
  72. package/dist/component.d.ts.map +1 -0
  73. package/dist/component.js +44 -0
  74. package/dist/component.js.map +1 -0
  75. package/dist/composable.d.ts +76 -0
  76. package/dist/composable.d.ts.map +1 -0
  77. package/dist/composable.js +221 -0
  78. package/dist/composable.js.map +1 -0
  79. package/dist/compositor-pool.d.ts +74 -0
  80. package/dist/compositor-pool.d.ts.map +1 -0
  81. package/dist/compositor-pool.js +119 -0
  82. package/dist/compositor-pool.js.map +1 -0
  83. package/dist/compositor.d.ts +90 -0
  84. package/dist/compositor.d.ts.map +1 -0
  85. package/dist/compositor.js +278 -0
  86. package/dist/compositor.js.map +1 -0
  87. package/dist/config.d.ts +72 -0
  88. package/dist/config.d.ts.map +1 -0
  89. package/dist/config.js +97 -0
  90. package/dist/config.js.map +1 -0
  91. package/dist/dag.d.ts +251 -0
  92. package/dist/dag.d.ts.map +1 -0
  93. package/dist/dag.js +450 -0
  94. package/dist/dag.js.map +1 -0
  95. package/dist/defaults.d.ts +45 -0
  96. package/dist/defaults.d.ts.map +1 -0
  97. package/dist/defaults.js +45 -0
  98. package/dist/defaults.js.map +1 -0
  99. package/dist/derived.d.ts +34 -0
  100. package/dist/derived.d.ts.map +1 -0
  101. package/dist/derived.js +101 -0
  102. package/dist/derived.js.map +1 -0
  103. package/dist/diagnostics.d.ts +77 -0
  104. package/dist/diagnostics.d.ts.map +1 -0
  105. package/dist/diagnostics.js +122 -0
  106. package/dist/diagnostics.js.map +1 -0
  107. package/dist/dirty.d.ts +55 -0
  108. package/dist/dirty.d.ts.map +1 -0
  109. package/dist/dirty.js +80 -0
  110. package/dist/dirty.js.map +1 -0
  111. package/dist/easing.d.ts +55 -0
  112. package/dist/easing.d.ts.map +1 -0
  113. package/dist/easing.js +291 -0
  114. package/dist/easing.js.map +1 -0
  115. package/dist/ecs.d.ts +105 -0
  116. package/dist/ecs.d.ts.map +1 -0
  117. package/dist/ecs.js +245 -0
  118. package/dist/ecs.js.map +1 -0
  119. package/dist/fnv.d.ts +14 -0
  120. package/dist/fnv.d.ts.map +1 -0
  121. package/dist/fnv.js +28 -0
  122. package/dist/fnv.js.map +1 -0
  123. package/dist/frame-budget.d.ts +73 -0
  124. package/dist/frame-budget.d.ts.map +1 -0
  125. package/dist/frame-budget.js +114 -0
  126. package/dist/frame-budget.js.map +1 -0
  127. package/dist/gen-frame.d.ts +102 -0
  128. package/dist/gen-frame.d.ts.map +1 -0
  129. package/dist/gen-frame.js +121 -0
  130. package/dist/gen-frame.js.map +1 -0
  131. package/dist/harness/arbitrary-from-schema.d.ts +28 -0
  132. package/dist/harness/arbitrary-from-schema.d.ts.map +1 -0
  133. package/dist/harness/arbitrary-from-schema.js +262 -0
  134. package/dist/harness/arbitrary-from-schema.js.map +1 -0
  135. package/dist/harness/cached-projection.d.ts +19 -0
  136. package/dist/harness/cached-projection.d.ts.map +1 -0
  137. package/dist/harness/cached-projection.js +39 -0
  138. package/dist/harness/cached-projection.js.map +1 -0
  139. package/dist/harness/index.d.ts +16 -0
  140. package/dist/harness/index.d.ts.map +1 -0
  141. package/dist/harness/index.js +15 -0
  142. package/dist/harness/index.js.map +1 -0
  143. package/dist/harness/policy-gate.d.ts +18 -0
  144. package/dist/harness/policy-gate.d.ts.map +1 -0
  145. package/dist/harness/policy-gate.js +46 -0
  146. package/dist/harness/policy-gate.js.map +1 -0
  147. package/dist/harness/pure-transform.d.ts +42 -0
  148. package/dist/harness/pure-transform.d.ts.map +1 -0
  149. package/dist/harness/pure-transform.js +76 -0
  150. package/dist/harness/pure-transform.js.map +1 -0
  151. package/dist/harness/receipted-mutation.d.ts +23 -0
  152. package/dist/harness/receipted-mutation.d.ts.map +1 -0
  153. package/dist/harness/receipted-mutation.js +52 -0
  154. package/dist/harness/receipted-mutation.js.map +1 -0
  155. package/dist/harness/scene-composition.d.ts +19 -0
  156. package/dist/harness/scene-composition.d.ts.map +1 -0
  157. package/dist/harness/scene-composition.js +47 -0
  158. package/dist/harness/scene-composition.js.map +1 -0
  159. package/dist/harness/site-adapter.d.ts +18 -0
  160. package/dist/harness/site-adapter.d.ts.map +1 -0
  161. package/dist/harness/site-adapter.js +38 -0
  162. package/dist/harness/site-adapter.js.map +1 -0
  163. package/dist/harness/state-machine.d.ts +19 -0
  164. package/dist/harness/state-machine.d.ts.map +1 -0
  165. package/dist/harness/state-machine.js +44 -0
  166. package/dist/harness/state-machine.js.map +1 -0
  167. package/dist/hlc.d.ts +99 -0
  168. package/dist/hlc.d.ts.map +1 -0
  169. package/dist/hlc.js +219 -0
  170. package/dist/hlc.js.map +1 -0
  171. package/dist/index.d.ts +104 -0
  172. package/dist/index.d.ts.map +1 -0
  173. package/dist/index.js +137 -0
  174. package/dist/index.js.map +1 -0
  175. package/dist/interpolate.d.ts +14 -0
  176. package/dist/interpolate.d.ts.map +1 -0
  177. package/dist/interpolate.js +31 -0
  178. package/dist/interpolate.js.map +1 -0
  179. package/dist/live-cell.d.ts +46 -0
  180. package/dist/live-cell.d.ts.map +1 -0
  181. package/dist/live-cell.js +154 -0
  182. package/dist/live-cell.js.map +1 -0
  183. package/dist/op.d.ts +58 -0
  184. package/dist/op.d.ts.map +1 -0
  185. package/dist/op.js +171 -0
  186. package/dist/op.js.map +1 -0
  187. package/dist/plan.d.ts +195 -0
  188. package/dist/plan.d.ts.map +1 -0
  189. package/dist/plan.js +211 -0
  190. package/dist/plan.js.map +1 -0
  191. package/dist/protocol.d.ts +33 -0
  192. package/dist/protocol.d.ts.map +1 -0
  193. package/dist/protocol.js +10 -0
  194. package/dist/protocol.js.map +1 -0
  195. package/dist/quantizer-types.d.ts +28 -0
  196. package/dist/quantizer-types.d.ts.map +1 -0
  197. package/dist/quantizer-types.js +9 -0
  198. package/dist/quantizer-types.js.map +1 -0
  199. package/dist/receipt.d.ts +294 -0
  200. package/dist/receipt.d.ts.map +1 -0
  201. package/dist/receipt.js +352 -0
  202. package/dist/receipt.js.map +1 -0
  203. package/dist/runtime-coordinator.d.ts +75 -0
  204. package/dist/runtime-coordinator.d.ts.map +1 -0
  205. package/dist/runtime-coordinator.js +149 -0
  206. package/dist/runtime-coordinator.js.map +1 -0
  207. package/dist/scheduler.d.ts +58 -0
  208. package/dist/scheduler.d.ts.map +1 -0
  209. package/dist/scheduler.js +109 -0
  210. package/dist/scheduler.js.map +1 -0
  211. package/dist/ship-capsule.d.ts +54 -0
  212. package/dist/ship-capsule.d.ts.map +1 -0
  213. package/dist/ship-capsule.js +142 -0
  214. package/dist/ship-capsule.js.map +1 -0
  215. package/dist/ship-manifest.d.ts +45 -0
  216. package/dist/ship-manifest.d.ts.map +1 -0
  217. package/dist/ship-manifest.js +175 -0
  218. package/dist/ship-manifest.js.map +1 -0
  219. package/dist/signal.d.ts +149 -0
  220. package/dist/signal.d.ts.map +1 -0
  221. package/dist/signal.js +277 -0
  222. package/dist/signal.js.map +1 -0
  223. package/dist/speculative.d.ts +67 -0
  224. package/dist/speculative.d.ts.map +1 -0
  225. package/dist/speculative.js +139 -0
  226. package/dist/speculative.js.map +1 -0
  227. package/dist/store.d.ts +39 -0
  228. package/dist/store.d.ts.map +1 -0
  229. package/dist/store.js +42 -0
  230. package/dist/store.js.map +1 -0
  231. package/dist/style.d.ts +119 -0
  232. package/dist/style.d.ts.map +1 -0
  233. package/dist/style.js +168 -0
  234. package/dist/style.js.map +1 -0
  235. package/dist/testing.d.ts +14 -0
  236. package/dist/testing.d.ts.map +1 -0
  237. package/dist/testing.js +14 -0
  238. package/dist/testing.js.map +1 -0
  239. package/dist/theme.d.ts +78 -0
  240. package/dist/theme.d.ts.map +1 -0
  241. package/dist/theme.js +109 -0
  242. package/dist/theme.js.map +1 -0
  243. package/dist/timeline.d.ts +45 -0
  244. package/dist/timeline.d.ts.map +1 -0
  245. package/dist/timeline.js +101 -0
  246. package/dist/timeline.js.map +1 -0
  247. package/dist/token-buffer.d.ts +43 -0
  248. package/dist/token-buffer.d.ts.map +1 -0
  249. package/dist/token-buffer.js +112 -0
  250. package/dist/token-buffer.js.map +1 -0
  251. package/dist/token.d.ts +107 -0
  252. package/dist/token.d.ts.map +1 -0
  253. package/dist/token.js +143 -0
  254. package/dist/token.js.map +1 -0
  255. package/dist/tuple.d.ts +16 -0
  256. package/dist/tuple.d.ts.map +1 -0
  257. package/dist/tuple.js +16 -0
  258. package/dist/tuple.js.map +1 -0
  259. package/dist/type-utils.d.ts +41 -0
  260. package/dist/type-utils.d.ts.map +1 -0
  261. package/dist/type-utils.js +10 -0
  262. package/dist/type-utils.js.map +1 -0
  263. package/dist/typed-ref.d.ts +50 -0
  264. package/dist/typed-ref.d.ts.map +1 -0
  265. package/dist/typed-ref.js +59 -0
  266. package/dist/typed-ref.js.map +1 -0
  267. package/dist/ui-quality.d.ts +50 -0
  268. package/dist/ui-quality.d.ts.map +1 -0
  269. package/dist/ui-quality.js +64 -0
  270. package/dist/ui-quality.js.map +1 -0
  271. package/dist/validation-error.d.ts +25 -0
  272. package/dist/validation-error.d.ts.map +1 -0
  273. package/dist/validation-error.js +32 -0
  274. package/dist/validation-error.js.map +1 -0
  275. package/dist/vector-clock.d.ts +46 -0
  276. package/dist/vector-clock.d.ts.map +1 -0
  277. package/dist/vector-clock.js +91 -0
  278. package/dist/vector-clock.js.map +1 -0
  279. package/dist/video.d.ts +62 -0
  280. package/dist/video.d.ts.map +1 -0
  281. package/dist/video.js +59 -0
  282. package/dist/video.js.map +1 -0
  283. package/dist/wasm-dispatch.d.ts +52 -0
  284. package/dist/wasm-dispatch.d.ts.map +1 -0
  285. package/dist/wasm-dispatch.js +204 -0
  286. package/dist/wasm-dispatch.js.map +1 -0
  287. package/dist/wasm-fallback.d.ts +19 -0
  288. package/dist/wasm-fallback.d.ts.map +1 -0
  289. package/dist/wasm-fallback.js +93 -0
  290. package/dist/wasm-fallback.js.map +1 -0
  291. package/dist/wire.d.ts +49 -0
  292. package/dist/wire.d.ts.map +1 -0
  293. package/dist/wire.js +201 -0
  294. package/dist/wire.js.map +1 -0
  295. package/dist/zap.d.ts +42 -0
  296. package/dist/zap.d.ts.map +1 -0
  297. package/dist/zap.js +172 -0
  298. package/dist/zap.js.map +1 -0
  299. package/package.json +71 -0
  300. package/src/addressed-digest.ts +48 -0
  301. package/src/animation.ts +103 -0
  302. package/src/assembly.ts +76 -0
  303. package/src/av-bridge.ts +161 -0
  304. package/src/av-renderer.ts +118 -0
  305. package/src/blend.ts +135 -0
  306. package/src/boundary.ts +363 -0
  307. package/src/brands.ts +86 -0
  308. package/src/caps.ts +100 -0
  309. package/src/capsule.ts +95 -0
  310. package/src/capsules/boundary-evaluate.ts +128 -0
  311. package/src/capsules/canonical-cbor.ts +60 -0
  312. package/src/capsules/token-buffer.ts +57 -0
  313. package/src/capture.ts +48 -0
  314. package/src/cbor.ts +199 -0
  315. package/src/cell.ts +130 -0
  316. package/src/codec.ts +39 -0
  317. package/src/component.ts +102 -0
  318. package/src/composable.ts +328 -0
  319. package/src/compositor-pool.ts +162 -0
  320. package/src/compositor.ts +387 -0
  321. package/src/config.ts +157 -0
  322. package/src/dag.ts +527 -0
  323. package/src/defaults.ts +60 -0
  324. package/src/derived.ts +164 -0
  325. package/src/diagnostics.ts +186 -0
  326. package/src/dirty.ts +101 -0
  327. package/src/easing.ts +334 -0
  328. package/src/ecs.ts +382 -0
  329. package/src/fnv.ts +31 -0
  330. package/src/frame-budget.ts +149 -0
  331. package/src/gen-frame.ts +229 -0
  332. package/src/harness/arbitrary-from-schema.ts +270 -0
  333. package/src/harness/cached-projection.ts +46 -0
  334. package/src/harness/index.ts +16 -0
  335. package/src/harness/policy-gate.ts +51 -0
  336. package/src/harness/pure-transform.ts +121 -0
  337. package/src/harness/receipted-mutation.ts +59 -0
  338. package/src/harness/scene-composition.ts +54 -0
  339. package/src/harness/site-adapter.ts +43 -0
  340. package/src/harness/state-machine.ts +49 -0
  341. package/src/hlc.ts +238 -0
  342. package/src/index.ts +274 -0
  343. package/src/interpolate.ts +37 -0
  344. package/src/live-cell.ts +199 -0
  345. package/src/op.ts +233 -0
  346. package/src/plan.ts +317 -0
  347. package/src/protocol.ts +49 -0
  348. package/src/quantizer-types.ts +29 -0
  349. package/src/receipt.ts +444 -0
  350. package/src/runtime-coordinator.ts +230 -0
  351. package/src/scheduler.ts +161 -0
  352. package/src/ship-capsule.ts +191 -0
  353. package/src/signal.ts +345 -0
  354. package/src/speculative.ts +186 -0
  355. package/src/store.ts +77 -0
  356. package/src/style.ts +249 -0
  357. package/src/testing.ts +14 -0
  358. package/src/theme.ts +153 -0
  359. package/src/timeline.ts +146 -0
  360. package/src/token-buffer.ts +151 -0
  361. package/src/token.ts +197 -0
  362. package/src/tuple.ts +19 -0
  363. package/src/type-utils.ts +48 -0
  364. package/src/typed-ref.ts +79 -0
  365. package/src/ui-quality.ts +105 -0
  366. package/src/validation-error.ts +34 -0
  367. package/src/vector-clock.ts +111 -0
  368. package/src/video.ts +106 -0
  369. package/src/wasm-dispatch.ts +300 -0
  370. package/src/wasm-fallback.ts +102 -0
  371. package/src/wire.ts +274 -0
  372. package/src/zap.ts +241 -0
@@ -0,0 +1,44 @@
1
+ /**
2
+ * ComponentDef -- adaptive component primitive for constraint-based rendering.
3
+ *
4
+ * A component binds a boundary, styles, and named slots into a single
5
+ * content-addressed unit. Content-addressed via FNV-1a.
6
+ *
7
+ * @module
8
+ */
9
+ import { CanonicalCbor } from './cbor.js';
10
+ import { fnv1aBytes } from './fnv.js';
11
+ function deterministicId(name, boundaryId, stylesId, slots, defaultSlot) {
12
+ return fnv1aBytes(CanonicalCbor.encode({
13
+ _tag: 'ComponentDef',
14
+ _version: 1,
15
+ name,
16
+ boundaryId: boundaryId ?? null,
17
+ stylesId,
18
+ slots,
19
+ defaultSlot: defaultSlot ?? null,
20
+ }));
21
+ }
22
+ /**
23
+ * Component — the content-addressed unit that binds a {@link Boundary}, a
24
+ * {@link Style}, and named slots into a single declaration compilers can
25
+ * target. The optional boundary gates style variants; the slots describe
26
+ * the consumer-facing API.
27
+ */
28
+ export const Component = {
29
+ make(config) {
30
+ const id = deterministicId(config.name, config.boundary?.id, config.styles.id, config.slots, config.defaultSlot);
31
+ const def = {
32
+ _tag: 'ComponentDef',
33
+ _version: 1,
34
+ id,
35
+ name: config.name,
36
+ ...(config.boundary !== undefined ? { boundary: config.boundary } : {}),
37
+ styles: config.styles,
38
+ slots: config.slots,
39
+ ...(config.defaultSlot !== undefined ? { defaultSlot: config.defaultSlot } : {}),
40
+ };
41
+ return Object.freeze(def);
42
+ },
43
+ };
44
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAgCtC,SAAS,eAAe,CACtB,IAAY,EACZ,UAA8B,EAC9B,QAAgB,EAChB,KAAwD,EACxD,WAAoB;IAEpB,OAAO,UAAU,CACf,aAAa,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,cAAc;QACpB,QAAQ,EAAE,CAAC;QACX,IAAI;QACJ,UAAU,EAAE,UAAU,IAAI,IAAI;QAC9B,QAAQ;QACR,KAAK;QACL,WAAW,EAAE,WAAW,IAAI,IAAI;KACjC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAqB;IACzC,IAAI,CAA4E,MAM/E;QACC,MAAM,EAAE,GAAG,eAAe,CAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAErH,MAAM,GAAG,GAAwB;YAC/B,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,CAAC;YACX,EAAE;YACF,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjF,CAAC;QACF,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;CACF,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Composable -- ECS Composition over Existing Primitives
3
+ *
4
+ * Universal composition API leveraging existing deterministic primitives.
5
+ * Zero boilerplate, type-safe, content-addressed entity composition.
6
+ *
7
+ * @module
8
+ */
9
+ import type { ContentAddress } from './brands.js';
10
+ import type { Token } from './token.js';
11
+ import type { Style } from './style.js';
12
+ import type { World } from './ecs.js';
13
+ import { Boundary } from './boundary.js';
14
+ import { Part } from './ecs.js';
15
+ import { Effect } from 'effect';
16
+ /**
17
+ * Component map for a {@link ComposableEntity} — well-known slots for czap
18
+ * primitives plus arbitrary user-defined keys.
19
+ */
20
+ export interface EntityComponents {
21
+ readonly boundary?: Boundary.Shape;
22
+ readonly token?: Token.Shape;
23
+ readonly style?: Style.Shape;
24
+ readonly [key: string]: unknown;
25
+ }
26
+ /**
27
+ * Content-addressed entity: the identity is an FNV-1a hash over its components,
28
+ * so two entities with structurally equal components share the same `id`.
29
+ */
30
+ export interface ComposableEntity<T extends EntityComponents = EntityComponents> {
31
+ readonly id: ContentAddress;
32
+ readonly components: T;
33
+ readonly _tag: 'ComposableEntity';
34
+ }
35
+ interface ComposableFactory {
36
+ make<T extends EntityComponents>(components: T): ComposableEntity<T>;
37
+ compose<T extends EntityComponents>(entity1: ComposableEntity<T>, entity2: ComposableEntity<T>): ComposableEntity<T>;
38
+ merge<T extends EntityComponents>(...entities: ComposableEntity<T>[]): ComposableEntity<T>;
39
+ }
40
+ interface TypedComposableWorld<Schema extends EntityComponents = EntityComponents> {
41
+ spawn<T extends Schema>(components: T): Effect.Effect<ComposableEntity<T>>;
42
+ spawnWith<T extends Schema>(entity: ComposableEntity<T>): Effect.Effect<ComposableEntity<T>>;
43
+ query<K extends keyof Schema>(...componentTypes: K[]): Effect.Effect<readonly ComposableEntity<Pick<Schema, K>>[]>;
44
+ evaluate<T extends Schema>(entity: ComposableEntity<T>, input: Record<string, number>): Effect.Effect<Record<string, string>>;
45
+ }
46
+ declare function makeComposableWorld<Schema extends EntityComponents = EntityComponents>(world: World.Shape): TypedComposableWorld<Schema>;
47
+ interface ComposableDenseStore {
48
+ create(name: string, capacity: number): Effect.Effect<Part.Dense>;
49
+ store<T extends EntityComponents>(entity: ComposableEntity<T>, value: number): Effect.Effect<void>;
50
+ retrieve<T extends EntityComponents>(entity: ComposableEntity<T>): Effect.Effect<number | undefined>;
51
+ }
52
+ declare function makeComposableDenseStore(world: World.Shape): ComposableDenseStore;
53
+ /**
54
+ * Composable — content-addressed entity algebra over czap primitives.
55
+ *
56
+ * Build entities from a bag of components (boundaries, tokens, styles, …),
57
+ * merge them associatively via `Composable.compose` / `Composable.merge`, and
58
+ * rely on the content address to deduplicate structurally-equal entities.
59
+ */
60
+ export declare const Composable: ComposableFactory;
61
+ /**
62
+ * Bridge between a raw ECS {@link World} and typed {@link ComposableEntity}
63
+ * operations (`spawn`, `query`, `evaluate`) plus a thin dense-store integration.
64
+ */
65
+ export declare const ComposableWorld: {
66
+ /** Wrap a {@link World} with the typed composable-entity API. */
67
+ make: typeof makeComposableWorld;
68
+ /** Build a dense-store bridge over a {@link World} for per-entity numeric data. */
69
+ dense: typeof makeComposableDenseStore;
70
+ };
71
+ export declare namespace ComposableWorld {
72
+ /** Structural shape of the typed world returned by {@link ComposableWorld.make}. */
73
+ type Shape<Schema extends EntityComponents = EntityComponents> = TypedComposableWorld<Schema>;
74
+ }
75
+ export type { TypedComposableWorld as ComposableWorldShape };
76
+ //# sourceMappingURL=composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composable.d.ts","sourceRoot":"","sources":["../src/composable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Composable -- ECS Composition over Existing Primitives
3
+ *
4
+ * Universal composition API leveraging existing deterministic primitives.
5
+ * Zero boilerplate, type-safe, content-addressed entity composition.
6
+ *
7
+ * @module
8
+ */
9
+ import { Token as TokenNS } from './token.js';
10
+ import { Style as StyleNS } from './style.js';
11
+ import { Boundary } from './boundary.js';
12
+ import { Part } from './ecs.js';
13
+ import { fnv1aBytes } from './fnv.js';
14
+ import { TypedRef } from './typed-ref.js';
15
+ import { Effect } from 'effect';
16
+ function makeEntityId(components) {
17
+ const canonical = canonicalizeForAddress(components);
18
+ return fnv1aBytes(TypedRef.canonicalize(canonical));
19
+ }
20
+ function canonicalizeForAddress(value) {
21
+ if (value === undefined) {
22
+ return undefined;
23
+ }
24
+ if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
25
+ return value;
26
+ }
27
+ if (Array.isArray(value)) {
28
+ return value.map((entry) => {
29
+ const canonical = canonicalizeForAddress(entry);
30
+ return canonical === undefined ? null : canonical;
31
+ });
32
+ }
33
+ if (typeof value === 'object') {
34
+ const entries = Object.entries(value)
35
+ .filter(([, entry]) => entry !== undefined)
36
+ .sort(([left], [right]) => left.localeCompare(right))
37
+ .map(([key, entry]) => [key, canonicalizeForAddress(entry)]);
38
+ return Object.fromEntries(entries);
39
+ }
40
+ return String(value);
41
+ }
42
+ function _make(components) {
43
+ const id = makeEntityId(components);
44
+ return {
45
+ id,
46
+ components,
47
+ _tag: 'ComposableEntity',
48
+ };
49
+ }
50
+ function _compose(entity1, entity2) {
51
+ // Merge components with entity2 taking precedence
52
+ const merged = { ...entity1.components, ...entity2.components };
53
+ return _make(merged);
54
+ }
55
+ function _merge(...entities) {
56
+ if (entities.length === 0) {
57
+ throw new Error('Cannot merge zero entities');
58
+ }
59
+ const first = entities[0];
60
+ if (!first) {
61
+ throw new Error('First entity is undefined');
62
+ }
63
+ return entities.slice(1).reduce((acc, entity) => _compose(acc, entity), first);
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // ECS Integration
67
+ // ---------------------------------------------------------------------------
68
+ /**
69
+ * Convert a runtime `Map<string, unknown>` (from ECS query results) into a typed
70
+ * `Pick<Schema, K>`. The ECS query filters guarantee the required keys are present;
71
+ * this helper contains the one boundary cast where runtime shape joins the type lattice.
72
+ */
73
+ function entriesToPick(components) {
74
+ return Object.fromEntries(components);
75
+ }
76
+ function makeComposableWorld(world) {
77
+ // Mapping from ContentAddress to ECS EntityId for query reconstruction
78
+ const addressToEntityId = new Map();
79
+ return {
80
+ spawn(components) {
81
+ return Effect.gen(function* () {
82
+ const entity = _make(components);
83
+ const ecsId = yield* world.spawn(components);
84
+ addressToEntityId.set(entity.id, ecsId);
85
+ return entity;
86
+ });
87
+ },
88
+ spawnWith(entity) {
89
+ return Effect.gen(function* () {
90
+ const ecsId = yield* world.spawn(entity.components);
91
+ addressToEntityId.set(entity.id, ecsId);
92
+ return entity;
93
+ });
94
+ },
95
+ query(...componentTypes) {
96
+ return Effect.gen(function* () {
97
+ const names = [...componentTypes].map((k) => String(k)).sort();
98
+ const entities = yield* world.query(...names);
99
+ return [...entities]
100
+ .sort((left, right) => left.id.localeCompare(right.id))
101
+ .map((entityShape) => {
102
+ // world.query guarantees entityShape.components contains at least the K keys
103
+ // that were queried for; convert the runtime Map<string, unknown> to the typed
104
+ // Pick<Schema, K> via a single contained cast (runtime shape is validated by
105
+ // the ECS query filter).
106
+ const components = entriesToPick(entityShape.components);
107
+ return _make(components);
108
+ });
109
+ });
110
+ },
111
+ evaluate(entity, input) {
112
+ return Effect.gen(function* () {
113
+ const results = {};
114
+ // Evaluate boundary component: quantize continuous input to discrete state
115
+ let boundaryState;
116
+ if (entity.components.boundary) {
117
+ const boundary = entity.components.boundary;
118
+ const boundaryInput = input[boundary.input] ?? 0;
119
+ const state = Boundary.evaluate(boundary, boundaryInput);
120
+ results[boundary.input] = state;
121
+ boundaryState = state;
122
+ }
123
+ // Evaluate token component: resolve axis values or fall back
124
+ if (entity.components.token) {
125
+ const token = entity.components.token;
126
+ // Build axis values from input keys. Token.tap expects string axis values,
127
+ // so we convert matching numeric inputs to strings.
128
+ const axisValues = {};
129
+ for (const axis of token.axes) {
130
+ if (axis in input) {
131
+ axisValues[axis] = String(input[axis]);
132
+ }
133
+ }
134
+ // Use Token.tap for proper axis-key lookup with fallback
135
+ const resolved = TokenNS.tap(token, axisValues);
136
+ results[token.name] = String(resolved);
137
+ }
138
+ // Evaluate style component: resolve properties for the current boundary state
139
+ if (entity.components.style) {
140
+ const style = entity.components.style;
141
+ const resolvedProps = StyleNS.tap(style, boundaryState);
142
+ for (const [prop, val] of Object.entries(resolvedProps)) {
143
+ results[prop] = val;
144
+ }
145
+ }
146
+ return results;
147
+ });
148
+ },
149
+ };
150
+ }
151
+ function makeComposableDenseStore(world) {
152
+ // Maintain a mapping from ContentAddress to ECS EntityId for dense store ops
153
+ const addressToEntityId = new Map();
154
+ let denseStore;
155
+ return {
156
+ create(name, capacity) {
157
+ return Effect.gen(function* () {
158
+ const store = Part.dense(name, capacity);
159
+ yield* world.addDenseStore(store);
160
+ denseStore = store;
161
+ return store;
162
+ });
163
+ },
164
+ store(entity, value) {
165
+ return Effect.gen(function* () {
166
+ if (!denseStore) {
167
+ throw new Error('No dense store created. Call create() first.');
168
+ }
169
+ // Ensure we have an ECS EntityId for this composable entity
170
+ let ecsId = addressToEntityId.get(entity.id);
171
+ if (!ecsId) {
172
+ // Spawn into the world to get an EntityId, then track mapping
173
+ ecsId = yield* world.spawn(entity.components);
174
+ addressToEntityId.set(entity.id, ecsId);
175
+ }
176
+ denseStore.set(ecsId, value);
177
+ });
178
+ },
179
+ retrieve(entity) {
180
+ return Effect.gen(function* () {
181
+ if (!denseStore) {
182
+ return undefined;
183
+ }
184
+ const ecsId = addressToEntityId.get(entity.id);
185
+ if (!ecsId) {
186
+ return undefined;
187
+ }
188
+ return denseStore.get(ecsId);
189
+ });
190
+ },
191
+ };
192
+ }
193
+ // ---------------------------------------------------------------------------
194
+ // Exports
195
+ // ---------------------------------------------------------------------------
196
+ /**
197
+ * Composable — content-addressed entity algebra over czap primitives.
198
+ *
199
+ * Build entities from a bag of components (boundaries, tokens, styles, …),
200
+ * merge them associatively via `Composable.compose` / `Composable.merge`, and
201
+ * rely on the content address to deduplicate structurally-equal entities.
202
+ */
203
+ export const Composable = {
204
+ /** Content-address a component bag into a {@link ComposableEntity}. */
205
+ make: _make,
206
+ /** Pairwise merge — right-biased; produces a new entity with a fresh content address. */
207
+ compose: _compose,
208
+ /** Variadic `Composable.compose`. Throws if called with zero entities. */
209
+ merge: _merge,
210
+ };
211
+ /**
212
+ * Bridge between a raw ECS {@link World} and typed {@link ComposableEntity}
213
+ * operations (`spawn`, `query`, `evaluate`) plus a thin dense-store integration.
214
+ */
215
+ export const ComposableWorld = {
216
+ /** Wrap a {@link World} with the typed composable-entity API. */
217
+ make: makeComposableWorld,
218
+ /** Build a dense-store bridge over a {@link World} for per-entity numeric data. */
219
+ dense: makeComposableDenseStore,
220
+ };
221
+ //# sourceMappingURL=composable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composable.js","sourceRoot":"","sources":["../src/composable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * CompositorStatePool -- ring buffer of pre-allocated CompositeState objects.
3
+ *
4
+ * The compositor grabs one, writes into it, hands it to the renderer,
5
+ * which returns it after DOM application. Zero-allocation hot path.
6
+ *
7
+ * @module
8
+ */
9
+ import type { CompositeState } from './compositor.js';
10
+ interface CompositorStatePoolShape {
11
+ acquire(): CompositeState;
12
+ release(state: CompositeState): void;
13
+ readonly size: number;
14
+ readonly available: number;
15
+ }
16
+ /**
17
+ * Mutable views into a CompositeState's fields. `CompositeState` declares
18
+ * its fields as `readonly Record<...>`, but the compositor and the pool
19
+ * both need to mutate those records in place for the zero-allocation
20
+ * hot path. This helper centralises the single cast that strips
21
+ * `readonly` so callers can stay type-safe without re-casting at each
22
+ * write site.
23
+ */
24
+ export interface MutableCompositeStateViews {
25
+ readonly discrete: Record<string, string>;
26
+ readonly blend: Record<string, Record<string, number>>;
27
+ readonly css: Record<string, number | string>;
28
+ readonly glsl: Record<string, number>;
29
+ readonly aria: Record<string, string>;
30
+ }
31
+ /**
32
+ * Expose the inner `Record<…>`s of a {@link CompositeState} as mutable views
33
+ * for the zero-allocation hot path. Single sanctioned site that strips
34
+ * `readonly` — do not cast at other call sites.
35
+ */
36
+ export declare function accessCompositeState(state: CompositeState): MutableCompositeStateViews;
37
+ /**
38
+ * Creates a ring-buffer pool of pre-allocated CompositeState objects.
39
+ * Acquire/release pattern avoids GC allocations on the hot render path.
40
+ * Default 8 slots -- enough for typical compositor with 4-6 quantizers + headroom.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const pool = CompositorStatePool.make(4);
45
+ * const state = pool.acquire();
46
+ * state.discrete['theme'] = 'dark';
47
+ * state.outputs.css['--bg'] = '#000';
48
+ * pool.release(state); // resets and returns to pool
49
+ * pool.available; // 4
50
+ * ```
51
+ */
52
+ declare function _make(capacity?: number): CompositorStatePoolShape;
53
+ /**
54
+ * CompositorStatePool -- ring buffer of pre-allocated CompositeState objects.
55
+ * Zero-allocation hot path: acquire a state, write into it, render, then release.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const pool = CompositorStatePool.make(8);
60
+ * const state = pool.acquire();
61
+ * // Write compositor output into state.discrete, state.blend, state.outputs
62
+ * pool.release(state); // resets and returns to pool
63
+ * console.log(pool.size, pool.available); // 8, 8
64
+ * ```
65
+ */
66
+ export declare const CompositorStatePool: {
67
+ make: typeof _make;
68
+ };
69
+ export declare namespace CompositorStatePool {
70
+ /** Structural shape of a pool instance: `acquire`, `release`, `size`, `available`. */
71
+ type Shape = CompositorStatePoolShape;
72
+ }
73
+ export {};
74
+ //# sourceMappingURL=compositor-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositor-pool.d.ts","sourceRoot":"","sources":["../src/compositor-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD,UAAU,wBAAwB;IAChC,OAAO,IAAI,cAAc,CAAC;IAC1B,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAUD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,0BAA0B,CAStF;AAoBD;;;;;;;;;;;;;;GAcG;AACH,iBAAS,KAAK,CAAC,QAAQ,SAAsB,GAAG,wBAAwB,CA+CvE;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB;;CAAkB,CAAC;AAEnD,MAAM,CAAC,OAAO,WAAW,mBAAmB,CAAC;IAC3C,sFAAsF;IACtF,KAAY,KAAK,GAAG,wBAAwB,CAAC;CAC9C"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * CompositorStatePool -- ring buffer of pre-allocated CompositeState objects.
3
+ *
4
+ * The compositor grabs one, writes into it, hands it to the renderer,
5
+ * which returns it after DOM application. Zero-allocation hot path.
6
+ *
7
+ * @module
8
+ */
9
+ import { COMPOSITOR_POOL_CAP } from './defaults.js';
10
+ /**
11
+ * Expose the inner `Record<…>`s of a {@link CompositeState} as mutable views
12
+ * for the zero-allocation hot path. Single sanctioned site that strips
13
+ * `readonly` — do not cast at other call sites.
14
+ */
15
+ export function accessCompositeState(state) {
16
+ const mutable = state;
17
+ return {
18
+ discrete: mutable.discrete,
19
+ blend: mutable.blend,
20
+ css: mutable.outputs.css,
21
+ glsl: mutable.outputs.glsl,
22
+ aria: mutable.outputs.aria,
23
+ };
24
+ }
25
+ function createMutableState() {
26
+ return {
27
+ discrete: {},
28
+ blend: {},
29
+ outputs: { css: {}, glsl: {}, aria: {} },
30
+ };
31
+ }
32
+ function resetState(state) {
33
+ // Clear all fields in-place (cheaper than allocation)
34
+ const { discrete, blend, css, glsl, aria } = accessCompositeState(state);
35
+ for (const k of Object.keys(discrete))
36
+ delete discrete[k];
37
+ for (const k of Object.keys(blend))
38
+ delete blend[k];
39
+ for (const k of Object.keys(css))
40
+ delete css[k];
41
+ for (const k of Object.keys(glsl))
42
+ delete glsl[k];
43
+ for (const k of Object.keys(aria))
44
+ delete aria[k];
45
+ }
46
+ /**
47
+ * Creates a ring-buffer pool of pre-allocated CompositeState objects.
48
+ * Acquire/release pattern avoids GC allocations on the hot render path.
49
+ * Default 8 slots -- enough for typical compositor with 4-6 quantizers + headroom.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const pool = CompositorStatePool.make(4);
54
+ * const state = pool.acquire();
55
+ * state.discrete['theme'] = 'dark';
56
+ * state.outputs.css['--bg'] = '#000';
57
+ * pool.release(state); // resets and returns to pool
58
+ * pool.available; // 4
59
+ * ```
60
+ */
61
+ function _make(capacity = COMPOSITOR_POOL_CAP) {
62
+ const buffer = [];
63
+ for (let i = 0; i < capacity; i++) {
64
+ buffer.push(createMutableState());
65
+ }
66
+ const free = new Array(capacity).fill(true);
67
+ let acquirePtr = 0;
68
+ return {
69
+ acquire() {
70
+ // Scan from current pointer for a free slot
71
+ for (let i = 0; i < capacity; i++) {
72
+ const idx = (acquirePtr + i) % capacity;
73
+ if (free[idx]) {
74
+ free[idx] = false;
75
+ acquirePtr = (idx + 1) % capacity;
76
+ return buffer[idx];
77
+ }
78
+ }
79
+ // All slots in use — allocate overflow (cold path)
80
+ const overflow = createMutableState();
81
+ buffer.push(overflow);
82
+ free.push(false);
83
+ return overflow;
84
+ },
85
+ release(state) {
86
+ const idx = buffer.indexOf(state);
87
+ if (idx !== -1) {
88
+ resetState(state);
89
+ free[idx] = true;
90
+ }
91
+ },
92
+ get size() {
93
+ return buffer.length;
94
+ },
95
+ get available() {
96
+ let count = 0;
97
+ for (let i = 0; i < free.length; i++) {
98
+ if (free[i])
99
+ count++;
100
+ }
101
+ return count;
102
+ },
103
+ };
104
+ }
105
+ /**
106
+ * CompositorStatePool -- ring buffer of pre-allocated CompositeState objects.
107
+ * Zero-allocation hot path: acquire a state, write into it, render, then release.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * const pool = CompositorStatePool.make(8);
112
+ * const state = pool.acquire();
113
+ * // Write compositor output into state.discrete, state.blend, state.outputs
114
+ * pool.release(state); // resets and returns to pool
115
+ * console.log(pool.size, pool.available); // 8, 8
116
+ * ```
117
+ */
118
+ export const CompositorStatePool = { make: _make };
119
+ //# sourceMappingURL=compositor-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositor-pool.js","sourceRoot":"","sources":["../src/compositor-pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Compositor -- merge multiple quantizers into composite state.
3
+ *
4
+ * The compositor aggregates discrete + blended state from all
5
+ * active quantizers into a single CompositeState, producing
6
+ * typed output channels (css, glsl, aria).
7
+ *
8
+ * Wired: DirtyFlags (selective recomputation), CompositorStatePool
9
+ * (zero-allocation), FrameBudget (priority scheduling), microtask batching,
10
+ * and RuntimeCoordinator (Plan + ECS-backed runtime bookkeeping).
11
+ *
12
+ * Hot path (computeStateSync) is plain JS — no Effect overhead.
13
+ * Effect is used only for resource lifecycle (create/scope) and
14
+ * reactive stream (SubscriptionRef.changes).
15
+ *
16
+ * @module
17
+ */
18
+ import type { Scope, Stream } from 'effect';
19
+ import { Effect } from 'effect';
20
+ import type { Boundary } from './boundary.js';
21
+ import type { FrameBudget } from './frame-budget.js';
22
+ import type { Quantizer } from './quantizer-types.js';
23
+ import { RuntimeCoordinator } from './runtime-coordinator.js';
24
+ /**
25
+ * Snapshot of the compositor's output per tick: discrete state names for each
26
+ * quantizer, their blend-weight vectors, and the compiled per-target output
27
+ * maps (`css` / `glsl` / `aria`).
28
+ */
29
+ export interface CompositeState {
30
+ readonly discrete: Record<string, string>;
31
+ readonly blend: Record<string, Record<string, number>>;
32
+ readonly outputs: {
33
+ readonly css: Record<string, number | string>;
34
+ readonly glsl: Record<string, number>;
35
+ readonly aria: Record<string, string>;
36
+ };
37
+ }
38
+ /**
39
+ * Options accepted by `Compositor.create`: pool capacity, optional
40
+ * frame-budget gating, and whether to enable speculative pre-evaluation.
41
+ */
42
+ export interface CompositorConfig {
43
+ readonly poolCapacity?: number;
44
+ readonly frameBudget?: FrameBudget.Shape;
45
+ readonly speculative?: boolean;
46
+ }
47
+ interface CompositorShape {
48
+ add<B extends Boundary.Shape>(name: string, quantizer: Quantizer<B>): Effect.Effect<void>;
49
+ remove(name: string): Effect.Effect<void>;
50
+ compute(): Effect.Effect<CompositeState>;
51
+ setBlendWeights(name: string, weights: Record<string, number>): Effect.Effect<void>;
52
+ evaluateSpeculative(name: string, value: number, velocity?: number): void;
53
+ scheduleBatch(): void;
54
+ readonly changes: Stream.Stream<CompositeState>;
55
+ readonly runtime: RuntimeCoordinator.Shape;
56
+ }
57
+ interface CompositorFactory {
58
+ create(config?: CompositorConfig): Effect.Effect<CompositorShape, never, Scope.Scope>;
59
+ }
60
+ /**
61
+ * Compositor — the live merge point for every attached {@link Quantizer}.
62
+ *
63
+ * `Compositor.create` hands back a scoped Effect that, when run inside a
64
+ * `Scope`, produces a compositor bound to a {@link RuntimeCoordinator}. Adding
65
+ * quantizers, marking dirty flags, and emitting CSS/GLSL/ARIA outputs all flow
66
+ * through the zero-allocation hot path backed by {@link CompositorStatePool}.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { Effect } from 'effect';
71
+ * import { Compositor } from '@czap/core';
72
+ *
73
+ * const program = Effect.scoped(Effect.gen(function* () {
74
+ * const compositor = yield* Compositor.create({ poolCapacity: 64, speculative: true });
75
+ * yield* compositor.add('viewport', viewportQuantizer);
76
+ * const state = yield* compositor.compute();
77
+ * // state.discrete.viewport === 'tablet'
78
+ * // state.outputs.css['--czap-viewport'] === 'tablet'
79
+ * }));
80
+ * ```
81
+ */
82
+ export declare const Compositor: CompositorFactory;
83
+ export declare namespace Compositor {
84
+ /** Structural shape of a live compositor instance. */
85
+ type Shape = CompositorShape;
86
+ /** Alias for {@link CompositorConfig}. */
87
+ type Config = CompositorConfig;
88
+ }
89
+ export {};
90
+ //# sourceMappingURL=compositor.d.ts.map