@elaraai/east-ui 1.0.80 → 1.0.82

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 (353) hide show
  1. package/dist/src/charts/chart/index.d.ts +4 -0
  2. package/dist/src/charts/chart/index.d.ts.map +1 -1
  3. package/dist/src/charts/spec/index.d.ts +8 -0
  4. package/dist/src/charts/spec/index.d.ts.map +1 -1
  5. package/dist/src/collections/deck/index.d.ts +8 -0
  6. package/dist/src/collections/deck/index.d.ts.map +1 -1
  7. package/dist/src/collections/index.d.ts +2 -2
  8. package/dist/src/collections/index.d.ts.map +1 -1
  9. package/dist/src/collections/index.js.map +1 -1
  10. package/dist/src/collections/library/index.d.ts +4 -0
  11. package/dist/src/collections/library/index.d.ts.map +1 -1
  12. package/dist/src/collections/library/types.d.ts +4 -0
  13. package/dist/src/collections/library/types.d.ts.map +1 -1
  14. package/dist/src/collections/matrix/index.d.ts +56 -19
  15. package/dist/src/collections/matrix/index.d.ts.map +1 -1
  16. package/dist/src/collections/matrix/index.js +38 -24
  17. package/dist/src/collections/matrix/index.js.map +1 -1
  18. package/dist/src/collections/plan/assemble.d.ts +655 -2113
  19. package/dist/src/collections/plan/assemble.d.ts.map +1 -1
  20. package/dist/src/collections/plan/assemble.js +159 -136
  21. package/dist/src/collections/plan/assemble.js.map +1 -1
  22. package/dist/src/collections/plan/builders.d.ts +193 -40
  23. package/dist/src/collections/plan/builders.d.ts.map +1 -1
  24. package/dist/src/collections/plan/builders.js +162 -32
  25. package/dist/src/collections/plan/builders.js.map +1 -1
  26. package/dist/src/collections/plan/factories.d.ts +290 -116
  27. package/dist/src/collections/plan/factories.d.ts.map +1 -1
  28. package/dist/src/collections/plan/factories.js +281 -156
  29. package/dist/src/collections/plan/factories.js.map +1 -1
  30. package/dist/src/collections/plan/index.d.ts +111 -58
  31. package/dist/src/collections/plan/index.d.ts.map +1 -1
  32. package/dist/src/collections/plan/index.js +62 -31
  33. package/dist/src/collections/plan/index.js.map +1 -1
  34. package/dist/src/collections/plan/ir.d.ts +759 -1769
  35. package/dist/src/collections/plan/ir.d.ts.map +1 -1
  36. package/dist/src/collections/plan/ir.js +51 -27
  37. package/dist/src/collections/plan/ir.js.map +1 -1
  38. package/dist/src/collections/plan/pick.d.ts +89 -71
  39. package/dist/src/collections/plan/pick.d.ts.map +1 -1
  40. package/dist/src/collections/plan/pick.js +101 -86
  41. package/dist/src/collections/plan/pick.js.map +1 -1
  42. package/dist/src/collections/plan/root.d.ts +164 -77
  43. package/dist/src/collections/plan/root.d.ts.map +1 -1
  44. package/dist/src/collections/plan/root.js +350 -42
  45. package/dist/src/collections/plan/root.js.map +1 -1
  46. package/dist/src/collections/plan/series.d.ts +12524 -10527
  47. package/dist/src/collections/plan/series.d.ts.map +1 -1
  48. package/dist/src/collections/plan/series.js +1596 -298
  49. package/dist/src/collections/plan/series.js.map +1 -1
  50. package/dist/src/collections/plan/types.d.ts +6115 -2802
  51. package/dist/src/collections/plan/types.d.ts.map +1 -1
  52. package/dist/src/collections/plan/types.js +575 -170
  53. package/dist/src/collections/plan/types.js.map +1 -1
  54. package/dist/src/collections/sheet/bridge.d.ts +154 -43
  55. package/dist/src/collections/sheet/bridge.d.ts.map +1 -1
  56. package/dist/src/collections/sheet/bridge.js +383 -240
  57. package/dist/src/collections/sheet/bridge.js.map +1 -1
  58. package/dist/src/collections/sheet/columns.d.ts +66 -16
  59. package/dist/src/collections/sheet/columns.d.ts.map +1 -1
  60. package/dist/src/collections/sheet/columns.js +25 -25
  61. package/dist/src/collections/sheet/columns.js.map +1 -1
  62. package/dist/src/collections/sheet/context-bridge.d.ts +48 -0
  63. package/dist/src/collections/sheet/context-bridge.d.ts.map +1 -0
  64. package/dist/src/collections/sheet/context-bridge.js +216 -0
  65. package/dist/src/collections/sheet/context-bridge.js.map +1 -0
  66. package/dist/src/collections/sheet/draft-bridge.d.ts +37 -0
  67. package/dist/src/collections/sheet/draft-bridge.d.ts.map +1 -0
  68. package/dist/src/collections/sheet/draft-bridge.js +153 -0
  69. package/dist/src/collections/sheet/draft-bridge.js.map +1 -0
  70. package/dist/src/collections/sheet/drafts.d.ts +14 -0
  71. package/dist/src/collections/sheet/drafts.d.ts.map +1 -0
  72. package/dist/src/collections/sheet/drafts.js +14 -0
  73. package/dist/src/collections/sheet/drafts.js.map +1 -0
  74. package/dist/src/collections/sheet/editing-bridge.d.ts +36 -0
  75. package/dist/src/collections/sheet/editing-bridge.d.ts.map +1 -0
  76. package/dist/src/collections/sheet/editing-bridge.js +196 -0
  77. package/dist/src/collections/sheet/editing-bridge.js.map +1 -0
  78. package/dist/src/collections/sheet/editing-types.d.ts +268 -0
  79. package/dist/src/collections/sheet/editing-types.d.ts.map +1 -0
  80. package/dist/src/collections/sheet/editing-types.js +34 -0
  81. package/dist/src/collections/sheet/editing-types.js.map +1 -0
  82. package/dist/src/collections/sheet/edits.d.ts +37 -0
  83. package/dist/src/collections/sheet/edits.d.ts.map +1 -0
  84. package/dist/src/collections/sheet/edits.js +31 -0
  85. package/dist/src/collections/sheet/edits.js.map +1 -0
  86. package/dist/src/collections/sheet/group.d.ts +165 -0
  87. package/dist/src/collections/sheet/group.d.ts.map +1 -0
  88. package/dist/src/collections/sheet/group.js +52 -0
  89. package/dist/src/collections/sheet/group.js.map +1 -0
  90. package/dist/src/collections/sheet/index.d.ts +171 -27
  91. package/dist/src/collections/sheet/index.d.ts.map +1 -1
  92. package/dist/src/collections/sheet/index.js +99 -17
  93. package/dist/src/collections/sheet/index.js.map +1 -1
  94. package/dist/src/collections/sheet/link.d.ts +22 -16
  95. package/dist/src/collections/sheet/link.d.ts.map +1 -1
  96. package/dist/src/collections/sheet/link.js +18 -12
  97. package/dist/src/collections/sheet/link.js.map +1 -1
  98. package/dist/src/collections/sheet/registers.d.ts +152 -5
  99. package/dist/src/collections/sheet/registers.d.ts.map +1 -1
  100. package/dist/src/collections/sheet/registers.js +154 -5
  101. package/dist/src/collections/sheet/registers.js.map +1 -1
  102. package/dist/src/collections/sheet/root.d.ts +175 -26
  103. package/dist/src/collections/sheet/root.d.ts.map +1 -1
  104. package/dist/src/collections/sheet/root.js +150 -26
  105. package/dist/src/collections/sheet/root.js.map +1 -1
  106. package/dist/src/collections/sheet/seed-bridge.d.ts +14 -0
  107. package/dist/src/collections/sheet/seed-bridge.d.ts.map +1 -0
  108. package/dist/src/collections/sheet/seed-bridge.js +51 -0
  109. package/dist/src/collections/sheet/seed-bridge.js.map +1 -0
  110. package/dist/src/collections/sheet/sub-rows.d.ts +249 -0
  111. package/dist/src/collections/sheet/sub-rows.d.ts.map +1 -0
  112. package/dist/src/collections/sheet/sub-rows.js +222 -0
  113. package/dist/src/collections/sheet/sub-rows.js.map +1 -0
  114. package/dist/src/collections/sheet/transactions.d.ts +76 -0
  115. package/dist/src/collections/sheet/transactions.d.ts.map +1 -0
  116. package/dist/src/collections/sheet/transactions.js +40 -0
  117. package/dist/src/collections/sheet/transactions.js.map +1 -0
  118. package/dist/src/collections/sheet/types.d.ts +12034 -3651
  119. package/dist/src/collections/sheet/types.d.ts.map +1 -1
  120. package/dist/src/collections/sheet/types.js +365 -48
  121. package/dist/src/collections/sheet/types.js.map +1 -1
  122. package/dist/src/collections/table/index.d.ts +98 -123
  123. package/dist/src/collections/table/index.d.ts.map +1 -1
  124. package/dist/src/collections/table/index.js +97 -111
  125. package/dist/src/collections/table/index.js.map +1 -1
  126. package/dist/src/collections/table/types.d.ts +87 -31
  127. package/dist/src/collections/table/types.d.ts.map +1 -1
  128. package/dist/src/collections/table/types.js +51 -26
  129. package/dist/src/collections/table/types.js.map +1 -1
  130. package/dist/src/collections/value-tree/flatten.d.ts.map +1 -1
  131. package/dist/src/collections/value-tree/flatten.js +4 -1
  132. package/dist/src/collections/value-tree/flatten.js.map +1 -1
  133. package/dist/src/component.d.ts +5075 -4079
  134. package/dist/src/component.d.ts.map +1 -1
  135. package/dist/src/component.js +46 -46
  136. package/dist/src/component.js.map +1 -1
  137. package/dist/src/contracts/approval.d.ts +10 -8
  138. package/dist/src/contracts/approval.d.ts.map +1 -1
  139. package/dist/src/contracts/approval.js +10 -8
  140. package/dist/src/contracts/approval.js.map +1 -1
  141. package/dist/src/contracts/drag.d.ts +11 -9
  142. package/dist/src/contracts/drag.d.ts.map +1 -1
  143. package/dist/src/contracts/drag.js +28 -21
  144. package/dist/src/contracts/drag.js.map +1 -1
  145. package/dist/src/contracts/editing.d.ts +1283 -0
  146. package/dist/src/contracts/editing.d.ts.map +1 -0
  147. package/dist/src/contracts/editing.js +711 -0
  148. package/dist/src/contracts/editing.js.map +1 -0
  149. package/dist/src/contracts/index.d.ts +2 -1
  150. package/dist/src/contracts/index.d.ts.map +1 -1
  151. package/dist/src/contracts/index.js +2 -1
  152. package/dist/src/contracts/index.js.map +1 -1
  153. package/dist/src/contracts/pick.d.ts +6 -7
  154. package/dist/src/contracts/pick.d.ts.map +1 -1
  155. package/dist/src/contracts/pick.js +6 -7
  156. package/dist/src/contracts/pick.js.map +1 -1
  157. package/dist/src/contracts/review.d.ts +3 -1
  158. package/dist/src/contracts/review.d.ts.map +1 -1
  159. package/dist/src/contracts/review.js +3 -1
  160. package/dist/src/contracts/review.js.map +1 -1
  161. package/dist/src/contracts/source.d.ts +270 -80
  162. package/dist/src/contracts/source.d.ts.map +1 -1
  163. package/dist/src/contracts/source.js +357 -58
  164. package/dist/src/contracts/source.js.map +1 -1
  165. package/dist/src/display/chip-rail/index.d.ts.map +1 -1
  166. package/dist/src/display/chip-rail/index.js +10 -10
  167. package/dist/src/display/chip-rail/index.js.map +1 -1
  168. package/dist/src/extension.d.ts +2 -1
  169. package/dist/src/extension.d.ts.map +1 -1
  170. package/dist/src/extension.js +2 -1
  171. package/dist/src/extension.js.map +1 -1
  172. package/dist/src/format/index.d.ts +1 -154
  173. package/dist/src/format/index.d.ts.map +1 -1
  174. package/dist/src/format/types.d.ts +35 -23
  175. package/dist/src/format/types.d.ts.map +1 -1
  176. package/dist/src/format/types.js +16 -14
  177. package/dist/src/format/types.js.map +1 -1
  178. package/dist/src/forms/field/index.js +4 -4
  179. package/dist/src/forms/field/index.js.map +1 -1
  180. package/dist/src/forms/file-upload/index.js +16 -16
  181. package/dist/src/forms/file-upload/index.js.map +1 -1
  182. package/dist/src/index.d.ts +4 -2
  183. package/dist/src/index.d.ts.map +1 -1
  184. package/dist/src/index.js +12 -5
  185. package/dist/src/index.js.map +1 -1
  186. package/dist/src/internal.d.ts +8 -3
  187. package/dist/src/internal.d.ts.map +1 -1
  188. package/dist/src/internal.js +11 -3
  189. package/dist/src/internal.js.map +1 -1
  190. package/dist/src/layout/box/index.d.ts.map +1 -1
  191. package/dist/src/layout/box/index.js +47 -47
  192. package/dist/src/layout/box/index.js.map +1 -1
  193. package/dist/src/layout/flex/index.d.ts.map +1 -1
  194. package/dist/src/layout/flex/index.js +47 -47
  195. package/dist/src/layout/flex/index.js.map +1 -1
  196. package/dist/src/layout/grid/index.js +11 -11
  197. package/dist/src/layout/grid/index.js.map +1 -1
  198. package/dist/src/layout/scroll-area/index.d.ts.map +1 -1
  199. package/dist/src/layout/scroll-area/index.js +8 -8
  200. package/dist/src/layout/scroll-area/index.js.map +1 -1
  201. package/dist/src/layout/separator/index.d.ts.map +1 -1
  202. package/dist/src/layout/separator/index.js +6 -6
  203. package/dist/src/layout/separator/index.js.map +1 -1
  204. package/dist/src/layout/stack/index.d.ts.map +1 -1
  205. package/dist/src/layout/stack/index.js +46 -46
  206. package/dist/src/layout/stack/index.js.map +1 -1
  207. package/dist/src/layout/sticky/index.d.ts.map +1 -1
  208. package/dist/src/layout/sticky/index.js +8 -8
  209. package/dist/src/layout/sticky/index.js.map +1 -1
  210. package/dist/src/overlays/action-bar/index.d.ts.map +1 -1
  211. package/dist/src/overlays/action-bar/index.js +8 -8
  212. package/dist/src/overlays/action-bar/index.js.map +1 -1
  213. package/dist/src/platform/index.d.ts +1 -1
  214. package/dist/src/platform/index.d.ts.map +1 -1
  215. package/dist/src/platform/index.js +1 -1
  216. package/dist/src/platform/index.js.map +1 -1
  217. package/dist/src/platform/slice/impl.d.ts +62 -51
  218. package/dist/src/platform/slice/impl.d.ts.map +1 -1
  219. package/dist/src/platform/slice/impl.js +155 -72
  220. package/dist/src/platform/slice/impl.js.map +1 -1
  221. package/dist/src/platform/slice/index.d.ts +3744 -2226
  222. package/dist/src/platform/slice/index.d.ts.map +1 -1
  223. package/dist/src/platform/slice/index.js +43 -1
  224. package/dist/src/platform/slice/index.js.map +1 -1
  225. package/dist/src/runtime/collections/deck.d.ts +4 -0
  226. package/dist/src/runtime/collections/deck.d.ts.map +1 -1
  227. package/dist/src/runtime/collections/matrix.d.ts +10 -9
  228. package/dist/src/runtime/collections/matrix.d.ts.map +1 -1
  229. package/dist/src/runtime/collections/matrix.js +11 -6
  230. package/dist/src/runtime/collections/matrix.js.map +1 -1
  231. package/dist/src/runtime/collections/plan.d.ts +148 -65
  232. package/dist/src/runtime/collections/plan.d.ts.map +1 -1
  233. package/dist/src/runtime/collections/plan.js +155 -67
  234. package/dist/src/runtime/collections/plan.js.map +1 -1
  235. package/dist/src/runtime/collections/sheet.d.ts +56 -23
  236. package/dist/src/runtime/collections/sheet.d.ts.map +1 -1
  237. package/dist/src/runtime/collections/sheet.js +30 -22
  238. package/dist/src/runtime/collections/sheet.js.map +1 -1
  239. package/dist/src/runtime/collections/table.d.ts +18 -11
  240. package/dist/src/runtime/collections/table.d.ts.map +1 -1
  241. package/dist/src/runtime/collections/table.js +7 -4
  242. package/dist/src/runtime/collections/table.js.map +1 -1
  243. package/dist/src/shared/reify.d.ts +4 -46
  244. package/dist/src/shared/reify.d.ts.map +1 -1
  245. package/dist/src/shared/reify.js +4 -61
  246. package/dist/src/shared/reify.js.map +1 -1
  247. package/dist/src/shared/tree.d.ts +88 -0
  248. package/dist/src/shared/tree.d.ts.map +1 -0
  249. package/dist/src/shared/tree.js +134 -0
  250. package/dist/src/shared/tree.js.map +1 -0
  251. package/dist/src/slice/breakdown/index.d.ts +4 -0
  252. package/dist/src/slice/breakdown/index.d.ts.map +1 -1
  253. package/dist/src/slice/breakdown/types.d.ts +4 -0
  254. package/dist/src/slice/breakdown/types.d.ts.map +1 -1
  255. package/dist/src/slice/cohort/index.d.ts +24 -4
  256. package/dist/src/slice/cohort/index.d.ts.map +1 -1
  257. package/dist/src/slice/cohort/index.js +8 -4
  258. package/dist/src/slice/cohort/index.js.map +1 -1
  259. package/dist/src/slice/cohort/types.d.ts +11 -0
  260. package/dist/src/slice/cohort/types.d.ts.map +1 -1
  261. package/dist/src/slice/cohort/types.js +7 -0
  262. package/dist/src/slice/cohort/types.js.map +1 -1
  263. package/dist/src/slice/filter/index.d.ts +4 -0
  264. package/dist/src/slice/filter/index.d.ts.map +1 -1
  265. package/dist/src/slice/filter/types.d.ts +4 -0
  266. package/dist/src/slice/filter/types.d.ts.map +1 -1
  267. package/dist/src/slice/index.d.ts +736 -0
  268. package/dist/src/slice/index.d.ts.map +1 -1
  269. package/dist/src/slice/legend/index.d.ts +4 -0
  270. package/dist/src/slice/legend/index.d.ts.map +1 -1
  271. package/dist/src/slice/legend/types.d.ts +4 -0
  272. package/dist/src/slice/legend/types.d.ts.map +1 -1
  273. package/dist/src/slice/rail/index.d.ts +8 -4
  274. package/dist/src/slice/rail/index.d.ts.map +1 -1
  275. package/dist/src/slice/rail/index.js.map +1 -1
  276. package/dist/src/slice/range/index.d.ts +4 -0
  277. package/dist/src/slice/range/index.d.ts.map +1 -1
  278. package/dist/src/slice/range/types.d.ts +4 -0
  279. package/dist/src/slice/range/types.d.ts.map +1 -1
  280. package/dist/src/slice/search/index.d.ts +4 -0
  281. package/dist/src/slice/search/index.d.ts.map +1 -1
  282. package/dist/src/slice/search/types.d.ts +4 -0
  283. package/dist/src/slice/search/types.d.ts.map +1 -1
  284. package/dist/src/slice/summary/index.d.ts +4 -0
  285. package/dist/src/slice/summary/index.d.ts.map +1 -1
  286. package/dist/src/slice/summary/types.d.ts +4 -0
  287. package/dist/src/slice/summary/types.d.ts.map +1 -1
  288. package/dist/src/typography/code/index.js +1 -1
  289. package/dist/src/typography/code/index.js.map +1 -1
  290. package/dist/src/typography/code-block/index.js +7 -7
  291. package/dist/src/typography/code-block/index.js.map +1 -1
  292. package/dist/src/typography/heading/index.js +2 -2
  293. package/dist/src/typography/heading/index.js.map +1 -1
  294. package/dist/src/typography/list/index.js +1 -1
  295. package/dist/src/typography/list/index.js.map +1 -1
  296. package/dist/src/typography/mark/index.js +1 -1
  297. package/dist/src/typography/mark/index.js.map +1 -1
  298. package/dist/src/typography/note/index.js +1 -1
  299. package/dist/src/typography/note/index.js.map +1 -1
  300. package/dist/src/typography/numeric/index.d.ts +3 -308
  301. package/dist/src/typography/numeric/index.d.ts.map +1 -1
  302. package/dist/src/typography/numeric/index.js +4 -4
  303. package/dist/src/typography/numeric/index.js.map +1 -1
  304. package/dist/src/typography/numeric/types.d.ts +1 -154
  305. package/dist/src/typography/numeric/types.d.ts.map +1 -1
  306. package/dist/src/typography/text/index.js +1 -1
  307. package/dist/src/typography/text/index.js.map +1 -1
  308. package/dist/test/collections/matrix.examples.d.ts +7 -3
  309. package/dist/test/collections/matrix.examples.d.ts.map +1 -1
  310. package/dist/test/collections/matrix.examples.js +55 -24
  311. package/dist/test/collections/matrix.examples.js.map +1 -1
  312. package/dist/test/collections/paged-source.examples.d.ts +4 -0
  313. package/dist/test/collections/paged-source.examples.d.ts.map +1 -1
  314. package/dist/test/collections/paged-source.examples.js +98 -13
  315. package/dist/test/collections/paged-source.examples.js.map +1 -1
  316. package/dist/test/collections/plan.examples.d.ts +101 -26
  317. package/dist/test/collections/plan.examples.d.ts.map +1 -1
  318. package/dist/test/collections/plan.examples.js +1481 -755
  319. package/dist/test/collections/plan.examples.js.map +1 -1
  320. package/dist/test/collections/sheet-link.examples.d.ts +7 -0
  321. package/dist/test/collections/sheet-link.examples.d.ts.map +1 -0
  322. package/dist/test/collections/sheet-link.examples.js +41 -0
  323. package/dist/test/collections/sheet-link.examples.js.map +1 -0
  324. package/dist/test/collections/sheet-transactions.examples.d.ts +7 -0
  325. package/dist/test/collections/sheet-transactions.examples.d.ts.map +1 -0
  326. package/dist/test/collections/sheet-transactions.examples.js +58 -0
  327. package/dist/test/collections/sheet-transactions.examples.js.map +1 -0
  328. package/dist/test/collections/sheet.examples.d.ts +52 -5
  329. package/dist/test/collections/sheet.examples.d.ts.map +1 -1
  330. package/dist/test/collections/sheet.examples.js +500 -158
  331. package/dist/test/collections/sheet.examples.js.map +1 -1
  332. package/dist/test/collections/table.examples.d.ts +31 -3
  333. package/dist/test/collections/table.examples.d.ts.map +1 -1
  334. package/dist/test/collections/table.examples.js +188 -28
  335. package/dist/test/collections/table.examples.js.map +1 -1
  336. package/dist/test/contracts/editing.examples.d.ts +7 -0
  337. package/dist/test/contracts/editing.examples.d.ts.map +1 -0
  338. package/dist/test/contracts/editing.examples.js +58 -0
  339. package/dist/test/contracts/editing.examples.js.map +1 -0
  340. package/dist/test/layout/splitter.examples.d.ts.map +1 -1
  341. package/dist/test/layout/splitter.examples.js +3 -1
  342. package/dist/test/layout/splitter.examples.js.map +1 -1
  343. package/dist/test/platform/slice.examples.d.ts.map +1 -1
  344. package/dist/test/platform/slice.examples.js +1 -0
  345. package/dist/test/platform/slice.examples.js.map +1 -1
  346. package/dist/test/slice/slice.examples.d.ts.map +1 -1
  347. package/dist/test/slice/slice.examples.js +5 -2
  348. package/dist/test/slice/slice.examples.js.map +1 -1
  349. package/package.json +4 -3
  350. package/dist/src/collections/plan/data-forms.d.ts +0 -332
  351. package/dist/src/collections/plan/data-forms.d.ts.map +0 -1
  352. package/dist/src/collections/plan/data-forms.js +0 -212
  353. package/dist/src/collections/plan/data-forms.js.map +0 -1
@@ -11,39 +11,44 @@
11
11
  * Chart measures, Matrix heat cells, Table numerals, Roster chips and event
12
12
  * marks — sliced and reviewed as one surface.
13
13
  *
14
- * Rows are **flat and KEYED** in the IR (`DictType(StringType, PlanRowType)`)
15
- * with `parent: Option<String>` keys — no nested `RecursiveType`. A row has
16
- * identity, not position: its `key` is what `parent` references, what `links`
17
- * address, what drag refs name and what focus / collapse / selection state is
18
- * keyed on, so the collection is a dictionary and two rows under one key are
19
- * unconstructable (#568). Dictionaries decode to a `SortedMap`, so the canvas
20
- * order is canonical KEY order — the order a paged Dict source's windows
21
- * already arrive in. The factories accept nested `rows: [...]` input and
22
- * flatten; parent aggregates (rollup bands, per-bucket heat means, table
23
- * subtotals) are derived renderer-side from the tree the `parent` keys encode.
14
+ * Rows are an ordered STREAM in the IR (`ArrayType(PlanRowType)`, #822): the
15
+ * stream IS the render order. The top-level series list is the layout — each
16
+ * series contributes its rows in declared order, as BLOCKS that travel apart
17
+ * ({@link PlanBlockType}, #823): a data series is one block of its entries'
18
+ * rows, which a paged canvas pages on its own, and a section's header and
19
+ * hand-built rows are fixed blocks drawn once — and a parent is followed by
20
+ * its descendants. A row has a TYPED identity
21
+ * ({@link PlanRowIdType}: the series that made it and the path of entry keys
22
+ * that leads to it), which is what `parent` references, what `links` address,
23
+ * what every callback reports and what focus / collapse / selection state is
24
+ * keyed on. Hierarchy comes from the data's own nesting (a series'
25
+ * `children`), never from a field value; parent aggregates (rollup bands,
26
+ * per-bucket heat means, table subtotals) are derived renderer-side from the
27
+ * tree the `parent` ids encode.
24
28
  *
25
29
  * This file holds only plain data — no UIComponent slots — so `component.ts`
26
30
  * can import it without a circular dependency. Since the data-interface
27
31
  * redesign (`Plan Data Interface.md` §3.2/§3.3) that includes the WHOLE row
28
32
  * vocabulary: elements (runs, bucket events, chips, event marks, decisions),
29
- * the row kind, the row itself and templates carry **no
30
- * `UIComponentType` and no per-element UI embeds** — rich surfaces resolve
31
- * through the ROOT's `popover` / `hover` / `expandRender` functions over
32
- * {@link PlanElementRefType} / row refs, so a row is
33
- * a storable, pageable dataset element. Only the root, review and the
34
- * resolver signatures stay UIComponent-coupled (`./ir.ts`, mirrored inline
35
- * with the recursion `node` in the `Plan` arm of `component.ts` — every
36
- * factory-built value is subtype-checked against the arm when the `Plan`
37
- * variant is constructed, so drift fails the specs).
33
+ * the row kind and the row itself carry **no `UIComponentType` and no
34
+ * per-element UI embeds** — rich surfaces resolve through the ROOT's
35
+ * `popover` / `hover` / `expandRender` functions over
36
+ * {@link PlanElementRefType} / row refs, so a row is a storable, pageable
37
+ * dataset element. Only the root, review and the resolver signatures stay
38
+ * UIComponent-coupled (`./ir.ts`, mirrored inline with the recursion `node`
39
+ * in the `Plan` arm of `component.ts`; the plan spec holds the two to one
40
+ * East type).
38
41
  *
39
42
  * @packageDocumentation
40
43
  */
41
- import { ArrayType, BooleanType, DateTimeType, DictType, FloatType, IntegerType, NullType, OptionType, StringType, StructType, VariantType, } from "@elaraai/east";
44
+ import { ArrayType, BlobType, BooleanType, DateTimeType, DictType, FloatType, FunctionType, IntegerType, NullType, OptionType, StringType, StructType, VariantType, } from "@elaraai/east";
42
45
  import { StatusValueType } from "../../feedback/status/types.js";
43
46
  import { IconType } from "../../display/icon/types.js";
44
47
  import { ColorSchemeType } from "../../style/scheme.js";
45
48
  import { EventStateType } from "../../contracts/states.js";
46
49
  import { ApprovalStateType } from "../../contracts/approval.js";
50
+ import { LibraryRefType } from "../../contracts/drag.js";
51
+ import { EditingDraftFieldType, EditingPatchEventTypeWith, EditingReadinessType, EditingSessionFields, } from "../../contracts/editing.js";
47
52
  import { TickFormatType } from "../../format/types.js";
48
53
  import { TimeResolutionType } from "../../contracts/time.js";
49
54
  import { ValueFormatType } from "../../contracts/format.js";
@@ -113,9 +118,11 @@ export const PlanAxisKindBrand = Symbol("PlanAxisKind");
113
118
  * at `week` resolution is exactly 12 columns. When a bound slice carries a
114
119
  * datetime range / resolution, the slice state supersedes these initial
115
120
  * values (the slice is the single source of truth for window + resolution);
116
- * `axis` seeds the defaults and covers the unbound case.
121
+ * `axis` seeds the defaults and covers the unbound case. There is no fit to
122
+ * the data (#822): a canvas states its window, or binds a slice whose range
123
+ * supplies it — the same inline and paged.
117
124
  *
118
- * @property window - Explicit window `[min, max)`. `none` ⇒ the bound slice's datetime range; else fit to the data
125
+ * @property window - Explicit window `[min, max)`. `none` ⇒ the bound slice's datetime range
119
126
  * @property resolution - Initial bucket unit (see {@link TimeResolutionType}); the toolbar segment overrides via slice state
120
127
  * @property resolutions - Resolution segment options (e.g. `[week, day]`); `[]` ⇒ no segment shown
121
128
  * @property now - The observed/plan split instant. `none` ⇒ no now-line
@@ -136,11 +143,11 @@ export const PlanTimeAxisType = StructType({
136
143
  * @remarks
137
144
  * Construct via `Plan.axis.number({ … })`. When a bound slice carries a
138
145
  * `float` / `integer` range, that range is the window (the horizon brush and
139
- * the `[` / `]` / `n` keys write it back); `window` seeds the unbound case,
140
- * else the axis fits to the data. There is no resolution segment on a
146
+ * the `[` / `]` / `n` keys write it back); `window` seeds the unbound case —
147
+ * there is no fit to the data (#822). There is no resolution segment on a
141
148
  * number axis — `step` is fixed by the declaration.
142
149
  *
143
- * @property window - Explicit half-open window `[min, max)`. `none` ⇒ the bound slice's numeric range; else fit to the data
150
+ * @property window - Explicit half-open window `[min, max)`. `none` ⇒ the bound slice's numeric range
144
151
  * @property step - The bucket width (`> 0`) — `n = window ÷ step`
145
152
  * @property now - The observed/plan split position. `none` ⇒ no now-line
146
153
  * @property format - Tick-label format (the shared {@link ValueFormatType} — `Chart.format.*`); `none` ⇒ plain numbers
@@ -196,6 +203,79 @@ export const PlanAxisType = VariantType({
196
203
  */
197
204
  export const PlanGrainType = VariantType({ group: NullType, resource: NullType });
198
205
  // ============================================================================
206
+ // Values — quantities, and how a bucket folds what falls in it (#824)
207
+ // ============================================================================
208
+ /**
209
+ * How the values that fall in one bucket fold into the one value it shows
210
+ * (#824). A canvas re-buckets every cell and chart point at the scale's
211
+ * resolution: switch WEEK → MONTH over weekly cells and each month shows ONE
212
+ * cell, the fold of its weeks, where it used to stack four.
213
+ *
214
+ * @remarks
215
+ * A bucket holding one value shows it as it is — its label, its text, its own
216
+ * instant — for every fold but `count`. A bucket holding several shows their
217
+ * fold at the bucket's start. Values with nothing in them (a `none` cell, a
218
+ * gap in a chart) are skipped; a bucket with no values left shows none.
219
+ *
220
+ * The defaults follow what the values mean: a heat cell is a level (`mean`),
221
+ * a weight cell the FRACTION of its bucket booked (`mean` — a month's fraction
222
+ * is its weeks' mean, where a sum would fill every bar), a segment the amount
223
+ * each fill holds (`sum`), a table numeral and a chart column an amount
224
+ * (`sum`), and a line or an area a level (`mean`).
225
+ *
226
+ * @property sum - The values added up
227
+ * @property mean - Their mean
228
+ * @property min - The least of them
229
+ * @property max - The greatest of them
230
+ * @property last - The one at the latest instant
231
+ * @property count - How many there are
232
+ */
233
+ export const PlanFoldType = VariantType({
234
+ sum: NullType,
235
+ mean: NullType,
236
+ min: NullType,
237
+ max: NullType,
238
+ last: NullType,
239
+ count: NullType,
240
+ });
241
+ /**
242
+ * A quantity — a number, its unit, and how it prints (#824). Runs and links
243
+ * carry one: a run's bar prints it after its label, a link's ribbon prints it
244
+ * as its caption and takes its share from it, and a parent's rollup band sums
245
+ * its runs' quantities unit by unit.
246
+ *
247
+ * @remarks
248
+ * The number is the value the canvas computes with, and the words are derived
249
+ * from it: `format` (the shared `Format.*` vocabulary, in the viewer's locale)
250
+ * prints `value`, followed by `unit`. `text` overrides the printed caption
251
+ * where the author wants their own words — the value still sums and weighs.
252
+ *
253
+ * @property value - The amount — what sums, weighs and compares
254
+ * @property unit - The unit it is in (`"t"`); quantities in different units never sum together
255
+ * @property format - How `value` prints (`Format.*`); `none` ⇒ the canvas's plain number
256
+ * @property text - The caption to print instead of the formatted value and unit
257
+ */
258
+ export const PlanQuantityType = StructType({
259
+ value: FloatType,
260
+ unit: OptionType(StringType),
261
+ format: OptionType(TickFormatType),
262
+ text: OptionType(StringType),
263
+ });
264
+ /**
265
+ * The scale heat cells paint on — the value at no depth, the value at full
266
+ * depth, and the threshold at or above which a cell wears the warn ring
267
+ * (#824 names it; it used to be three loose options on the heat arm).
268
+ *
269
+ * @property min - The value painted at no depth; `none` ⇒ the least value shown
270
+ * @property max - The value painted at full depth; `none` ⇒ the greatest value shown
271
+ * @property warnAt - The warn-ring threshold (a cell at or above it rings); `none` ⇒ no ring
272
+ */
273
+ export const PlanHeatScaleType = StructType({
274
+ min: OptionType(FloatType),
275
+ max: OptionType(FloatType),
276
+ warnAt: OptionType(FloatType),
277
+ });
278
+ // ============================================================================
199
279
  // Gutter — the left cell's identity vocabulary
200
280
  // ============================================================================
201
281
  /**
@@ -216,20 +296,20 @@ export const PlanGutterSwatchType = StructType({
216
296
  * `sub`, `value`, `meta`, `stacked`, `swatches` ride on every row factory).
217
297
  *
218
298
  * @property label - The row name (12.5/500; groups and names)
219
- * @property id - `true` ⇒ the label renders as a mono row id (11.5/600 — `L1-M03`, `COVERAGE`)
299
+ * @property id - `true` ⇒ the label renders as a mono row id (11.5/600 — `L1-M03`, `COVERAGE`); `false` by default
220
300
  * @property sub - The muted mono sub line (`"120 t"`, `"week · 1 lane"`)
221
301
  * @property value - The right-aligned mono value slot (`"94.2%"`, `"82"`) — the same aggregate slot a table group header uses
222
302
  * @property meta - The group meta line (`"8 rs · 82%"`)
223
- * @property stacked - `true` ⇒ two-line layout (label over sub; row min-height 42px)
303
+ * @property stacked - `true` ⇒ two-line layout (label over sub; row min-height 42px); `false` by default
224
304
  * @property swatches - Chart-series legend chips printed under the label
225
305
  */
226
306
  export const PlanGutterType = StructType({
227
307
  label: StringType,
228
- id: OptionType(BooleanType),
308
+ id: BooleanType,
229
309
  sub: OptionType(StringType),
230
310
  value: OptionType(StringType),
231
311
  meta: OptionType(StringType),
232
- stacked: OptionType(BooleanType),
312
+ stacked: BooleanType,
233
313
  swatches: ArrayType(PlanGutterSwatchType),
234
314
  });
235
315
  // ============================================================================
@@ -318,8 +398,13 @@ export const PlanAnimationType = VariantType({ none: NullType, pulse: NullType }
318
398
  * type (`DateTimeType` ⇒ `time`, numeric ⇒ `number`, `StringType` ⇒
319
399
  * `ordinal`) and must match the canvas axis at render.
320
400
  *
401
+ * @remarks
402
+ * A `y` that is not a finite number (`NaN`) is a GAP — a missing
403
+ * observation: a line or an area breaks there instead of bridging it, a
404
+ * column draws nothing, and the value counts toward no axis domain.
405
+ *
321
406
  * @property t - The instant on the shared scale
322
- * @property y - The measure value
407
+ * @property y - The measure value (`NaN` ⇒ a gap)
323
408
  */
324
409
  export const PlanChartPointType = StructType({ t: PlanInstantType, y: FloatType });
325
410
  /**
@@ -340,7 +425,8 @@ export const PlanAxisSideType = VariantType({ left: NullType, right: NullType })
340
425
  */
341
426
  export const PlanBreachType = VariantType({ above: FloatType, below: FloatType });
342
427
  /**
343
- * One `{t, lo, hi}` point of a band (area-range) chart layer.
428
+ * One `{t, lo, hi}` point of a band (area-range) chart layer. A bound that is
429
+ * not finite (`NaN`) makes the point a gap: the band breaks there.
344
430
  *
345
431
  * @property t - The instant on the shared scale
346
432
  * @property lo - The lower bound
@@ -354,7 +440,7 @@ export const PlanChartBandPointType = StructType({ t: PlanInstantType, lo: Float
354
440
  * arms are meaningful (a Plan chart row's time axis is the shared canvas
355
441
  * scale, never per-axis).
356
442
  *
357
- * @property domain - Explicit `[min, max]` extent (`none` ⇒ derived from the data)
443
+ * @property domain - Explicit `[min, max]` extent (`none` ⇒ derived from what the row draws: its values, an area's and each column's baseline, and every column stack's ends)
358
444
  * @property tickValues - Explicit tick positions printed at the gutter/plot edge (`none` ⇒ no ticks)
359
445
  * @property format - Optional tick format (the shared {@link ValueFormatType} — `Chart.format.*`)
360
446
  */
@@ -371,13 +457,23 @@ export const PlanChartAxisType = StructType({
371
457
  * @remarks
372
458
  * Renderer vocabulary (fixed by the spec, not the IR): lines draw solid ≤ now
373
459
  * and dashed after; columns observed `ink`, planned brand at half strength,
374
- * breach warn; stacked columns pair by `series`; refLines are dotted
375
- * gridlines with a mono label. `Chart.Bar` (horizontal) is a build-time error
376
- * on every axis kind — horizontal bars flip the frame the shared axis owns.
377
- *
378
- * @property line - A continuous line series (optional breach threshold)
379
- * @property area - A filled area series
380
- * @property column - Per-bucket columns (optional stack `series` id + breach)
460
+ * breach warn; stacked columns pair by `series`, each value axis stacking on
461
+ * its own — positive parts up from the baseline, negative parts down;
462
+ * refLines are dotted gridlines with a mono label. Every mark sits at its
463
+ * true instant — a point beyond the window keeps its position and the plot
464
+ * clips it. Hovering a bucket reads each data layer's value there.
465
+ * `Chart.Bar` (horizontal) is a build-time error on every axis kind —
466
+ * horizontal bars flip the frame the shared axis owns.
467
+ *
468
+ * A line, an area and a column series FOLD what falls in one bucket (#824):
469
+ * at a coarser resolution than its points, a column series draws one column
470
+ * per bucket — the `sum` of its points there by default — and a line or an
471
+ * area one vertex — their `mean` ({@link PlanFoldType}). Scatter points and
472
+ * bands draw every point where it is.
473
+ *
474
+ * @property line - A continuous line series (optional breach threshold; folds by `mean`)
475
+ * @property area - A filled area series (folds by `mean`)
476
+ * @property column - Per-bucket columns (optional stack `series` id + breach; folds by `sum`)
381
477
  * @property scatter - Point markers
382
478
  * @property band - A filled range (lo/hi per instant)
383
479
  * @property refLine - A horizontal reference line at a y value (dotted, mono label)
@@ -386,10 +482,10 @@ export const PlanChartAxisType = StructType({
386
482
  */
387
483
  export const PlanChartLayerType = VariantType({
388
484
  line: StructType({ points: ArrayType(PlanChartPointType), axis: PlanAxisSideType,
389
- breach: OptionType(PlanBreachType) }),
390
- area: StructType({ points: ArrayType(PlanChartPointType), axis: PlanAxisSideType }),
485
+ breach: OptionType(PlanBreachType), fold: PlanFoldType }),
486
+ area: StructType({ points: ArrayType(PlanChartPointType), axis: PlanAxisSideType, fold: PlanFoldType }),
391
487
  column: StructType({ points: ArrayType(PlanChartPointType), axis: PlanAxisSideType,
392
- series: OptionType(StringType), breach: OptionType(PlanBreachType) }),
488
+ series: OptionType(StringType), breach: OptionType(PlanBreachType), fold: PlanFoldType }),
393
489
  scatter: StructType({ points: ArrayType(PlanChartPointType), axis: PlanAxisSideType }),
394
490
  band: StructType({ points: ArrayType(PlanChartBandPointType), axis: PlanAxisSideType }),
395
491
  refLine: StructType({ y: FloatType, axis: PlanAxisSideType, label: OptionType(StringType) }),
@@ -415,7 +511,8 @@ export const PlanChartHeightType = VariantType({ spark: NullType, expanded: Null
415
511
  *
416
512
  * @property at - The bucket instant
417
513
  * @property value - The scalar (`none` ⇒ the 45° no-data hatch + `–`)
418
- * @property label - Optional printed value text (shown when the cell is ≥ 12px tall)
514
+ * @property label - Optional printed value text (shown when the cell is ≥ 12px tall); without one, a cell prints
515
+ * its value only when its arm declares a `format` (#824)
419
516
  */
420
517
  export const PlanHeatCellType = StructType({
421
518
  at: PlanInstantType,
@@ -458,23 +555,33 @@ export const PlanSegmentCellType = StructType({
458
555
  segments: ArrayType(PlanSegmentType),
459
556
  });
460
557
  /**
461
- * A heat row's cells — one of the three Matrix-borrowed cell recipes.
558
+ * A heat row's cells — one of the three Matrix-borrowed cell recipes, each
559
+ * declaring how a bucket folds the cells that fall in it and how their values
560
+ * print (#824).
462
561
  *
463
562
  * @remarks
464
- * `heat` carries its own scale (`min`/`max`, defaulting to the observed
465
- * extent) and an optional `warnAt` threshold (≥ it ⇒ the warn ring). Group
563
+ * `heat` carries the scale its own cells paint on ({@link PlanHeatScaleType}:
564
+ * `min`/`max`, defaulting to the extent shown, and the `warnAt` ring). Group
466
565
  * summary strips (§5) are exactly the `heat` arm computed over descendants.
467
566
  *
468
- * @property heat - Colour-depth cells + scale + warn threshold
469
- * @property weight - Booked-vs-free weight bars
470
- * @property segments - Weighted segment compositions
567
+ * `fold` ({@link PlanFoldType}) is how a coarser resolution than the cells'
568
+ * shows them — one cell per bucket: heat `mean` and weight `mean` by default
569
+ * (a level and a fraction), segments `sum` (each fill's weight adds up, then
570
+ * normalises). `format` prints the arm's values where the canvas prints one:
571
+ * a heat cell without a `label` of its own, a folded or derived heat cell, and
572
+ * the words a reader hears for a weight or a segment share.
573
+ *
574
+ * @property heat - Colour-depth cells, their scale, fold (`mean`) and format
575
+ * @property weight - Booked-vs-free weight bars, their fold (`mean`) and format
576
+ * @property segments - Weighted segment compositions, their fold (`sum`) and format
471
577
  */
472
578
  export const PlanHeatCellsType = VariantType({
473
- heat: StructType({ cells: ArrayType(PlanHeatCellType),
474
- min: OptionType(FloatType), max: OptionType(FloatType),
475
- warnAt: OptionType(FloatType) }),
476
- weight: ArrayType(PlanWeightCellType),
477
- segments: ArrayType(PlanSegmentCellType),
579
+ heat: StructType({ cells: ArrayType(PlanHeatCellType), scale: PlanHeatScaleType,
580
+ fold: PlanFoldType, format: OptionType(TickFormatType) }),
581
+ weight: StructType({ cells: ArrayType(PlanWeightCellType),
582
+ fold: PlanFoldType, format: OptionType(TickFormatType) }),
583
+ segments: StructType({ cells: ArrayType(PlanSegmentCellType),
584
+ fold: PlanFoldType, format: OptionType(TickFormatType) }),
478
585
  });
479
586
  /**
480
587
  * How a parent heat row derives its per-bucket cells from its children.
@@ -484,6 +591,20 @@ export const PlanHeatCellsType = VariantType({
484
591
  * @property sum - The per-bucket sum
485
592
  */
486
593
  export const PlanAggregateType = VariantType({ mean: NullType, max: NullType, sum: NullType });
594
+ /**
595
+ * What a collapsed group strip shows (#824) — ONE declaration, where there
596
+ * used to be two independent options (explicit cells, and an aggregate) that
597
+ * could both be set.
598
+ *
599
+ * @property none - A plain band
600
+ * @property cells - Explicit strip cells
601
+ * @property aggregate - Cells the canvas derives from the members' heat cells, per bucket
602
+ */
603
+ export const PlanGroupSummaryType = VariantType({
604
+ none: NullType,
605
+ cells: PlanHeatCellsType,
606
+ aggregate: PlanAggregateType,
607
+ });
487
608
  // ============================================================================
488
609
  // Table-row leaf data — bucketed numerals
489
610
  // ============================================================================
@@ -532,15 +653,17 @@ export const PlanTableSplitType = VariantType({ horizontal: NullType, vertical:
532
653
  * @property cells - The series' per-bucket cells (raw values)
533
654
  * @property format - Numeral format override for this series (`none` ⇒ the row's `format`)
534
655
  * @property tone - Default tone for the series' values (per-cell tones and derived neg/muted win)
535
- * @property strong - Semibold emphasis for this series' values
536
- * @property rollup - `true` ⇒ this series feeds declared parent aggregation (default: the first series)
656
+ * @property strong - Semibold emphasis for this series' values (`false` by default)
657
+ * @property rollup - `true` ⇒ this series feeds declared parent aggregation — flag none and every series does (`false` by default)
658
+ * @property fold - How a bucket folds the cells that fall in it at a coarser resolution ({@link PlanFoldType}; `sum` by default, #824)
537
659
  */
538
660
  export const PlanTableSeriesType = StructType({
539
661
  cells: ArrayType(PlanTableCellType),
540
662
  format: OptionType(TickFormatType),
541
663
  tone: OptionType(PlanTableToneType),
542
- strong: OptionType(BooleanType),
543
- rollup: OptionType(BooleanType),
664
+ strong: BooleanType,
665
+ rollup: BooleanType,
666
+ fold: PlanFoldType,
544
667
  });
545
668
  /**
546
669
  * A table row's emphasis — body, header (caption-styled numerals) or footer
@@ -571,82 +694,243 @@ export const PlanEventMarkKindType = VariantType({
571
694
  // Refs + callback payloads
572
695
  // ============================================================================
573
696
  /**
574
- * The Plan row-subject reference — rows are addressed by their stable `key`
575
- * (never an index; the flat row array reorders under grouping and grain).
697
+ * A row's identity (#822) — which series made it, and the path of entry keys
698
+ * that leads to it. Every callback that names a row (`onSelect`, an element
699
+ * ref's `row`, `links`, review, `expand`) carries this; `Plan.ref` /
700
+ * `Plan.sectionRef` build one.
576
701
  *
577
- * @property key - The row key
702
+ * @remarks
703
+ * A path segment is an entry's key: at the top level the source key — the
704
+ * String itself, or its `.east` text (`printFor(K)`) for any other key type —
705
+ * and below that a `Dict` child's key or an `Array` child's index. A path is
706
+ * unique by construction (keys within a collection, indices within an array),
707
+ * and series keys are unique across the whole series tree, so two rows can
708
+ * share an id only when a hand-built `Plan.series.rows` repeats a key — which
709
+ * renders as a row diagnostic, never a silent drop.
710
+ *
711
+ * A drag grammar `CellRef.row` carries the id's canonical text
712
+ * (`printFor(PlanRowIdType)`), so the shared drag grammar stays string-based.
713
+ *
714
+ * @property entry - A row made from a source entry (or a hand-built row): `{ series, path }` — `["L1"]`, `["L1", "m03"]`
715
+ * @property section - A section header (`Plan.series.section`), at its parent's path
578
716
  */
579
- export const PlanRowRefType = StructType({ key: StringType });
717
+ export const PlanRowIdType = VariantType({
718
+ entry: StructType({ series: StringType, path: ArrayType(StringType) }),
719
+ section: StructType({ series: StringType, path: ArrayType(StringType) }),
720
+ });
580
721
  /**
581
- * The `onRunClick` payload — a span bar was clicked.
722
+ * One run, by reference — its row's id and its key. What a `run` element ref
723
+ * carries, and what a link's two ends are.
582
724
  *
583
- * @property row - The row key
725
+ * @property row - The row's id
584
726
  * @property run - The run key
585
727
  */
586
- export const PlanRunClickEventType = StructType({ row: StringType, run: StringType });
728
+ export const PlanRunRefType = StructType({ row: PlanRowIdType, run: StringType });
587
729
  /**
588
- * The `onEventClick` payload — a bucket-event tile was clicked.
730
+ * One canvas element, by reference — what the root's ONE element callback
731
+ * (`onElementClick`, #824) and its generalized `popover` / `hover` resolvers
732
+ * (`Plan Data Interface.md` §3.3) are called with. Each ref carries the row's
733
+ * id plus the element's key, so one function covers every element kind.
589
734
  *
590
- * @property row - The row key
591
- * @property event - The event key
735
+ * @remarks
736
+ * Span decision diamonds ride the `mark` arm (mark keys are unique per row).
737
+ * A cell names its bucket by its instant (on the axis's arm), never an index:
738
+ * the cell's own instant, or — for a bucket that folds several cells — the
739
+ * bucket's start. A link names itself by its key and its two ends; it belongs
740
+ * to no one row. A resolver returning `none` for a ref opens no surface —
741
+ * per-element presence is the author's decision, made lazily at interaction
742
+ * time.
743
+ *
744
+ * @property run - A span run bar (`{ row, run }`)
745
+ * @property event - A bucket-event tile (`{ row, event }`)
746
+ * @property chip - A cards chip (`{ row, chip }`)
747
+ * @property mark - An event-row mark or span decision diamond (`{ row, mark }`)
748
+ * @property cell - A heat / table / weight / segment bucket cell (`{ row, at }`)
749
+ * @property link - A link ribbon (`{ key, from, to }` — the runs it joins)
592
750
  */
593
- export const PlanEventClickEventType = StructType({ row: StringType, event: StringType });
751
+ export const PlanElementRefType = VariantType({
752
+ run: PlanRunRefType,
753
+ event: StructType({ row: PlanRowIdType, event: StringType }),
754
+ chip: StructType({ row: PlanRowIdType, chip: StringType }),
755
+ mark: StructType({ row: PlanRowIdType, mark: StringType }),
756
+ cell: StructType({ row: PlanRowIdType, at: PlanInstantType }),
757
+ link: StructType({ key: StringType, from: PlanRunRefType, to: PlanRunRefType }),
758
+ });
594
759
  /**
595
- * The `onMarkClick` payload — an event-row mark or a span row's decision
596
- * diamond was clicked (mark keys are unique per row).
760
+ * The `onGroupToggle` payload — a row with children was expanded or collapsed
761
+ * (fires after the in-place swap).
597
762
  *
598
- * @property row - The row key
599
- * @property mark - The mark / decision key
763
+ * @property row - The row's id
764
+ * @property expanded - The new expansion state
600
765
  */
601
- export const PlanMarkClickEventType = StructType({ row: StringType, mark: StringType });
766
+ export const PlanGroupToggleEventType = StructType({ row: PlanRowIdType, expanded: BooleanType });
767
+ // ============================================================================
768
+ // Editing — the gestures a draft is made by (#880)
769
+ // ============================================================================
602
770
  /**
603
- * The `onChipClick` payload — a cards-row chip was clicked.
771
+ * A library card dropped on a row (#880) — what an editable series' `create`
772
+ * builds its new item from.
604
773
  *
605
- * @property row - The row key
606
- * @property chip - The chip key
774
+ * @remarks
775
+ * `at` is the start of the bucket the card landed in, on the axis's arm (a
776
+ * time axis's UTC instant, a number axis's bucket start, an ordinal axis's
777
+ * value) — the same instant a `cell` element ref reports.
778
+ *
779
+ * @property from - The card — the library that declared it and its item key
780
+ * @property row - The row it landed on
781
+ * @property at - The start of the bucket it landed in
782
+ * @property duplicate - Whether the drag was an alt-drag copy
607
783
  */
608
- export const PlanChipClickEventType = StructType({ row: StringType, chip: StringType });
784
+ export const PlanDropType = StructType({
785
+ from: LibraryRefType,
786
+ row: PlanRowIdType,
787
+ at: PlanInstantType,
788
+ duplicate: BooleanType,
789
+ });
609
790
  /**
610
- * The `onCellClick` payload — a heat / table / weight / segment bucket cell
611
- * was clicked. Carries the bucket instant (on the axis's arm), never an
612
- * index.
791
+ * A run, chip, tile or mark moved or resized (#825) — where its item goes and
792
+ * the instants it takes there, which the series write into the fields they
793
+ * declare (`edit: { key, start, end }`, or `at`).
613
794
  *
614
- * @property row - The row key
615
- * @property at - The clicked bucket's instant
795
+ * @remarks
796
+ * `key` is the element's key, which is its item's (`edit.key` names the item's
797
+ * key field). A move along its own row, or a resize, has `to` equal to `from`,
798
+ * and sets the item's instants where it is. A move to another row takes the
799
+ * item out of the list it was in and puts it, with its new instants, into the
800
+ * target row's list — even when the two rows come from different entries,
801
+ * which is then one gesture over both. A point element (a tile, a mark) moves
802
+ * to `start`, and `end` repeats it. A row's list keeps its keys unique, so a
803
+ * move onto a row whose list already holds the key is refused.
804
+ *
805
+ * @property key - The element's key — its item's key
806
+ * @property from - The row it was on
807
+ * @property to - The row it goes to — `from` itself for a resize, or a move along its row
808
+ * @property start - Its start after the gesture (a point element's instant)
809
+ * @property end - Its end after the gesture (a point element's instant again)
810
+ */
811
+ export const PlanMoveType = StructType({
812
+ key: StringType,
813
+ from: PlanRowIdType,
814
+ to: PlanRowIdType,
815
+ start: PlanInstantType,
816
+ end: PlanInstantType,
817
+ });
818
+ /**
819
+ * A gesture on the canvas — what one draft is made by (#880). A series writes
820
+ * it into the entry its row came from, through the fields it declares: a
821
+ * verdict into its `review.verdict` field, a drop into its `edit.items`, a
822
+ * move into the item's instant fields (and, across rows, into another row's
823
+ * list — #825).
824
+ *
825
+ * @property verdict - Approve or Reject (their "all" forms are the same verdict on every row the canvas holds)
826
+ * @property drop - A library card dropped on a row
827
+ * @property move - A run, chip, tile or mark moved or resized ({@link PlanMoveType}, #825)
616
828
  */
617
- export const PlanCellClickEventType = StructType({ row: StringType, at: PlanInstantType });
829
+ export const PlanGestureType = VariantType({
830
+ verdict: ApprovalStateType,
831
+ drop: PlanDropType,
832
+ move: PlanMoveType,
833
+ });
618
834
  /**
619
- * One canvas element, by reference — the subject of the root's generalized
620
- * `popover` / `hover` resolvers (`Plan Data Interface.md` §3.3). Every arm
621
- * reuses its click-event payload, so each ref carries the row key plus the
622
- * element key; one resolver function covers every element kind.
835
+ * How a row's elements move (#825) — present when its series declares the
836
+ * instant fields a move writes (`edit: { key, start, end }`, or `at`).
623
837
  *
624
838
  * @remarks
625
- * Span decision diamonds ride the `mark` arm (mark keys are unique per row).
626
- * A resolver returning `none` for a ref opens no surface — per-element
627
- * presence is the author's decision, made lazily at interaction time.
839
+ * `items` is the East type of the row's items, as East prints it: a run, chip,
840
+ * tile or mark moves onto another row only when that row's items are the same
841
+ * type, since the item itself changes lists. `resize` says whether the
842
+ * elements have two ends to drag (a run, a chip) or one instant (a tile, a
843
+ * mark).
844
+ *
845
+ * @property items - The row's item type, printed — rows of one item type share it
846
+ * @property resize - Whether its elements have a start and an end to resize
847
+ */
848
+ export const PlanMoveEditsType = StructType({
849
+ items: StringType,
850
+ resize: BooleanType,
851
+ });
852
+ /**
853
+ * Which gestures a row takes (#880) — whether its series declares the field
854
+ * each one writes, so the canvas offers only what a draft can hold: the
855
+ * decision buttons act on a `verdict` row, a card lands only on a `drop` row,
856
+ * and an element is picked up only on a `move` row (#825).
857
+ *
858
+ * @property verdict - Its series names the field a verdict writes (`review.verdict`)
859
+ * @property drop - Its series names where a dropped card lands and how it becomes an item (`edit.create`)
860
+ * @property move - Its series names the item fields a move writes (`edit.key` and `start` / `end`, or `at`) — {@link PlanMoveEditsType}
861
+ */
862
+ export const PlanRowEditsType = StructType({
863
+ verdict: BooleanType,
864
+ drop: BooleanType,
865
+ move: OptionType(PlanMoveEditsType),
866
+ });
867
+ /**
868
+ * The entries in one window a paged canvas reads — it pages its source at
869
+ * `w × PLAN_PAGE_SIZE`, and the editing session reads an entry back from the
870
+ * very window it came from, so a gesture never waits on a new request (#880).
871
+ */
872
+ export const PLAN_PAGE_SIZE = 200;
873
+ // ============================================================================
874
+ // The bound UI state (#824)
875
+ // ============================================================================
876
+ /**
877
+ * The canvas's interaction state, as a host holds it — the value behind a
878
+ * root's bound `ui` ({@link PlanUiBindType}). Bound, the canvas reads it and
879
+ * writes the user's actions back to it: a host selects a row, opens or folds
880
+ * one, expands a chart or brings a row into view from outside (a deep link, a
881
+ * list beside the canvas), and reads what the user did.
628
882
  *
629
- * @property run - A span run bar (`{ row, run }`)
630
- * @property event - A bucket-event tile (`{ row, event }`)
631
- * @property chip - A cards chip (`{ row, chip }`)
632
- * @property mark - An event-row mark or span decision diamond (`{ row, mark }`)
633
- * @property cell - A heat / table / weight / segment bucket cell (`{ row, at }`)
883
+ * @remarks
884
+ * Rows are named by their typed ids ({@link PlanRowIdType}) in lists — an
885
+ * East `Set` needs an immutable element type, and an id's path is an `Array`.
886
+ * The canvas treats each list as a set, keeps the order of what it finds there
887
+ * and adds what is new at the end.
888
+ *
889
+ * A row's collapse is the one it DECLARES (`collapsed`, per row) until
890
+ * someone decides otherwise: `collapsed` lists the rows folded against it
891
+ * or by the user, `expanded` the rows opened, and a row in neither follows its
892
+ * declaration — so binding `ui` changes nothing about a canvas until someone
893
+ * acts, and a row a paged window has not landed yet still folds as it
894
+ * declares. A row in both lists is collapsed.
895
+ *
896
+ * `focus` is a REQUEST, not a state: write a row's id and the canvas brings
897
+ * that row into view (opening the rows it nests under, and on a paged canvas
898
+ * loading its window — through the source's `seek` for a row it has not
899
+ * loaded yet), makes it the row the keyboard starts from, and clears the
900
+ * request (`none`). A row it cannot find clears it too.
901
+ *
902
+ * @property selected - The selected row (`none` ⇒ no selection)
903
+ * @property collapsed - Rows folded — overriding what they declare
904
+ * @property expanded - Rows opened — overriding what they declare
905
+ * @property charts - Chart rows expanded from spark to full height
906
+ * @property focus - A row to bring into view — spent (`none`) once the canvas has
634
907
  */
635
- export const PlanElementRefType = VariantType({
636
- run: PlanRunClickEventType,
637
- event: PlanEventClickEventType,
638
- chip: PlanChipClickEventType,
639
- mark: PlanMarkClickEventType,
640
- cell: PlanCellClickEventType,
908
+ export const PlanUiStateType = StructType({
909
+ selected: OptionType(PlanRowIdType),
910
+ collapsed: ArrayType(PlanRowIdType),
911
+ expanded: ArrayType(PlanRowIdType),
912
+ charts: ArrayType(PlanRowIdType),
913
+ focus: OptionType(PlanRowIdType),
641
914
  });
642
915
  /**
643
- * The `onGroupToggle` payload — a group strip was expanded or collapsed
644
- * (fires after the in-place swap).
916
+ * A bound {@link PlanUiStateType} — EXACTLY `State.bind`'s handle at it, so
917
+ * `State.bind([Plan.Types.UiState], key, Plan.uiState())` passes straight
918
+ * through as a root's `ui` (#824).
645
919
  *
646
- * @property row - The group row key
647
- * @property expanded - The new expansion state
920
+ * @remarks
921
+ * Field order is `read` / `write` / `has`: East struct subtyping is exact, so
922
+ * declaring the shape here means a change to `State.bind`'s fails this file's
923
+ * build rather than a canvas's.
924
+ *
925
+ * @property read - The current state
926
+ * @property write - Replace it
927
+ * @property has - Whether the key is set
648
928
  */
649
- export const PlanGroupToggleEventType = StructType({ row: StringType, expanded: BooleanType });
929
+ export const PlanUiBindType = StructType({
930
+ read: FunctionType([], PlanUiStateType),
931
+ write: FunctionType([PlanUiStateType], NullType),
932
+ has: FunctionType([], BooleanType),
933
+ });
650
934
  // ============================================================================
651
935
  // Footer + style
652
936
  // ============================================================================
@@ -655,12 +939,12 @@ export const PlanGroupToggleEventType = StructType({ row: StringType, expanded:
655
939
  *
656
940
  * @property text - The footer text (`"512 RESOURCES · 12 GROUPS · 3 IN VIEW"`)
657
941
  * @property tone - Optional status tint (`warning` for the exceptions count)
658
- * @property end - `true` ⇒ pushed to the right edge
942
+ * @property end - `true` ⇒ pushed to the right edge (`false` by default)
659
943
  */
660
944
  export const PlanFooterItemType = StructType({
661
945
  text: StringType,
662
946
  tone: OptionType(StatusValueType),
663
- end: OptionType(BooleanType),
947
+ end: BooleanType,
664
948
  });
665
949
  /**
666
950
  * The Plan style — uniform sizing (#320), density, and the gutter width.
@@ -677,7 +961,7 @@ export const PlanStyleType = StructType({
677
961
  gutterWidth: OptionType(StringType),
678
962
  });
679
963
  // ============================================================================
680
- // Templates + links — the plain vocabulary
964
+ // Links + expand — the plain vocabulary
681
965
  // ============================================================================
682
966
  /**
683
967
  * One quantity link between two runs — the Plan's edge vocabulary. The root's
@@ -686,20 +970,23 @@ export const PlanStyleType = StructType({
686
970
  * a quantity-weighted ribbon between the run edges it names; geometry is fixed
687
971
  * by the spec and lives in the renderer.
688
972
  *
689
- * @property fromRow - The source row key
690
- * @property fromRun - The source run key
691
- * @property toRow - The destination row key
692
- * @property toRun - The destination run key
693
- * @property quantity - The moved quantity (drives edge share + opacity)
694
- * @property label - The printed quantity caption (`"34 t"`)
973
+ * @remarks
974
+ * The quantity is a number with its unit and format (#824): its value weighs
975
+ * the ribbon's share of the family's largest, and its caption — `text`, else
976
+ * the value formatted with its unit — prints on the ribbon. A link without one
977
+ * draws at the faintest share and prints nothing. A click on a ribbon reports
978
+ * the `link` arm of the element ref, which names the link by its `key`.
979
+ *
980
+ * @property key - The link's identity (what a `link` element ref names it by)
981
+ * @property from - The source run (`{ row, run }` — the ribbon leaves its end)
982
+ * @property to - The destination run (the ribbon lands on its start)
983
+ * @property quantity - The moved quantity (share, opacity and caption)
695
984
  */
696
985
  export const PlanLinkType = StructType({
697
- fromRow: StringType,
698
- fromRun: StringType,
699
- toRow: StringType,
700
- toRun: StringType,
701
- quantity: FloatType,
702
- label: StringType,
986
+ key: StringType,
987
+ from: PlanRunRefType,
988
+ to: PlanRunRefType,
989
+ quantity: OptionType(PlanQuantityType),
703
990
  });
704
991
  /**
705
992
  * How a row's expand-in-place developer render treats the shared axis lines
@@ -720,21 +1007,20 @@ export const PlanExpandAxisType = VariantType({ keep: NullType, dim: NullType, o
720
1007
  * dependency arrows, no critical path.
721
1008
  *
722
1009
  * @remarks
723
- * `quantity` is the displayed `.q` suffix (`"96 t"`); `qty` is the optional
724
- * numeric twin the renderer sums into parent rollup bands — display and
725
- * arithmetic deliberately separate. `state` is the shared `EventStateType`
726
- * lifecycle driving the bar recipe; `status: warning` adds the `.stuck`
727
- * warn ring; `moved` collapses same-status churn to a `moved ×k` counter.
728
- * Rich click/hover surfaces resolve through the ROOT's `popover` / `hover`
729
- * functions with the `run` arm of {@link PlanElementRefType}.
1010
+ * `quantity` is ONE value (#824, {@link PlanQuantityType}): the bar prints its
1011
+ * caption after the label (the muted `.q` suffix, `"96 t"`), and a parent's
1012
+ * rollup band sums its runs' values unit by unit. `state` is the shared
1013
+ * `EventStateType` lifecycle driving the bar recipe; `status: warning` adds
1014
+ * the `.stuck` warn ring; `moved` collapses same-status churn to a `moved ×k`
1015
+ * counter. Rich click/hover surfaces resolve through the ROOT's `popover` /
1016
+ * `hover` functions with the `run` arm of {@link PlanElementRefType}.
730
1017
  */
731
1018
  export const PlanRunType = StructType({
732
1019
  key: StringType,
733
1020
  start: PlanInstantType,
734
1021
  end: PlanInstantType,
735
1022
  label: StringType,
736
- quantity: OptionType(StringType),
737
- qty: OptionType(FloatType),
1023
+ quantity: OptionType(PlanQuantityType),
738
1024
  state: EventStateType,
739
1025
  status: OptionType(StatusValueType),
740
1026
  moved: OptionType(IntegerType),
@@ -835,20 +1121,24 @@ export const PlanExpandType = StructType({
835
1121
  * `buckets` / `heat` / `table` / `cards` quantise to the bucket grid;
836
1122
  * `chart` draws per-bucket and continuous marks; `events` places instant
837
1123
  * marks; `group` is the heterogeneous container whose collapsed form is
838
- * its `summary` heat strip.
1124
+ * its `summary` heat strip. Whether a row with children starts collapsed is
1125
+ * the ROW's `collapsed` (every kind may have children, #822).
1126
+ *
1127
+ * A span parent's rollup bands sum its runs' quantities unit by unit — the
1128
+ * unit rides each quantity (#824). A heat parent's derived cells paint on the
1129
+ * kind's `scale` (#824 — it used to ride an empty cells arm). A chart row's
1130
+ * height is its `height` mode (`fixed` is its px), `expandedHeight` what the
1131
+ * expanded state opens to, and `expandable` whether the user may toggle it.
839
1132
  */
840
1133
  export const PlanRowKindType = VariantType({
841
1134
  group: StructType({
842
- summary: OptionType(PlanHeatCellsType),
843
- summaryAggregate: OptionType(PlanAggregateType),
844
- collapsed: OptionType(BooleanType),
1135
+ summary: PlanGroupSummaryType,
845
1136
  }),
846
1137
  span: StructType({
847
1138
  runs: ArrayType(PlanRunType),
848
1139
  decisions: ArrayType(PlanDecisionMarkType),
849
1140
  ports: ArrayType(PlanPortType),
850
1141
  rollup: OptionType(PlanRollupType),
851
- unit: OptionType(StringType),
852
1142
  }),
853
1143
  buckets: StructType({
854
1144
  lanes: ArrayType(PlanLaneType),
@@ -863,11 +1153,13 @@ export const PlanRowKindType = VariantType({
863
1153
  /** Height the EXPANDED state opens to, a CSS px size like every
864
1154
  * component height (`"120px"`; `none` ⇒ the 88px default). */
865
1155
  expandedHeight: OptionType(StringType),
866
- expandable: OptionType(BooleanType),
1156
+ expandable: BooleanType,
867
1157
  }),
868
1158
  heat: StructType({
869
1159
  cells: PlanHeatCellsType,
870
1160
  aggregate: OptionType(PlanAggregateType),
1161
+ /** The scale a parent's DERIVED cells paint on (#824); `none` ⇒ the extent they span. */
1162
+ scale: OptionType(PlanHeatScaleType),
871
1163
  }),
872
1164
  table: StructType({
873
1165
  series: ArrayType(PlanTableSeriesType),
@@ -884,57 +1176,170 @@ export const PlanRowKindType = VariantType({
884
1176
  }),
885
1177
  });
886
1178
  /**
887
- * One flat canvas row — a pure-data, storable, pageable dataset element
888
- * (no `UIComponentType`, no `FunctionType`).
1179
+ * One canvas row — a pure-data, storable, pageable dataset element (no
1180
+ * `UIComponentType`, no `FunctionType`).
889
1181
  *
890
1182
  * @remarks
891
- * Rows are flat and keyed, in canonical KEY order; `parent` keys encode the
892
- * tree (depth structurally unlimited — the Table `groupBy` guarantee), which
893
- * the renderer walks from the roots, so a subtree need not be contiguous in
894
- * the collection. `pinned`
895
- * rows render above the virtualised body under the ruler; `height` is a
896
- * fixed CSS-px override; `status` the quiet gutter dot; `approval` the
897
- * review verdict (rendered only with the root's review chrome); `expand`
898
- * the R2 declaration (the render itself is the root's `expandRender`
899
- * resolver).
1183
+ * Rows ride the canvas's STREAM ({@link PlanRowsCollectionType}), whose order
1184
+ * is the render order. `id` is the row's typed identity and `parent` the id of
1185
+ * the row it nests under — the tree the renderer derives aggregates from and
1186
+ * collapses by. A parent precedes its descendants, but they need not follow it
1187
+ * directly: an entry's children under `Plan.series.views` come after ALL of
1188
+ * that entry's view rows while nesting under the first of them. `collapsed` is
1189
+ * the initial state of a row that has children; `pinned` rows render above
1190
+ * the virtualised body under the ruler (both `false` unless declared, #824);
1191
+ * `height` is a fixed CSS-px override; `status` the quiet gutter dot;
1192
+ * `approval` the review verdict (rendered only with the root's review
1193
+ * chrome); `expand` the R2 declaration (the render itself is the root's
1194
+ * `expandRender` resolver); `edits` the gestures the row takes (#880 —
1195
+ * neither, unless its series declares the fields they write).
900
1196
  */
901
1197
  export const PlanRowType = StructType({
902
- key: StringType,
903
- parent: OptionType(StringType),
1198
+ id: PlanRowIdType,
1199
+ parent: OptionType(PlanRowIdType),
904
1200
  gutter: PlanGutterType,
905
1201
  kind: PlanRowKindType,
906
- pinned: OptionType(BooleanType),
1202
+ collapsed: BooleanType,
1203
+ pinned: BooleanType,
907
1204
  height: OptionType(StringType),
908
1205
  status: OptionType(StatusValueType),
909
1206
  approval: OptionType(ApprovalStateType),
910
1207
  expand: OptionType(PlanExpandType),
1208
+ edits: PlanRowEditsType,
911
1209
  });
912
1210
  /**
913
- * The canvas's row COLLECTION — rows keyed by their stable `key` (#568).
1211
+ * The canvas's rows — an ordered STREAM (#822). The stream IS the render
1212
+ * order: the top-level series each contribute one contiguous block in
1213
+ * declared order, and a parent is followed by its subtree.
914
1214
  *
915
1215
  * @remarks
916
- * A `Dict` cannot hold two entries under one key, so the duplicate rows a
917
- * per-window pipeline used to synthesize (a group parent re-emitted per paged
918
- * window) are unconstructable rather than gated. `Dict` also decodes to a
919
- * `SortedMap`, so the collection's order is canonical and deterministic —
920
- * `Array` preserved construction order and nothing else.
1216
+ * It used to be a `Dict` keyed by a row string, so the canvas sat in KEY
1217
+ * order and authors numbered their keys to get a layout; two series emitting
1218
+ * the same key silently lost a row. Identity is now the typed
1219
+ * {@link PlanRowIdType}, which is unique by construction, and order is the
1220
+ * series list's.
921
1221
  */
922
- export const PlanRowsCollectionType = DictType(StringType, PlanRowType);
1222
+ export const PlanRowsCollectionType = ArrayType(PlanRowType);
1223
+ /**
1224
+ * One BLOCK of the canvas's rows (#823) — the unit a paged canvas pages.
1225
+ *
1226
+ * @remarks
1227
+ * The series list lays the canvas out block by block, top to bottom. A data
1228
+ * series (`span`, `buckets`, `chart`, `heat`, `table`, `cards`, `events`,
1229
+ * `group`, `views`) is one block of its entries' rows, each entry's row
1230
+ * followed by its subtree: a window of a paged source holds its entries'
1231
+ * share, and a paged canvas pages each such block on its own over the one
1232
+ * source. A section's header and a `Plan.series.rows` block are FIXED — no
1233
+ * entry produces them, so every window serves them alike and the canvas draws
1234
+ * them once. A section is its header's block followed by its members' blocks,
1235
+ * so the series inside a section page on their own too: inline or paged, the
1236
+ * canvas draws the same rows in the same order.
1237
+ *
1238
+ * @property fixed - `true` when no entry produces the rows — a section's header, hand-built rows — so every window serves them alike
1239
+ * @property parent - The row the block's top rows nest under — the header of the section it sits in — or `none` at the top of the canvas
1240
+ * @property rows - The block's rows, in stream order
1241
+ */
1242
+ export const PlanBlockType = StructType({
1243
+ fixed: BooleanType,
1244
+ parent: OptionType(PlanRowIdType),
1245
+ rows: PlanRowsCollectionType,
1246
+ });
1247
+ /**
1248
+ * The canvas's BLOCKS (#823), in layout order — the series list's blocks, one
1249
+ * after another ({@link PlanBlockType}).
1250
+ *
1251
+ * @remarks
1252
+ * The blocks travel apart rather than concatenated so a paged canvas can page
1253
+ * each one on its own. A window of a paged source is every block's share of
1254
+ * that window's entries, so ONE read of a window serves every block, while
1255
+ * each block keeps its own residency over the source. Inline, the blocks are
1256
+ * the whole canvas, drawn one after another: the same rows in the same order
1257
+ * either way.
1258
+ */
1259
+ export const PlanBlocksType = ArrayType(PlanBlockType);
923
1260
  /**
924
1261
  * The paged source of a `data` + `series` canvas — the SHARED row-source
925
- * contract ({@link PagedSourceType}) instantiated at the canvas-row
926
- * COLLECTION (`Plan Data Interface.md` §3.8). The factory builds it from the
927
- * author's source (a `Data.bindPaged` handle, a `Paged.of` fixture) by
928
- * wrapping each window with the series' `derive` functions, so the renderer only
929
- * ever sees typed, KEYED canvas-row windows — no bytes, no domain types, and
930
- * no row a later window can duplicate.
1262
+ * contract ({@link PagedSourceType}) instantiated at the canvas's BLOCKS
1263
+ * (`Plan Data Interface.md` §3.8). The factory builds it from the author's
1264
+ * source (a `Data.bindPaged` handle, a `Paged.of` fixture) by wrapping each
1265
+ * window with the series' `derive` functions, so the renderer only ever sees
1266
+ * typed canvas-row windows — no bytes and no domain types. A window is the
1267
+ * canvas's blocks over that window's entries: each data series' block holds
1268
+ * the rows it derives from them, every entry with its whole subtree, and each
1269
+ * fixed block its rows as ever (#823).
931
1270
  */
932
- export const PlanPagedSourceType = PagedSourceType(PlanRowsCollectionType);
1271
+ export const PlanPagedSourceType = PagedSourceType(PlanBlocksType);
1272
+ /**
1273
+ * The root's rows channel — the shared {@link RowSourceType} at the canvas's
1274
+ * BLOCKS: `inline` blocks (what a `data`+`series` canvas over a collection
1275
+ * collapses to) or a `paged` source serving a window of every block at once.
1276
+ * One vocabulary across every collection, so a component never sniffs shapes
1277
+ * of its own (#567).
1278
+ */
1279
+ export const PlanRowsType = RowSourceType(PlanBlocksType);
1280
+ // ============================================================================
1281
+ // The editing wire (#880) — what the canvas hands the shared session
1282
+ // ============================================================================
1283
+ /**
1284
+ * What a Plan's `editing.onPatch` receives for entries of `R` (#880) — the
1285
+ * shared patch event (`Editing.Types.PatchEvent`) over the Plan's drafts,
1286
+ * which are whole entries (`Editing.Types.DraftField(R)`): every gesture
1287
+ * writes a complete entry, so a draft is always its `value`.
1288
+ *
1289
+ * @typeParam R - The entry type
1290
+ * @param entryType - The canvas's entry type
1291
+ * @returns The patch event type
1292
+ */
1293
+ export function PlanPatchEventTypeFor(entryType) {
1294
+ return EditingPatchEventTypeWith(entryType, EditingDraftFieldType(entryType));
1295
+ }
1296
+ /**
1297
+ * One entry's gesture, to be written (#880) — the entry's id (its key's text),
1298
+ * its bytes, the rows the gesture was made on, and the gesture. Approve all
1299
+ * writes every entry the canvas holds in one call, and a move to another row
1300
+ * writes the entry holding its source row, then the one holding its target
1301
+ * (#825) — one request when both rows are the same entry's.
1302
+ *
1303
+ * @internal
1304
+ * @property id - The entry's id — its key, as a row path's first segment spells it
1305
+ * @property entry - The entry as it stands now (its draft, else the source's), encoded
1306
+ * @property rows - The rows the gesture was made on — one, each of the entry's for a verdict on all, or a move's source then target
1307
+ * @property gesture - The gesture
1308
+ */
1309
+ export const PlanWriteRequestType = StructType({
1310
+ id: StringType,
1311
+ entry: BlobType,
1312
+ rows: ArrayType(PlanRowIdType),
1313
+ gesture: PlanGestureType,
1314
+ });
1315
+ /**
1316
+ * A drafted entry the author's readiness check reads (#880).
1317
+ *
1318
+ * @internal
1319
+ * @property id - The entry's id
1320
+ * @property entry - The drafted entry, encoded
1321
+ */
1322
+ export const PlanReadyEntryType = StructType({ id: StringType, entry: BlobType });
1323
+ const PlanEditingTypeImpl = StructType({
1324
+ ...EditingSessionFields,
1325
+ derive: FunctionType([IntegerType, IntegerType, DictType(StringType, BlobType)], OptionType(PlanBlocksType)),
1326
+ deriveEntry: FunctionType([StringType, BlobType], PlanBlocksType),
1327
+ write: FunctionType([ArrayType(PlanWriteRequestType)], ArrayType(OptionType(BlobType))),
1328
+ entryIds: FunctionType([IntegerType, IntegerType], OptionType(ArrayType(StringType))),
1329
+ ready: OptionType(FunctionType([ArrayType(PlanReadyEntryType)], ArrayType(EditingReadinessType))),
1330
+ });
933
1331
  /**
934
- * The root's rows channel — the shared {@link RowSourceType} at the canvas-row
935
- * COLLECTION: `inline` rows (what a `data`+`series` canvas over a collection
936
- * collapses to) or a `paged` source of the same shape. One vocabulary across
937
- * every collection, so a component never sniffs shapes of its own (#567).
1332
+ * The Plan's editing declaration, on the wire (#880) — the shared session's
1333
+ * fields ({@link EditingSessionFields}) and the canvas's own. Every value
1334
+ * crosses as bytes at the exact entry type the wire names, so the arm stays a
1335
+ * closed type whatever the canvas's entries are.
1336
+ *
1337
+ * @internal
1338
+ * @property derive - The canvas's blocks with drafted entries in place of the source's — `(offset, limit, drafts by id)`: inline the whole source (offset and limit unread), paged the window `(offset, limit)`, `none` while it is in flight. The series applied to the drafted entries, so a draft draws exactly as the applied batch would.
1339
+ * @property deriveEntry - One entry's blocks — `(id, entry)` — the rows a draft is compared by, where it was made
1340
+ * @property write - Gestures written into their entries — each request's entry, or `none` when no series takes it; a move carries its item from the request holding its source row to the one holding its target, and is refused whole (every result `none`) unless both take it — a target whose list already holds the item's key does not (#825)
1341
+ * @property entryIds - The ids of the source's entries `[offset, offset + limit)`, `none` while in flight — how the session reads an entry back after an Apply
1342
+ * @property ready - The author's readiness check over drafted entries, one result each, in order
938
1343
  */
939
- export const PlanRowsType = RowSourceType(PlanRowsCollectionType);
1344
+ export const PlanEditingType = PlanEditingTypeImpl;
940
1345
  //# sourceMappingURL=types.js.map