@elaraai/east-ui 1.0.86 → 1.0.87

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 (561) hide show
  1. package/dist/src/buttons/button/index.d.ts +4 -0
  2. package/dist/src/buttons/button/index.d.ts.map +1 -1
  3. package/dist/src/buttons/button/index.js +8 -1
  4. package/dist/src/buttons/button/index.js.map +1 -1
  5. package/dist/src/buttons/button/types.d.ts +6 -5
  6. package/dist/src/buttons/button/types.d.ts.map +1 -1
  7. package/dist/src/buttons/button/types.js.map +1 -1
  8. package/dist/src/buttons/icon-button/index.d.ts +5 -5
  9. package/dist/src/buttons/icon-button/index.d.ts.map +1 -1
  10. package/dist/src/buttons/icon-button/index.js +8 -2
  11. package/dist/src/buttons/icon-button/index.js.map +1 -1
  12. package/dist/src/buttons/icon-button/types.d.ts +8 -12
  13. package/dist/src/buttons/icon-button/types.d.ts.map +1 -1
  14. package/dist/src/buttons/icon-button/types.js +2 -2
  15. package/dist/src/buttons/icon-button/types.js.map +1 -1
  16. package/dist/src/buttons/toggle/index.d.ts +4 -0
  17. package/dist/src/buttons/toggle/index.d.ts.map +1 -1
  18. package/dist/src/buttons/toggle/index.js +6 -1
  19. package/dist/src/buttons/toggle/index.js.map +1 -1
  20. package/dist/src/buttons/toggle/types.d.ts +3 -2
  21. package/dist/src/buttons/toggle/types.d.ts.map +1 -1
  22. package/dist/src/buttons/toggle/types.js.map +1 -1
  23. package/dist/src/charts/chart/index.d.ts.map +1 -1
  24. package/dist/src/charts/chart/index.js +3 -3
  25. package/dist/src/charts/chart/index.js.map +1 -1
  26. package/dist/src/charts/spec/index.d.ts.map +1 -1
  27. package/dist/src/charts/spec/index.js +5 -2
  28. package/dist/src/charts/spec/index.js.map +1 -1
  29. package/dist/src/collections/deck/index.d.ts.map +1 -1
  30. package/dist/src/collections/deck/index.js +2 -2
  31. package/dist/src/collections/deck/index.js.map +1 -1
  32. package/dist/src/collections/index.d.ts +0 -6
  33. package/dist/src/collections/index.d.ts.map +1 -1
  34. package/dist/src/collections/index.js +0 -6
  35. package/dist/src/collections/index.js.map +1 -1
  36. package/dist/src/collections/library/index.d.ts +1 -1
  37. package/dist/src/collections/library/index.d.ts.map +1 -1
  38. package/dist/src/collections/library/index.js +2 -2
  39. package/dist/src/collections/library/index.js.map +1 -1
  40. package/dist/src/collections/schematic/index.d.ts.map +1 -1
  41. package/dist/src/collections/schematic/index.js +2 -2
  42. package/dist/src/collections/schematic/index.js.map +1 -1
  43. package/dist/src/collections/table/index.d.ts +1 -1
  44. package/dist/src/collections/table/index.d.ts.map +1 -1
  45. package/dist/src/collections/table/index.js +2 -2
  46. package/dist/src/collections/table/index.js.map +1 -1
  47. package/dist/src/collections/tree-view/index.d.ts +11 -32
  48. package/dist/src/collections/tree-view/index.d.ts.map +1 -1
  49. package/dist/src/collections/tree-view/index.js +15 -10
  50. package/dist/src/collections/tree-view/index.js.map +1 -1
  51. package/dist/src/component.d.ts +673 -9344
  52. package/dist/src/component.d.ts.map +1 -1
  53. package/dist/src/component.js +5 -259
  54. package/dist/src/component.js.map +1 -1
  55. package/dist/src/contracts/approval.d.ts +6 -8
  56. package/dist/src/contracts/approval.d.ts.map +1 -1
  57. package/dist/src/contracts/approval.js +6 -8
  58. package/dist/src/contracts/approval.js.map +1 -1
  59. package/dist/src/contracts/drag.d.ts +1 -1
  60. package/dist/src/contracts/drag.d.ts.map +1 -1
  61. package/dist/src/contracts/drag.js +4 -5
  62. package/dist/src/contracts/drag.js.map +1 -1
  63. package/dist/src/contracts/editing.d.ts +19 -19
  64. package/dist/src/contracts/editing.js +14 -14
  65. package/dist/src/contracts/fields.d.ts +471 -0
  66. package/dist/src/contracts/fields.d.ts.map +1 -0
  67. package/dist/src/contracts/fields.js +492 -0
  68. package/dist/src/contracts/fields.js.map +1 -0
  69. package/dist/src/contracts/index.d.ts +1 -0
  70. package/dist/src/contracts/index.d.ts.map +1 -1
  71. package/dist/src/contracts/index.js +1 -0
  72. package/dist/src/contracts/index.js.map +1 -1
  73. package/dist/src/contracts/indexed-source.d.ts +118 -0
  74. package/dist/src/contracts/indexed-source.d.ts.map +1 -0
  75. package/dist/src/contracts/indexed-source.js +89 -0
  76. package/dist/src/contracts/indexed-source.js.map +1 -0
  77. package/dist/src/contracts/pick.d.ts +0 -16
  78. package/dist/src/contracts/pick.d.ts.map +1 -1
  79. package/dist/src/contracts/review.d.ts +4 -6
  80. package/dist/src/contracts/review.d.ts.map +1 -1
  81. package/dist/src/contracts/review.js +4 -6
  82. package/dist/src/contracts/review.js.map +1 -1
  83. package/dist/src/contracts/source.d.ts +2 -2
  84. package/dist/src/contracts/source.d.ts.map +1 -1
  85. package/dist/src/contracts/source.js.map +1 -1
  86. package/dist/src/contracts/states.d.ts +1 -3
  87. package/dist/src/contracts/states.d.ts.map +1 -1
  88. package/dist/src/contracts/states.js +1 -3
  89. package/dist/src/contracts/states.js.map +1 -1
  90. package/dist/src/display/editable-chip/index.d.ts +2 -0
  91. package/dist/src/display/editable-chip/index.d.ts.map +1 -1
  92. package/dist/src/display/editable-chip/index.js +4 -1
  93. package/dist/src/display/editable-chip/index.js.map +1 -1
  94. package/dist/src/display/icon/index.d.ts +14 -31
  95. package/dist/src/display/icon/index.d.ts.map +1 -1
  96. package/dist/src/display/icon/index.js +15 -19
  97. package/dist/src/display/icon/index.js.map +1 -1
  98. package/dist/src/display/icon/solid.d.ts +24 -0
  99. package/dist/src/display/icon/solid.d.ts.map +1 -0
  100. package/dist/src/display/icon/solid.js +39 -0
  101. package/dist/src/display/icon/solid.js.map +1 -0
  102. package/dist/src/display/icon/types.d.ts +14 -38
  103. package/dist/src/display/icon/types.d.ts.map +1 -1
  104. package/dist/src/display/icon/types.js +6 -15
  105. package/dist/src/display/icon/types.js.map +1 -1
  106. package/dist/src/display/metric-chip/index.d.ts +2 -0
  107. package/dist/src/display/metric-chip/index.d.ts.map +1 -1
  108. package/dist/src/display/metric-chip/index.js +4 -1
  109. package/dist/src/display/metric-chip/index.js.map +1 -1
  110. package/dist/src/display/stat/index.d.ts +2 -0
  111. package/dist/src/display/stat/index.d.ts.map +1 -1
  112. package/dist/src/display/stat/index.js +4 -1
  113. package/dist/src/display/stat/index.js.map +1 -1
  114. package/dist/src/display/stat/types.d.ts +3 -5
  115. package/dist/src/display/stat/types.d.ts.map +1 -1
  116. package/dist/src/display/stat/types.js +5 -2
  117. package/dist/src/display/stat/types.js.map +1 -1
  118. package/dist/src/feedback/banner/index.d.ts +5 -3
  119. package/dist/src/feedback/banner/index.d.ts.map +1 -1
  120. package/dist/src/feedback/banner/index.js +4 -1
  121. package/dist/src/feedback/banner/index.js.map +1 -1
  122. package/dist/src/feedback/empty-state/index.d.ts +16 -19
  123. package/dist/src/feedback/empty-state/index.d.ts.map +1 -1
  124. package/dist/src/feedback/empty-state/index.js +17 -10
  125. package/dist/src/feedback/empty-state/index.js.map +1 -1
  126. package/dist/src/feedback/status/index.d.ts +5 -3
  127. package/dist/src/feedback/status/index.d.ts.map +1 -1
  128. package/dist/src/feedback/status/index.js +4 -1
  129. package/dist/src/feedback/status/index.js.map +1 -1
  130. package/dist/src/index.d.ts +5 -6
  131. package/dist/src/index.d.ts.map +1 -1
  132. package/dist/src/index.js +12 -11
  133. package/dist/src/index.js.map +1 -1
  134. package/dist/src/internal.d.ts +23 -16
  135. package/dist/src/internal.d.ts.map +1 -1
  136. package/dist/src/internal.js +29 -13
  137. package/dist/src/internal.js.map +1 -1
  138. package/dist/src/navigation/index.d.ts +0 -2
  139. package/dist/src/navigation/index.d.ts.map +1 -1
  140. package/dist/src/navigation/index.js +0 -2
  141. package/dist/src/navigation/index.js.map +1 -1
  142. package/dist/src/navigation/nav-list/index.d.ts +2 -0
  143. package/dist/src/navigation/nav-list/index.d.ts.map +1 -1
  144. package/dist/src/navigation/nav-list/index.js +4 -1
  145. package/dist/src/navigation/nav-list/index.js.map +1 -1
  146. package/dist/src/navigation/nav-list/types.d.ts +3 -14
  147. package/dist/src/navigation/nav-list/types.d.ts.map +1 -1
  148. package/dist/src/navigation/nav-list/types.js.map +1 -1
  149. package/dist/src/overlays/command-palette/index.d.ts +2 -0
  150. package/dist/src/overlays/command-palette/index.d.ts.map +1 -1
  151. package/dist/src/overlays/command-palette/index.js +5 -0
  152. package/dist/src/overlays/command-palette/index.js.map +1 -1
  153. package/dist/src/overlays/command-palette/types.d.ts +0 -8
  154. package/dist/src/overlays/command-palette/types.d.ts.map +1 -1
  155. package/dist/src/pick/index.d.ts +1 -17
  156. package/dist/src/pick/index.d.ts.map +1 -1
  157. package/dist/src/pick/index.js +1 -1
  158. package/dist/src/platform/slice/index.d.ts +1324 -2039
  159. package/dist/src/platform/slice/index.d.ts.map +1 -1
  160. package/dist/src/platform/slice/index.js +55 -74
  161. package/dist/src/platform/slice/index.js.map +1 -1
  162. package/dist/src/platform/slice/local.d.ts +743 -0
  163. package/dist/src/platform/slice/local.d.ts.map +1 -0
  164. package/dist/src/platform/slice/local.js +133 -0
  165. package/dist/src/platform/slice/local.js.map +1 -0
  166. package/dist/src/platform/slice/record-chrome.d.ts +211 -0
  167. package/dist/src/platform/slice/record-chrome.d.ts.map +1 -0
  168. package/dist/src/platform/slice/record-chrome.js +52 -0
  169. package/dist/src/platform/slice/record-chrome.js.map +1 -0
  170. package/dist/src/platform/slice/record-interval.d.ts +24 -0
  171. package/dist/src/platform/slice/record-interval.d.ts.map +1 -0
  172. package/dist/src/platform/slice/record-interval.js +61 -0
  173. package/dist/src/platform/slice/record-interval.js.map +1 -0
  174. package/dist/src/platform/slice/record-plan.d.ts +54 -0
  175. package/dist/src/platform/slice/record-plan.d.ts.map +1 -0
  176. package/dist/src/platform/slice/record-plan.js +139 -0
  177. package/dist/src/platform/slice/record-plan.js.map +1 -0
  178. package/dist/src/platform/slice/record-types.d.ts +2739 -0
  179. package/dist/src/platform/slice/record-types.d.ts.map +1 -0
  180. package/dist/src/platform/slice/record-types.js +209 -0
  181. package/dist/src/platform/slice/record-types.js.map +1 -0
  182. package/dist/src/platform/slice/record.d.ts +109 -0
  183. package/dist/src/platform/slice/record.d.ts.map +1 -0
  184. package/dist/src/platform/slice/record.js +210 -0
  185. package/dist/src/platform/slice/record.js.map +1 -0
  186. package/dist/src/reactive/match.d.ts +4 -6
  187. package/dist/src/reactive/match.d.ts.map +1 -1
  188. package/dist/src/reactive/match.js +4 -6
  189. package/dist/src/reactive/match.js.map +1 -1
  190. package/dist/src/runtime/collections/deck.d.ts.map +1 -1
  191. package/dist/src/runtime/collections/index.d.ts +0 -6
  192. package/dist/src/runtime/collections/index.d.ts.map +1 -1
  193. package/dist/src/runtime/collections/index.js +0 -6
  194. package/dist/src/runtime/collections/index.js.map +1 -1
  195. package/dist/src/runtime/display/icon.d.ts +6 -5
  196. package/dist/src/runtime/display/icon.d.ts.map +1 -1
  197. package/dist/src/runtime/display/icon.js +6 -5
  198. package/dist/src/runtime/display/icon.js.map +1 -1
  199. package/dist/src/runtime/feedback/empty-state.d.ts +5 -5
  200. package/dist/src/runtime/feedback/empty-state.js +5 -5
  201. package/dist/src/runtime/layout/dock.d.ts +2 -1
  202. package/dist/src/runtime/layout/dock.d.ts.map +1 -1
  203. package/dist/src/runtime/layout/dock.js +2 -1
  204. package/dist/src/runtime/layout/dock.js.map +1 -1
  205. package/dist/src/runtime/navigation/index.d.ts +0 -3
  206. package/dist/src/runtime/navigation/index.d.ts.map +1 -1
  207. package/dist/src/runtime/navigation/index.js +0 -3
  208. package/dist/src/runtime/navigation/index.js.map +1 -1
  209. package/dist/src/runtime/reactive/match.d.ts +2 -3
  210. package/dist/src/runtime/reactive/match.d.ts.map +1 -1
  211. package/dist/src/runtime/reactive/match.js +2 -3
  212. package/dist/src/runtime/reactive/match.js.map +1 -1
  213. package/dist/src/runtime/record-slice-source.d.ts +78 -0
  214. package/dist/src/runtime/record-slice-source.d.ts.map +1 -0
  215. package/dist/src/runtime/record-slice-source.js +201 -0
  216. package/dist/src/runtime/record-slice-source.js.map +1 -0
  217. package/dist/src/runtime/record-slice.d.ts +110 -0
  218. package/dist/src/runtime/record-slice.d.ts.map +1 -0
  219. package/dist/src/runtime/record-slice.js +374 -0
  220. package/dist/src/runtime/record-slice.js.map +1 -0
  221. package/dist/src/runtime/slice.d.ts +11 -13
  222. package/dist/src/runtime/slice.d.ts.map +1 -1
  223. package/dist/src/runtime/slice.js +41 -93
  224. package/dist/src/runtime/slice.js.map +1 -1
  225. package/dist/src/shared/plot-gutter.d.ts +1 -1
  226. package/dist/src/shared/plot-gutter.js +1 -1
  227. package/dist/src/shared/resolve-tag.d.ts +23 -0
  228. package/dist/src/shared/resolve-tag.d.ts.map +1 -0
  229. package/dist/src/shared/resolve-tag.js +26 -0
  230. package/dist/src/shared/resolve-tag.js.map +1 -0
  231. package/dist/src/shared/tree.d.ts +1 -1
  232. package/dist/src/shared/tree.js +1 -1
  233. package/dist/src/slice/breakdown/index.d.ts +1 -1
  234. package/dist/src/slice/breakdown/index.d.ts.map +1 -1
  235. package/dist/src/slice/breakdown/index.js +3 -3
  236. package/dist/src/slice/breakdown/index.js.map +1 -1
  237. package/dist/src/slice/cohort/index.d.ts +4 -5
  238. package/dist/src/slice/cohort/index.d.ts.map +1 -1
  239. package/dist/src/slice/cohort/index.js +6 -7
  240. package/dist/src/slice/cohort/index.js.map +1 -1
  241. package/dist/src/slice/filter/index.d.ts +1 -1
  242. package/dist/src/slice/filter/index.d.ts.map +1 -1
  243. package/dist/src/slice/filter/index.js +3 -3
  244. package/dist/src/slice/filter/index.js.map +1 -1
  245. package/dist/src/slice/index.d.ts +20 -2230
  246. package/dist/src/slice/index.d.ts.map +1 -1
  247. package/dist/src/slice/legend/index.d.ts +2 -2
  248. package/dist/src/slice/legend/index.d.ts.map +1 -1
  249. package/dist/src/slice/legend/index.js +4 -4
  250. package/dist/src/slice/legend/index.js.map +1 -1
  251. package/dist/src/slice/rail/index.d.ts +7 -4
  252. package/dist/src/slice/rail/index.d.ts.map +1 -1
  253. package/dist/src/slice/rail/index.js +10 -5
  254. package/dist/src/slice/rail/index.js.map +1 -1
  255. package/dist/src/slice/range/index.d.ts +1 -1
  256. package/dist/src/slice/range/index.d.ts.map +1 -1
  257. package/dist/src/slice/range/index.js +3 -3
  258. package/dist/src/slice/range/index.js.map +1 -1
  259. package/dist/src/slice/record/index.d.ts +171 -0
  260. package/dist/src/slice/record/index.d.ts.map +1 -0
  261. package/dist/src/slice/record/index.js +10 -0
  262. package/dist/src/slice/record/index.js.map +1 -0
  263. package/dist/src/slice/search/index.d.ts +6 -6
  264. package/dist/src/slice/search/index.d.ts.map +1 -1
  265. package/dist/src/slice/search/index.js +7 -7
  266. package/dist/src/slice/search/index.js.map +1 -1
  267. package/dist/src/slice/summary/index.d.ts +1 -1
  268. package/dist/src/slice/summary/index.d.ts.map +1 -1
  269. package/dist/src/slice/summary/index.js +3 -3
  270. package/dist/src/slice/summary/index.js.map +1 -1
  271. package/dist/src/typography/list/index.d.ts +2 -8
  272. package/dist/src/typography/list/index.d.ts.map +1 -1
  273. package/dist/src/typography/list/index.js +4 -1
  274. package/dist/src/typography/list/index.js.map +1 -1
  275. package/dist/src/typography/list/types.d.ts +0 -8
  276. package/dist/src/typography/list/types.d.ts.map +1 -1
  277. package/dist/test/collections/deck.examples.d.ts.map +1 -1
  278. package/dist/test/collections/deck.examples.js +6 -7
  279. package/dist/test/collections/deck.examples.js.map +1 -1
  280. package/dist/test/collections/index.d.ts +0 -1
  281. package/dist/test/collections/index.d.ts.map +1 -1
  282. package/dist/test/collections/index.js +0 -1
  283. package/dist/test/collections/index.js.map +1 -1
  284. package/dist/test/collections/library.examples.d.ts.map +1 -1
  285. package/dist/test/collections/library.examples.js +6 -7
  286. package/dist/test/collections/library.examples.js.map +1 -1
  287. package/dist/test/collections/schematic.examples.d.ts.map +1 -1
  288. package/dist/test/collections/schematic.examples.js +11 -19
  289. package/dist/test/collections/schematic.examples.js.map +1 -1
  290. package/dist/test/collections/tree-view.examples.js +2 -2
  291. package/dist/test/contracts/editing.examples.d.ts +1 -0
  292. package/dist/test/contracts/editing.examples.d.ts.map +1 -1
  293. package/dist/test/contracts/editing.examples.js +37 -6
  294. package/dist/test/contracts/editing.examples.js.map +1 -1
  295. package/dist/test/contracts/fields.examples.d.ts +7 -0
  296. package/dist/test/contracts/fields.examples.d.ts.map +1 -0
  297. package/dist/test/contracts/fields.examples.js +42 -0
  298. package/dist/test/contracts/fields.examples.js.map +1 -0
  299. package/dist/test/display/avatar.examples.d.ts.map +1 -1
  300. package/dist/test/display/avatar.examples.js +3 -3
  301. package/dist/test/display/avatar.examples.js.map +1 -1
  302. package/dist/test/display/icon.examples.d.ts.map +1 -1
  303. package/dist/test/display/icon.examples.js +12 -11
  304. package/dist/test/display/icon.examples.js.map +1 -1
  305. package/dist/test/feedback/empty-state.examples.js +9 -9
  306. package/dist/test/feedback/empty-state.examples.js.map +1 -1
  307. package/dist/test/layout/dock.examples.d.ts +0 -8
  308. package/dist/test/layout/dock.examples.d.ts.map +1 -1
  309. package/dist/test/layout/dock.examples.js +2 -42
  310. package/dist/test/layout/dock.examples.js.map +1 -1
  311. package/dist/test/layout/snap-grid.examples.d.ts.map +1 -1
  312. package/dist/test/layout/snap-grid.examples.js +18 -28
  313. package/dist/test/layout/snap-grid.examples.js.map +1 -1
  314. package/dist/test/navigation/index.d.ts +0 -2
  315. package/dist/test/navigation/index.d.ts.map +1 -1
  316. package/dist/test/navigation/index.js +0 -2
  317. package/dist/test/navigation/index.js.map +1 -1
  318. package/dist/test/navigation/nav-list.examples.js.map +1 -1
  319. package/dist/test/platform/index.d.ts +1 -0
  320. package/dist/test/platform/index.d.ts.map +1 -1
  321. package/dist/test/platform/index.js +1 -0
  322. package/dist/test/platform/index.js.map +1 -1
  323. package/dist/test/platform/slice-local.examples.d.ts +2 -0
  324. package/dist/test/platform/slice-local.examples.d.ts.map +1 -0
  325. package/dist/test/platform/slice-local.examples.js +31 -0
  326. package/dist/test/platform/slice-local.examples.js.map +1 -0
  327. package/dist/test/platform/slice.examples.js +61 -61
  328. package/dist/test/platform/slice.examples.js.map +1 -1
  329. package/dist/test/slice/slice.examples.d.ts +0 -1
  330. package/dist/test/slice/slice.examples.d.ts.map +1 -1
  331. package/dist/test/slice/slice.examples.js +67 -181
  332. package/dist/test/slice/slice.examples.js.map +1 -1
  333. package/package.json +4 -4
  334. package/dist/src/collections/board/index.d.ts +0 -855
  335. package/dist/src/collections/board/index.d.ts.map +0 -1
  336. package/dist/src/collections/board/index.js +0 -416
  337. package/dist/src/collections/board/index.js.map +0 -1
  338. package/dist/src/collections/board/types.d.ts +0 -111
  339. package/dist/src/collections/board/types.d.ts.map +0 -1
  340. package/dist/src/collections/board/types.js +0 -89
  341. package/dist/src/collections/board/types.js.map +0 -1
  342. package/dist/src/collections/calendar/index.d.ts +0 -446
  343. package/dist/src/collections/calendar/index.d.ts.map +0 -1
  344. package/dist/src/collections/calendar/index.js +0 -287
  345. package/dist/src/collections/calendar/index.js.map +0 -1
  346. package/dist/src/collections/calendar/types.d.ts +0 -338
  347. package/dist/src/collections/calendar/types.d.ts.map +0 -1
  348. package/dist/src/collections/calendar/types.js +0 -206
  349. package/dist/src/collections/calendar/types.js.map +0 -1
  350. package/dist/src/collections/flowchart/index.d.ts +0 -430
  351. package/dist/src/collections/flowchart/index.d.ts.map +0 -1
  352. package/dist/src/collections/flowchart/index.js +0 -292
  353. package/dist/src/collections/flowchart/index.js.map +0 -1
  354. package/dist/src/collections/flowchart/types.d.ts +0 -333
  355. package/dist/src/collections/flowchart/types.d.ts.map +0 -1
  356. package/dist/src/collections/flowchart/types.js +0 -263
  357. package/dist/src/collections/flowchart/types.js.map +0 -1
  358. package/dist/src/collections/plan/assemble.d.ts +0 -2274
  359. package/dist/src/collections/plan/assemble.d.ts.map +0 -1
  360. package/dist/src/collections/plan/assemble.js +0 -210
  361. package/dist/src/collections/plan/assemble.js.map +0 -1
  362. package/dist/src/collections/plan/builders.d.ts +0 -765
  363. package/dist/src/collections/plan/builders.d.ts.map +0 -1
  364. package/dist/src/collections/plan/builders.js +0 -673
  365. package/dist/src/collections/plan/builders.js.map +0 -1
  366. package/dist/src/collections/plan/factories.d.ts +0 -512
  367. package/dist/src/collections/plan/factories.d.ts.map +0 -1
  368. package/dist/src/collections/plan/factories.js +0 -539
  369. package/dist/src/collections/plan/factories.js.map +0 -1
  370. package/dist/src/collections/plan/index.d.ts +0 -324
  371. package/dist/src/collections/plan/index.d.ts.map +0 -1
  372. package/dist/src/collections/plan/index.js +0 -193
  373. package/dist/src/collections/plan/index.js.map +0 -1
  374. package/dist/src/collections/plan/ir.d.ts +0 -2490
  375. package/dist/src/collections/plan/ir.d.ts.map +0 -1
  376. package/dist/src/collections/plan/ir.js +0 -107
  377. package/dist/src/collections/plan/ir.js.map +0 -1
  378. package/dist/src/collections/plan/pick.d.ts +0 -133
  379. package/dist/src/collections/plan/pick.d.ts.map +0 -1
  380. package/dist/src/collections/plan/pick.js +0 -208
  381. package/dist/src/collections/plan/pick.js.map +0 -1
  382. package/dist/src/collections/plan/root.d.ts +0 -297
  383. package/dist/src/collections/plan/root.d.ts.map +0 -1
  384. package/dist/src/collections/plan/root.js +0 -427
  385. package/dist/src/collections/plan/root.js.map +0 -1
  386. package/dist/src/collections/plan/series.d.ts +0 -13887
  387. package/dist/src/collections/plan/series.d.ts.map +0 -1
  388. package/dist/src/collections/plan/series.js +0 -1710
  389. package/dist/src/collections/plan/series.js.map +0 -1
  390. package/dist/src/collections/plan/types.d.ts +0 -12612
  391. package/dist/src/collections/plan/types.d.ts.map +0 -1
  392. package/dist/src/collections/plan/types.js +0 -1345
  393. package/dist/src/collections/plan/types.js.map +0 -1
  394. package/dist/src/collections/roster/index.d.ts +0 -787
  395. package/dist/src/collections/roster/index.d.ts.map +0 -1
  396. package/dist/src/collections/roster/index.js +0 -325
  397. package/dist/src/collections/roster/index.js.map +0 -1
  398. package/dist/src/collections/roster/types.d.ts +0 -97
  399. package/dist/src/collections/roster/types.d.ts.map +0 -1
  400. package/dist/src/collections/roster/types.js +0 -72
  401. package/dist/src/collections/roster/types.js.map +0 -1
  402. package/dist/src/collections/sheet/bridge.d.ts +0 -376
  403. package/dist/src/collections/sheet/bridge.d.ts.map +0 -1
  404. package/dist/src/collections/sheet/bridge.js +0 -773
  405. package/dist/src/collections/sheet/bridge.js.map +0 -1
  406. package/dist/src/collections/sheet/columns.d.ts +0 -410
  407. package/dist/src/collections/sheet/columns.d.ts.map +0 -1
  408. package/dist/src/collections/sheet/columns.js +0 -99
  409. package/dist/src/collections/sheet/columns.js.map +0 -1
  410. package/dist/src/collections/sheet/context-bridge.d.ts +0 -48
  411. package/dist/src/collections/sheet/context-bridge.d.ts.map +0 -1
  412. package/dist/src/collections/sheet/context-bridge.js +0 -216
  413. package/dist/src/collections/sheet/context-bridge.js.map +0 -1
  414. package/dist/src/collections/sheet/draft-bridge.d.ts +0 -37
  415. package/dist/src/collections/sheet/draft-bridge.d.ts.map +0 -1
  416. package/dist/src/collections/sheet/draft-bridge.js +0 -153
  417. package/dist/src/collections/sheet/draft-bridge.js.map +0 -1
  418. package/dist/src/collections/sheet/drafts.d.ts +0 -14
  419. package/dist/src/collections/sheet/drafts.d.ts.map +0 -1
  420. package/dist/src/collections/sheet/drafts.js +0 -14
  421. package/dist/src/collections/sheet/drafts.js.map +0 -1
  422. package/dist/src/collections/sheet/editing-bridge.d.ts +0 -36
  423. package/dist/src/collections/sheet/editing-bridge.d.ts.map +0 -1
  424. package/dist/src/collections/sheet/editing-bridge.js +0 -196
  425. package/dist/src/collections/sheet/editing-bridge.js.map +0 -1
  426. package/dist/src/collections/sheet/editing-types.d.ts +0 -268
  427. package/dist/src/collections/sheet/editing-types.d.ts.map +0 -1
  428. package/dist/src/collections/sheet/editing-types.js +0 -34
  429. package/dist/src/collections/sheet/editing-types.js.map +0 -1
  430. package/dist/src/collections/sheet/edits.d.ts +0 -37
  431. package/dist/src/collections/sheet/edits.d.ts.map +0 -1
  432. package/dist/src/collections/sheet/edits.js +0 -31
  433. package/dist/src/collections/sheet/edits.js.map +0 -1
  434. package/dist/src/collections/sheet/group.d.ts +0 -165
  435. package/dist/src/collections/sheet/group.d.ts.map +0 -1
  436. package/dist/src/collections/sheet/group.js +0 -52
  437. package/dist/src/collections/sheet/group.js.map +0 -1
  438. package/dist/src/collections/sheet/index.d.ts +0 -351
  439. package/dist/src/collections/sheet/index.d.ts.map +0 -1
  440. package/dist/src/collections/sheet/index.js +0 -208
  441. package/dist/src/collections/sheet/index.js.map +0 -1
  442. package/dist/src/collections/sheet/link.d.ts +0 -398
  443. package/dist/src/collections/sheet/link.d.ts.map +0 -1
  444. package/dist/src/collections/sheet/link.js +0 -228
  445. package/dist/src/collections/sheet/link.js.map +0 -1
  446. package/dist/src/collections/sheet/registers.d.ts +0 -278
  447. package/dist/src/collections/sheet/registers.d.ts.map +0 -1
  448. package/dist/src/collections/sheet/registers.js +0 -268
  449. package/dist/src/collections/sheet/registers.js.map +0 -1
  450. package/dist/src/collections/sheet/root.d.ts +0 -328
  451. package/dist/src/collections/sheet/root.d.ts.map +0 -1
  452. package/dist/src/collections/sheet/root.js +0 -432
  453. package/dist/src/collections/sheet/root.js.map +0 -1
  454. package/dist/src/collections/sheet/seed-bridge.d.ts +0 -14
  455. package/dist/src/collections/sheet/seed-bridge.d.ts.map +0 -1
  456. package/dist/src/collections/sheet/seed-bridge.js +0 -51
  457. package/dist/src/collections/sheet/seed-bridge.js.map +0 -1
  458. package/dist/src/collections/sheet/sub-rows.d.ts +0 -249
  459. package/dist/src/collections/sheet/sub-rows.d.ts.map +0 -1
  460. package/dist/src/collections/sheet/sub-rows.js +0 -222
  461. package/dist/src/collections/sheet/sub-rows.js.map +0 -1
  462. package/dist/src/collections/sheet/transactions.d.ts +0 -76
  463. package/dist/src/collections/sheet/transactions.d.ts.map +0 -1
  464. package/dist/src/collections/sheet/transactions.js +0 -40
  465. package/dist/src/collections/sheet/transactions.js.map +0 -1
  466. package/dist/src/collections/sheet/types.d.ts +0 -14992
  467. package/dist/src/collections/sheet/types.d.ts.map +0 -1
  468. package/dist/src/collections/sheet/types.js +0 -1061
  469. package/dist/src/collections/sheet/types.js.map +0 -1
  470. package/dist/src/navigation/app/index.d.ts +0 -150
  471. package/dist/src/navigation/app/index.d.ts.map +0 -1
  472. package/dist/src/navigation/app/index.js +0 -191
  473. package/dist/src/navigation/app/index.js.map +0 -1
  474. package/dist/src/navigation/pages/index.d.ts +0 -165
  475. package/dist/src/navigation/pages/index.d.ts.map +0 -1
  476. package/dist/src/navigation/pages/index.js +0 -152
  477. package/dist/src/navigation/pages/index.js.map +0 -1
  478. package/dist/src/navigation/pages/types.d.ts +0 -111
  479. package/dist/src/navigation/pages/types.d.ts.map +0 -1
  480. package/dist/src/navigation/pages/types.js +0 -101
  481. package/dist/src/navigation/pages/types.js.map +0 -1
  482. package/dist/src/runtime/collections/board.d.ts +0 -73
  483. package/dist/src/runtime/collections/board.d.ts.map +0 -1
  484. package/dist/src/runtime/collections/board.js +0 -68
  485. package/dist/src/runtime/collections/board.js.map +0 -1
  486. package/dist/src/runtime/collections/calendar.d.ts +0 -54
  487. package/dist/src/runtime/collections/calendar.d.ts.map +0 -1
  488. package/dist/src/runtime/collections/calendar.js +0 -54
  489. package/dist/src/runtime/collections/calendar.js.map +0 -1
  490. package/dist/src/runtime/collections/flowchart.d.ts +0 -58
  491. package/dist/src/runtime/collections/flowchart.d.ts.map +0 -1
  492. package/dist/src/runtime/collections/flowchart.js +0 -54
  493. package/dist/src/runtime/collections/flowchart.js.map +0 -1
  494. package/dist/src/runtime/collections/plan.d.ts +0 -181
  495. package/dist/src/runtime/collections/plan.d.ts.map +0 -1
  496. package/dist/src/runtime/collections/plan.js +0 -186
  497. package/dist/src/runtime/collections/plan.js.map +0 -1
  498. package/dist/src/runtime/collections/roster.d.ts +0 -60
  499. package/dist/src/runtime/collections/roster.d.ts.map +0 -1
  500. package/dist/src/runtime/collections/roster.js +0 -59
  501. package/dist/src/runtime/collections/roster.js.map +0 -1
  502. package/dist/src/runtime/collections/sheet.d.ts +0 -122
  503. package/dist/src/runtime/collections/sheet.d.ts.map +0 -1
  504. package/dist/src/runtime/collections/sheet.js +0 -73
  505. package/dist/src/runtime/collections/sheet.js.map +0 -1
  506. package/dist/src/runtime/navigation/app.d.ts +0 -52
  507. package/dist/src/runtime/navigation/app.d.ts.map +0 -1
  508. package/dist/src/runtime/navigation/app.js +0 -53
  509. package/dist/src/runtime/navigation/app.js.map +0 -1
  510. package/dist/src/runtime/navigation/pages.d.ts +0 -50
  511. package/dist/src/runtime/navigation/pages.d.ts.map +0 -1
  512. package/dist/src/runtime/navigation/pages.js +0 -52
  513. package/dist/src/runtime/navigation/pages.js.map +0 -1
  514. package/dist/src/runtime/navigation/route.d.ts +0 -46
  515. package/dist/src/runtime/navigation/route.d.ts.map +0 -1
  516. package/dist/src/runtime/navigation/route.js +0 -47
  517. package/dist/src/runtime/navigation/route.js.map +0 -1
  518. package/dist/test/collections/board.examples.d.ts +0 -18
  519. package/dist/test/collections/board.examples.d.ts.map +0 -1
  520. package/dist/test/collections/board.examples.js +0 -297
  521. package/dist/test/collections/board.examples.js.map +0 -1
  522. package/dist/test/collections/calendar.examples.d.ts +0 -5
  523. package/dist/test/collections/calendar.examples.d.ts.map +0 -1
  524. package/dist/test/collections/calendar.examples.js +0 -147
  525. package/dist/test/collections/calendar.examples.js.map +0 -1
  526. package/dist/test/collections/flowchart.examples.d.ts +0 -17
  527. package/dist/test/collections/flowchart.examples.d.ts.map +0 -1
  528. package/dist/test/collections/flowchart.examples.js +0 -243
  529. package/dist/test/collections/flowchart.examples.js.map +0 -1
  530. package/dist/test/collections/plan.examples.d.ts +0 -200
  531. package/dist/test/collections/plan.examples.d.ts.map +0 -1
  532. package/dist/test/collections/plan.examples.js +0 -3665
  533. package/dist/test/collections/plan.examples.js.map +0 -1
  534. package/dist/test/collections/roster.examples.d.ts +0 -26
  535. package/dist/test/collections/roster.examples.d.ts.map +0 -1
  536. package/dist/test/collections/roster.examples.js +0 -237
  537. package/dist/test/collections/roster.examples.js.map +0 -1
  538. package/dist/test/collections/sheet-link.examples.d.ts +0 -7
  539. package/dist/test/collections/sheet-link.examples.d.ts.map +0 -1
  540. package/dist/test/collections/sheet-link.examples.js +0 -41
  541. package/dist/test/collections/sheet-link.examples.js.map +0 -1
  542. package/dist/test/collections/sheet-transactions.examples.d.ts +0 -7
  543. package/dist/test/collections/sheet-transactions.examples.d.ts.map +0 -1
  544. package/dist/test/collections/sheet-transactions.examples.js +0 -58
  545. package/dist/test/collections/sheet-transactions.examples.js.map +0 -1
  546. package/dist/test/collections/sheet.examples.d.ts +0 -96
  547. package/dist/test/collections/sheet.examples.d.ts.map +0 -1
  548. package/dist/test/collections/sheet.examples.js +0 -1040
  549. package/dist/test/collections/sheet.examples.js.map +0 -1
  550. package/dist/test/navigation/app.examples.d.ts +0 -22
  551. package/dist/test/navigation/app.examples.d.ts.map +0 -1
  552. package/dist/test/navigation/app.examples.js +0 -136
  553. package/dist/test/navigation/app.examples.js.map +0 -1
  554. package/dist/test/navigation/pages.examples.d.ts +0 -13
  555. package/dist/test/navigation/pages.examples.d.ts.map +0 -1
  556. package/dist/test/navigation/pages.examples.js +0 -113
  557. package/dist/test/navigation/pages.examples.js.map +0 -1
  558. package/dist/test/navigation/route.examples.d.ts +0 -13
  559. package/dist/test/navigation/route.examples.d.ts.map +0 -1
  560. package/dist/test/navigation/route.examples.js +0 -69
  561. package/dist/test/navigation/route.examples.js.map +0 -1
@@ -1,1710 +0,0 @@
1
- /**
2
- * Copyright (c) 2025 Elara AI Pty Ltd
3
- * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
- */
5
- /**
6
- * Plan series (#822) — the row recipes of a `data` + `series` canvas.
7
- *
8
- * A canvas is its `data` (keyed entries) plus a list of series. Each series
9
- * says which entries it takes (`match`), what kind of row each becomes, and
10
- * how to read that row's content from the entry; several series over one
11
- * source give each entry several rows. The top-level list IS the layout: each
12
- * series contributes its rows in declared order, as BLOCKS kept apart
13
- * (`PlanBlockType`, #823) — a data series one block of its entries' rows (an
14
- * ordered stream, `Array<PlanRow>`), which a paged canvas pages on its own; a
15
- * section its header's fixed block, then its members' blocks; hand-built rows
16
- * a fixed block.
17
- *
18
- * Hierarchy comes only from the data's own nesting. Every data series takes
19
- * `children`: a bare accessor returns more of THIS series' entries (to any
20
- * depth — a `RecursiveType` entry), and `Plan.children(of, [series…])` steps
21
- * down to a child collection of another type, laid out like a top-level list.
22
- * `Plan.series.section` puts a titled block over series, `Plan.series.views`
23
- * gives each entry one adjacent row per member series, and `Plan.series.rows`
24
- * places hand-built rows.
25
- *
26
- * Every row has a typed id — `{ series, path }`, the path the entry keys that
27
- * lead to it — and every series is a REAL EAST VALUE (the `DataBindHandleType`
28
- * pattern): its `derive` is a reified East function from the source to its
29
- * rows, so a series list can be bound, picked (`Plan.pick`) and stored. Each
30
- * builder also records how to BUILD the series for any collection type, which
31
- * is what lets a step-down compile its child series for the child collection's
32
- * type, the root compile them for a source keyed by any type, and the root
33
- * refuse two series sharing a key.
34
- *
35
- * @packageDocumentation
36
- */
37
- import { East, Expr, ArrayType, BlobType, BooleanType, DateTimeType, DictType, EastTypeType, FloatType, FunctionType, IntegerType, OptionType, RefType, StringType, StructType, VariantType, isTypeEqual, printFor, toEastTypeValue, variant, some, none, } from "@elaraai/east";
38
- import { StatusValueType } from "../../feedback/status/types.js";
39
- import { IconType } from "../../display/icon/types.js";
40
- import { ApprovalStateType } from "../../contracts/approval.js";
41
- import { TableAggregateType } from "../table/types.js";
42
- import { TickFormatType } from "../../format/types.js";
43
- import { reifyAccessor } from "../../shared/reify.js";
44
- import { PlanAggregateType, PlanExpandType, PlanGroupSummaryType, PlanHeatCellsType, PlanLaneType, PlanBucketEventType, PlanCellMarkerType, PlanChipType, PlanEventMarkType, PlanRunType, PlanDecisionMarkType, PlanPortType, PlanRollupType, PlanRowIdType, PlanRowKindType, PlanRowType, PlanRowsCollectionType, PlanBlockType, PlanBlocksType, PlanGestureType, PlanDropType, PlanInstantType, } from "./types.js";
45
- import { resolveTag, resolveIcon } from "./builders.js";
46
- import { planRow, planGutter, normalizeRows, REBASE_ROWS } from "./assemble.js";
47
- import { spanKind, bucketsKind, chartKind, heatKind, tableKind, cardsKind, eventsKind, groupKind, groupSummary, } from "./factories.js";
48
- // ============================================================================
49
- // The series type — a constructor, instantiated per row type
50
- // ============================================================================
51
- /**
52
- * The item a move to another row carries between its two writes (#825) — its
53
- * bytes, from the source row's write, which takes it out of its list, to the
54
- * target row's, which puts it into its own; `none` while nothing is in
55
- * transit. The canvas threads ONE through every row a gesture writes, in
56
- * order, and an item still carried at the end is a move that landed nowhere.
57
- *
58
- * @internal
59
- */
60
- export const PlanCarriedType = RefType(OptionType(BlobType));
61
- /**
62
- * The Plan series type CONSTRUCTOR — given the entry type (and the entries'
63
- * key type, `String` by default) it returns the concrete variant type of one
64
- * series value (the `DataBindHandleType` precedent: the entry type lives
65
- * structurally in each arm's `derive` signature, so a series built for one
66
- * entry type is a compile error against data of another).
67
- *
68
- * @remarks
69
- * Every arm carries the series' identity and `derive: Fn(Dict<K, R>) →
70
- * Array<PlanBlock>` — the blocks the series contributes (#823: a data series'
71
- * one block of its entries' rows, each followed by its subtree; a section's
72
- * header block, then its members'), reified once by its builder. The arm is
73
- * the series' kind, which is all the series library reads beyond the identity.
74
- *
75
- * It carries its writer too (#880), `write: Fn(R, K, RowId, Gesture,
76
- * Ref<Option<Blob>>) → Option<R>` — a gesture on one of its rows written into
77
- * the entry the row came from, through the fields the series declares
78
- * (`review.verdict`, `edit`), at whatever depth the row sits; `none` when no
79
- * series in its tree takes the gesture on that row. The `Ref` is the item a
80
- * move to another row carries (#825): the source row's write takes the item
81
- * out of its list into it, as bytes, and the target row's write puts it into
82
- * its own list — the two rows may be different series' and different
83
- * entries'. A series list is an East value (a pick, a stored list), so the
84
- * writer travels with the series rather than being rebuilt by the canvas.
85
- *
86
- * @param r - The entry type value
87
- * @param k - The entries' key type (default `StringType`)
88
- * @returns The concrete `VariantType` of a series over entries of `r` keyed by `k`
89
- */
90
- const seriesShape = (r, k = StringType) => {
91
- const arm = StructType({
92
- key: StringType,
93
- title: StringType,
94
- subtitle: OptionType(StringType),
95
- icon: OptionType(IconType),
96
- derive: FunctionType([DictType(k, r)], PlanBlocksType),
97
- write: FunctionType([r, k, PlanRowIdType, PlanGestureType, PlanCarriedType], OptionType(r)),
98
- });
99
- return VariantType({
100
- span: arm, buckets: arm, chart: arm, heat: arm, table: arm, cards: arm, events: arm,
101
- group: arm, section: arm, views: arm, rows: arm,
102
- });
103
- };
104
- /**
105
- * The Plan series type constructor — `Plan.Types.Series(RowType)` for a list
106
- * of series over `Dict<String, RowType>` entries, `Plan.Types.Series(RowType,
107
- * IntegerType)` over `Dict<Integer, RowType>`.
108
- */
109
- export const PlanSeriesType = seriesShape;
110
- /** Marks a {@link PlanChildren} step-down. */
111
- const PLAN_CHILDREN = Symbol("PlanChildren");
112
- /**
113
- * Step down from an entry to a child collection of another entry type (#822).
114
- *
115
- * @typeParam R - The parent entry type (inferred from where the step-down is used)
116
- * @typeParam KT - The parent entries' key type
117
- * @param of - The child collection — an `Array` (index order) or a `Dict` (key order) — from the parent entry
118
- * @param series - The series over the child entries, laid out like a top-level list
119
- * @returns The step-down, for a series' `children`
120
- */
121
- export function createChildren(of, series) {
122
- return { [PLAN_CHILDREN]: true, of, series };
123
- }
124
- function isStepDown(x) {
125
- return typeof x === "object" && x !== null && x[PLAN_CHILDREN] === true;
126
- }
127
- // ============================================================================
128
- // Build specs — how each series is built for a collection type
129
- // ============================================================================
130
- const PathType = ArrayType(StringType);
131
- const IdOptType = OptionType(PlanRowIdType);
132
- /** Every series value a builder made, with its build spec. */
133
- const SPECS = new WeakMap();
134
- /** The spec of a series value a `Plan.series.*` builder made, if it was one. */
135
- function specOf(s) {
136
- return typeof s === "object" && s !== null ? SPECS.get(s) : undefined;
137
- }
138
- /** A series value inside a composite series — it must come from a builder, since the parent builds it for its own entries. */
139
- function nestedSpec(s, where) {
140
- const spec = specOf(s);
141
- if (spec === undefined) {
142
- throw new Error(`${where}: a nested series must be a \`Plan.series.*\` value written in place — the parent builds it ` +
143
- "for its own entries, so a series bound to a variable elsewhere cannot be nested here");
144
- }
145
- return spec;
146
- }
147
- /** A readable name for a series, in messages. */
148
- function nameOf(spec) {
149
- return `${spec.arm} "${spec.title}"`;
150
- }
151
- /** A collection type's entry and key types — a `Dict`'s value and key, an `Array`'s element and `Integer` index. */
152
- function shapeOf(collection, where) {
153
- if (collection.type === "Dict")
154
- return { entry: collection.value, key: collection.key };
155
- if (collection.type === "Array")
156
- return { entry: collection.value, key: IntegerType };
157
- throw new Error(`${where}: entries come from a Dict (keyed) or an Array (by index) — got a ${collection.type}`);
158
- }
159
- /** Refuse a collection whose entries are not the series' entry type. */
160
- function assertEntry(entry, rowType, where) {
161
- if (!isTypeEqual(entry, rowType)) {
162
- throw new Error(`${where}: the series is built over one entry type and applied to entries of another — ` +
163
- `pass the entries' own type as the series' first argument`);
164
- }
165
- }
166
- /** A path segment from a key — a String key as is, any other key as its `.east` text. */
167
- function segmentOf(keyType) {
168
- return keyType.type === "String"
169
- ? (key) => key
170
- : (key) => East.print(key);
171
- }
172
- /**
173
- * A series' rows as ONE block (#823) — a data series' entries (`fixed: false`),
174
- * or rows no entry produces (`fixed: true`: hand-built rows), under the parent
175
- * the block nests in.
176
- *
177
- * @param collection - The collection type the rows are built for
178
- * @param rows - The series' rows emitter for that collection
179
- * @param fixed - Whether no entry produces the rows
180
- * @returns The block list's emitter
181
- */
182
- function oneBlock(collection, rows, fixed) {
183
- return East.function([collection, PathType, IdOptType], PlanBlocksType, ($, coll, prefix, parent) => {
184
- const block = $.let(East.value({ fixed, parent, rows: rows(coll, prefix, parent) }, PlanBlockType), PlanBlockType);
185
- return East.value([block], PlanBlocksType);
186
- });
187
- }
188
- /** A cache of built functions by East type. */
189
- class ByType {
190
- entries = [];
191
- get(type, build) {
192
- const hit = this.entries.find((e) => isTypeEqual(e.type, type));
193
- if (hit !== undefined)
194
- return hit.value;
195
- const value = build();
196
- this.entries.push({ type, value });
197
- return value;
198
- }
199
- }
200
- /** Build `fn`, naming the series and the key type when its accessors do not build for it. */
201
- function building(where, keyType, fn) {
202
- try {
203
- return fn();
204
- }
205
- catch (err) {
206
- const kt = keyType.type;
207
- const reason = err instanceof Error ? err.message : String(err);
208
- throw new Error(`${where}: its accessors do not build for entries keyed by ${kt} (${reason}) — the key an accessor ` +
209
- `receives is the collection's: the source's key, a Dict child's key, or an Array child's Integer ` +
210
- "index. Declare the key type the accessors expect with `keyType`, or leave the key unread.");
211
- }
212
- }
213
- /**
214
- * How `accessor` reaches the child collection it returns, read off the
215
- * expression it builds (#880): a plain field of the entry (`r => r.children`,
216
- * `Plan.children(r => r.lines, …)`), or the entry itself (`g => g`). A write
217
- * follows either back into the entry. Anything else — a filtered or computed
218
- * collection — is a copy a write would be lost in, and is `undefined`.
219
- *
220
- * @param rowType - The entry type
221
- * @param keyType - The entries' key type
222
- * @param accessor - The accessor, over the entry (its node, when recursive) and key
223
- * @returns How it reaches its collection, or `undefined` when a write cannot follow it
224
- */
225
- function childRefOf(rowType, keyType, accessor) {
226
- const recursive = rowType.type === "Recursive";
227
- let found;
228
- East.function([rowType, keyType], undefined, (_$, v, k) => {
229
- const node = recursive ? v.unwrap() : v;
230
- const out = accessor(node, k);
231
- const ast = Expr.ast(out);
232
- const param = Expr.ast(v);
233
- const nodeAst = Expr.ast(node);
234
- if (ast === param || ast === nodeAst)
235
- found = { kind: "self" };
236
- else if (ast.ast_type === "GetField" && ast.field !== undefined && (ast.struct === nodeAst || ast.struct === param)) {
237
- found = { kind: "field", field: ast.field };
238
- }
239
- return out;
240
- });
241
- return found;
242
- }
243
- /** Each key type's segment reader, built once. */
244
- const segmentKeys = new ByType();
245
- /**
246
- * A path segment read back as its collection's key (#880) — the inverse of
247
- * {@link segmentOf}: a String key as it is, any other key its `.east` text
248
- * parsed (an `Array` child's segment is its Integer index).
249
- *
250
- * @param keyType - The collection's key type
251
- * @returns `(segment) → key`
252
- */
253
- function segmentKeyOf(keyType) {
254
- return segmentKeys.get(keyType, () => (keyType.type === "String"
255
- ? East.function([StringType], StringType, (_$, s) => s)
256
- : East.function([StringType], keyType, (_$, s) => s.parse(keyType))));
257
- }
258
- /**
259
- * A child collection's part of a write (#880) — whether it holds a key, its
260
- * entry at it, and that entry written back in place. A `Dict` by key; an
261
- * `Array` by index.
262
- */
263
- function collectionOps(collection) {
264
- if (collection.type === "Dict") {
265
- const dict = (c) => c;
266
- return {
267
- has: (c, k) => dict(c).has(k),
268
- get: (c, k) => dict(c).get(k),
269
- put: (c, k, v) => dict(c).update(k, v),
270
- };
271
- }
272
- const array = (c) => c;
273
- const index = (k) => k;
274
- return {
275
- has: (c, k) => index(k).greaterEqual(0n).and(() => index(k).less(array(c).size())),
276
- get: (c, k) => array(c).get(index(k)),
277
- put: (c, k, v) => array(c).update(index(k), v),
278
- };
279
- }
280
- /** The instant fields a kind's elements have (#825): two ends (a run, a chip) or one instant (a tile, a mark). */
281
- function editShapeOf(arm) {
282
- return arm === "span" || arm === "cards" ? "span" : "point";
283
- }
284
- /** The item field types a move can write an instant into (#825). */
285
- const INSTANT_FIELD_TYPES = [DateTimeType, FloatType, IntegerType, StringType, PlanInstantType];
286
- /** Print an item type as the text rows of one item type share (#825) — East's own printer over its type value. */
287
- const printType = printFor(EastTypeType);
288
- /**
289
- * Check what a series' `edit` declares for a move (#825), against its item
290
- * type — `undefined` when it declares no move (only `create`).
291
- *
292
- * @param edit - The declaration
293
- * @param itemType - The type of the items in `edit.items`
294
- * @param arm - The series' kind
295
- * @param where - The series, for the message
296
- * @returns The move's fields
297
- * @throws {Error} Naming the field and what is wrong with it
298
- */
299
- function moveFieldsOf(edit, itemType, arm, where) {
300
- const shape = editShapeOf(arm);
301
- if (shape === "span" && edit.at !== undefined) {
302
- throw new Error(`${where}: \`edit.at\` is a tile's or a mark's instant — a ${arm} element has two ends: name them with \`start\` and \`end\``);
303
- }
304
- if (shape === "point" && (edit.start !== undefined || edit.end !== undefined)) {
305
- throw new Error(`${where}: a ${arm} element has one instant — name it with \`edit.at\`, not \`start\` / \`end\``);
306
- }
307
- const start = shape === "span" ? edit.start : edit.at;
308
- const end = shape === "span" ? edit.end : undefined;
309
- if (shape === "span" && (start === undefined) !== (end === undefined)) {
310
- throw new Error(`${where}: a move writes both ends of a ${arm} element — give \`edit.start\` and \`edit.end\` together`);
311
- }
312
- if (start === undefined) {
313
- if (edit.create === undefined) {
314
- throw new Error(`${where}: \`edit\` declares neither \`create\` (what a dropped card becomes) nor the item fields a move ` +
315
- `writes (\`key\` and ${shape === "span" ? "`start` / `end`" : "`at`"}) — declare one or both`);
316
- }
317
- return undefined;
318
- }
319
- const item = itemType;
320
- if (item.type !== "Struct") {
321
- throw new Error(`${where}: a move writes fields of the item — the items in "${edit.items}" must be structs`);
322
- }
323
- if (edit.key === undefined) {
324
- throw new Error(`${where}: a move finds its element's item by key — name the item's String key field with \`edit.key\``);
325
- }
326
- const keyType = item.fields[edit.key];
327
- if (keyType === undefined || !isTypeEqual(keyType, StringType)) {
328
- throw new Error(`${where}: \`edit.key\` names "${edit.key}", which is not a String field of the item`);
329
- }
330
- const instant = (name, what) => {
331
- const type = item.fields[name];
332
- if (type === undefined || !INSTANT_FIELD_TYPES.some((t) => isTypeEqual(t, type))) {
333
- throw new Error(`${where}: \`edit.${what}\` names "${name}", which is not an instant field of the item — a DateTime, a Float or ` +
334
- "an Integer, a String, or a Plan.Types.Instant");
335
- }
336
- if (name === edit.key) {
337
- throw new Error(`${where}: \`edit.${what}\` names the key field "${name}" — a move would change the item's identity; name its instant field`);
338
- }
339
- return { name, type };
340
- };
341
- if (end !== undefined && end === start) {
342
- throw new Error(`${where}: \`edit.start\` and \`edit.end\` both name "${start}" — a move writes two different fields`);
343
- }
344
- return {
345
- item,
346
- key: edit.key,
347
- start: instant(start, shape === "span" ? "start" : "at"),
348
- end: end !== undefined ? instant(end, "end") : undefined,
349
- edits: { items: printType(toEastTypeValue(itemType)), resize: shape === "span" },
350
- };
351
- }
352
- /** Each instant field type's converter, built once (#825). */
353
- const instantConverters = new ByType();
354
- /**
355
- * The converter from an axis instant into an item field's type (#825): the
356
- * instant on the arm the field holds — a time instant's DateTime, a number
357
- * instant's Float (an Integer field takes it rounded, half away from zero), an
358
- * ordinal instant's String, or the instant itself — else `none`.
359
- *
360
- * @param fieldType - The field's type (one of {@link INSTANT_FIELD_TYPES})
361
- * @returns `(instant) → Option<field>`
362
- */
363
- function instantInto(fieldType) {
364
- return instantConverters.get(fieldType, () => {
365
- const out = OptionType(fieldType);
366
- const kind = fieldType.type;
367
- const whole = isTypeEqual(fieldType, PlanInstantType);
368
- return East.function([PlanInstantType], out, ($, t) => {
369
- const result = $.let(none, out);
370
- if (whole) {
371
- $.assign(result, some(t));
372
- return result;
373
- }
374
- $.match(t, {
375
- time: ($2, d) => {
376
- if (kind === "DateTime")
377
- $2.assign(result, some(d));
378
- },
379
- number: ($2, n) => {
380
- if (kind === "Float") {
381
- $2.assign(result, some(n));
382
- }
383
- else if (kind === "Integer") {
384
- const rounded = $2.let(n.greaterEqual(0).ifElse(() => n.add(0.5).subtract(n.add(0.5).remainder(1)), () => n.subtract(0.5).subtract(n.subtract(0.5).remainder(1))), FloatType);
385
- $2.assign(result, some(rounded.toInteger()));
386
- }
387
- },
388
- ordinal: ($2, s) => {
389
- if (kind === "String")
390
- $2.assign(result, some(s));
391
- },
392
- });
393
- return result;
394
- });
395
- });
396
- }
397
- /**
398
- * The build spec of a data series (span / buckets / chart / heat / table /
399
- * cards / events / group).
400
- *
401
- * @remarks
402
- * Per key type it builds ONE entry-row function (the entry's gutter, kind and
403
- * row facts through the one envelope) and the membership, collapse and
404
- * children functions, each reified once and CALLED in the block's loop. The
405
- * block walks the collection in order; each matched entry's row is followed by
406
- * its children's rows — a bare `children` accessor walks the entry's subtree
407
- * with an explicit pre-order stack (its depth is data), a step-down calls its
408
- * child series' blocks on the child collection.
409
- */
410
- function dataSpec(rowType, cfg, recipe) {
411
- const where = `Plan.series.${recipe.arm} "${cfg.key}"`;
412
- const children = cfg.children;
413
- const steps = children === undefined || typeof children === "function"
414
- ? [] : (Array.isArray(children) ? children : [children]);
415
- for (const step of steps) {
416
- if (!isStepDown(step)) {
417
- throw new Error(`${where}: \`children\` is an accessor for more of this series, or \`Plan.children(of, [series…])\` step-downs`);
418
- }
419
- }
420
- const nested = steps.flatMap((s) => s.series.map((x) => nestedSpec(x, `${where} › children`)));
421
- // A recursive entry reaches the accessors as its NODE (`PlanEntryExpr`),
422
- // so they read its fields directly at every depth.
423
- const recursive = rowType.type === "Recursive";
424
- const nodeOf = (value) => recursive
425
- ? value.unwrap()
426
- : value;
427
- /** An accessor over entries, applied to an entry value (its node, when recursive). */
428
- const onEntry = (accessor) => (v, k) => accessor(nodeOf(v), k);
429
- // What a gesture writes (#880, #825) — a verdict into `review.verdict`, a
430
- // dropped card into `edit.items`, a moved element into its item's fields
431
- // — each a FIELD of the entry (its node, when recursive) or of its items,
432
- // checked here so a misnamed field fails the build.
433
- const review = cfg.review;
434
- const edit = recipe.edit;
435
- const nodeType = (recursive ? rowType.node : rowType);
436
- if ((review !== undefined || edit !== undefined) && nodeType.type !== "Struct") {
437
- throw new Error(`${where}: \`review\` and \`edit\` write a field of the entry — its entries must be structs (a recursive entry's node included)`);
438
- }
439
- const entryFields = nodeType.fields ?? {};
440
- if (review !== undefined) {
441
- if (cfg.approval !== undefined) {
442
- throw new Error(`${where}: give \`review.verdict\` (the field a verdict writes, which the row shows) or \`approval\` (a verdict the canvas only shows) — not both`);
443
- }
444
- const t = entryFields[review.verdict];
445
- if (t === undefined || !isTypeEqual(t, ApprovalStateType)) {
446
- throw new Error(`${where}: \`review.verdict\` names "${review.verdict}", which is not an ApprovalStateType field of the entry`);
447
- }
448
- }
449
- let itemType;
450
- let move;
451
- if (edit !== undefined) {
452
- const t = entryFields[edit.items];
453
- if (t === undefined || t.type !== "Array") {
454
- throw new Error(`${where}: \`edit.items\` names "${edit.items}", which is not an Array field of the entry — a gesture writes a list of items`);
455
- }
456
- itemType = t.value;
457
- move = moveFieldsOf(edit, itemType, recipe.arm, where);
458
- }
459
- const edits = review !== undefined || edit !== undefined
460
- ? {
461
- verdict: review !== undefined,
462
- drop: edit?.create !== undefined,
463
- move: move !== undefined ? some(move.edits) : none,
464
- }
465
- : undefined;
466
- const rows = new ByType();
467
- const matches = new ByType();
468
- const collapses = new ByType();
469
- const kids = new ByType();
470
- const walks = new ByType();
471
- const emitters = new ByType();
472
- const blockLists = new ByType();
473
- const rowFor = (kt) => rows.get(kt, () => building(where, kt, () => East.function([rowType, kt, PlanRowIdType, IdOptType, BooleanType, BooleanType], PlanRowType, ($, value, key, id, parent, hasChildren, collapsed) => {
474
- // The node every accessor reads, unwrapped once.
475
- const entry = recursive ? $.let(nodeOf(value)) : value;
476
- return planRow({
477
- id, parent,
478
- gutter: planGutter({
479
- label: cfg.label(entry, key),
480
- ...(cfg.id !== undefined ? { id: cfg.id } : {}),
481
- ...(cfg.stacked !== undefined ? { stacked: cfg.stacked } : {}),
482
- ...(cfg.sub !== undefined ? { sub: cfg.sub(entry, key) } : {}),
483
- ...(cfg.value !== undefined ? { value: cfg.value(entry, key) } : {}),
484
- ...(recipe.swatches !== undefined ? { swatches: recipe.swatches } : {}),
485
- }),
486
- kind: recipe.kind(entry, key, hasChildren),
487
- collapsed,
488
- ...(recipe.pinned !== undefined ? { pinned: recipe.pinned(entry, key) } : {}),
489
- ...(cfg.status !== undefined ? { status: cfg.status(entry, key) } : {}),
490
- // A verdict the canvas takes shows from its field (#880) — so
491
- // a drafted verdict draws where it was made.
492
- ...(review !== undefined
493
- ? { approval: some(entry[review.verdict]) }
494
- : cfg.approval !== undefined ? { approval: cfg.approval(entry, key) } : {}),
495
- ...(cfg.expand !== undefined ? { expand: cfg.expand(entry, key) } : {}),
496
- ...(edits !== undefined ? { edits } : {}),
497
- });
498
- })));
499
- const matchFor = (kt) => matches.get(kt, () => {
500
- const match = cfg.match;
501
- if (match === undefined)
502
- return undefined;
503
- return building(where, kt, () => East.function([rowType, kt], BooleanType, (_$, value, key) => match(nodeOf(value), key)));
504
- });
505
- const collapsedFor = (kt) => collapses.get(kt, () => {
506
- const collapsed = cfg.collapsed;
507
- if (collapsed === undefined)
508
- return undefined;
509
- return building(where, kt, () => East.function([rowType, kt], BooleanType, (_$, value, key) => typeof collapsed === "boolean"
510
- ? East.value(collapsed, BooleanType)
511
- : East.value(collapsed(nodeOf(value), key), BooleanType)));
512
- });
513
- /** A bare `children` accessor, built for entries keyed by `kt` — the child collection's type is its output. */
514
- const childOf = (kt) => building(where, kt, () => reifyAccessor([rowType, kt], onEntry(children)));
515
- /** The subtree walk below one entry — every level's entries in pre-order, over the child collection type. */
516
- const walkFor = (cc) => walks.get(cc, () => {
517
- const at = `${where} › children`;
518
- const { entry, key: kc } = shapeOf(cc, at);
519
- assertEntry(entry, rowType, `${at} (a bare accessor returns more of this series' entries — step down to another type with Plan.children)`);
520
- const next = childOf(kc);
521
- const nextType = Expr.type(next).output;
522
- if (!isTypeEqual(nextType, cc)) {
523
- throw new Error(`${at}: a recursive series' children must be the same collection type at every level`);
524
- }
525
- const row = rowFor(kc);
526
- const match = matchFor(kc);
527
- const collapsed = collapsedFor(kc);
528
- const seg = segmentOf(kc);
529
- const Frame = StructType({ value: rowType, key: kc, path: PathType, parent: PlanRowIdType });
530
- const Frames = ArrayType(Frame);
531
- // A level's matched entries as frames, REVERSED — so the stack
532
- // pops the first of them first.
533
- const framesOf = East.function([cc, PathType, PlanRowIdType], Frames, ($, coll, path, parentId) => {
534
- const frames = $.let([], Frames);
535
- const member = match === undefined ? undefined : $.const(match);
536
- $.for(coll, ($2, value, key) => {
537
- const add = ($3) => {
538
- const segs = $3.let(East.value([seg(key)], PathType), PathType);
539
- $3(frames.pushLast(East.value({ value, key, path: path.concat(segs), parent: parentId }, Frame)));
540
- };
541
- if (member === undefined)
542
- add($2);
543
- else
544
- $2.if(member(value, key), add);
545
- });
546
- $(frames.reverseInPlace());
547
- return frames;
548
- });
549
- return East.function([cc, PathType, PlanRowIdType], PlanRowsCollectionType, ($, coll, path0, parent0) => {
550
- // Every function the loop calls, bound ONCE — a captured function
551
- // referenced in the loop would be re-inlined per use.
552
- const frames = $.const(framesOf);
553
- const childrenOf = $.const(next);
554
- const entryRow = $.const(row);
555
- const collapse = collapsed === undefined ? undefined : $.const(collapsed);
556
- const out = $.let([], PlanRowsCollectionType);
557
- const stack = $.let(frames(coll, path0, parent0), Frames);
558
- $.while(stack.size().greater(0n), ($2) => {
559
- const f = $2.let(stack.popLast(), Frame);
560
- const id = $2.let(East.value(variant("entry", { series: cfg.key, path: f.path }), PlanRowIdType), PlanRowIdType);
561
- const below = $2.let(frames(childrenOf(f.value, f.key), f.path, id), Frames);
562
- const parent = $2.let(East.value(some(f.parent), IdOptType), IdOptType);
563
- const fold = $2.let(collapse === undefined
564
- ? East.value(false, BooleanType)
565
- : collapse(f.value, f.key), BooleanType);
566
- $2(out.pushLast(entryRow(f.value, f.key, id, parent, below.size().greater(0n), fold)));
567
- $2(stack.append(below));
568
- });
569
- return out;
570
- });
571
- });
572
- const childrenFor = (kt) => kids.get(kt, () => {
573
- if (children === undefined)
574
- return undefined;
575
- if (typeof children === "function") {
576
- const of = childOf(kt);
577
- const cc = Expr.type(of).output;
578
- const walk = walkFor(cc);
579
- return East.function([rowType, kt, PlanRowIdType, PathType], PlanRowsCollectionType, (_$, value, key, id, path) => walk(of(value, key), path, id));
580
- }
581
- const parts = steps.map((step, i) => {
582
- const at = `${where} › children[${i}]`;
583
- const of = building(at, kt, () => reifyAccessor([rowType, kt], onEntry(step.of)));
584
- const cc = Expr.type(of).output;
585
- const blocks = step.series.map((s) => nestedSpec(s, at).emitter(cc, at));
586
- return { of, cc, blocks };
587
- });
588
- return East.function([rowType, kt, PlanRowIdType, PathType], PlanRowsCollectionType, ($, value, key, id, path) => {
589
- const out = $.let([], PlanRowsCollectionType);
590
- const under = $.let(East.value(some(id), IdOptType), IdOptType);
591
- for (const part of parts) {
592
- const coll = $.let(part.of(value, key), part.cc);
593
- for (const block of part.blocks)
594
- $(out.append(block(coll, path, under)));
595
- }
596
- return out;
597
- });
598
- });
599
- // ── Writing a gesture back (#880) ─────────────────────────────────────
600
- // The entry a writer is handed is DETACHED (the series value's `write`
601
- // copies it), so a nested entry is written in place in its collection and
602
- // a dropped card's item joins its list in place: only an entry whose OWN
603
- // field changes — a verdict — is rebuilt.
604
- const owns = new ByType();
605
- const writers = new ByType();
606
- const entryAccess = (value) => nodeOf(value);
607
- /** The entry with its verdict field set — rebuilt, every other field as it was. */
608
- const withVerdict = review === undefined ? undefined : East.function([rowType, ApprovalStateType], rowType, ($, value, verdict) => {
609
- const node = recursive ? $.let(nodeOf(value)) : value;
610
- const read = node;
611
- const rebuilt = East.value(Object.fromEntries(Object.keys(entryFields).map((f) => [f, f === review.verdict ? verdict : read[f]])), nodeType);
612
- return recursive ? East.wrapRecursive(rebuilt, rowType) : rebuilt;
613
- });
614
- /** The item a dropped card becomes, for entries keyed by `kt`. */
615
- const createFor = (kt, create) => building(where, kt, () => East.function([PlanDropType, rowType, kt], itemType, (_$, drop, value, key) => create(drop, nodeOf(value), key)));
616
- /**
617
- * An item at a move's instants (#825) — its declared instant fields set
618
- * from the axis's instants, each on its own arm, every other field as it
619
- * was; `none` when an instant rides an arm the field cannot hold (a time
620
- * instant into a Float field).
621
- */
622
- const placed = move === undefined ? undefined : (() => {
623
- const m = move;
624
- const startAs = instantInto(m.start.type);
625
- const endAs = m.end !== undefined ? instantInto(m.end.type) : undefined;
626
- return East.function([m.item, PlanInstantType, PlanInstantType], OptionType(m.item), ($, item, start, end) => {
627
- const result = $.let(none, OptionType(m.item));
628
- const asStart = $.const(startAs);
629
- const s = $.let(asStart(start), OptionType(m.start.type));
630
- const read = item;
631
- const rebuild = (fields) => East.value(Object.fromEntries(Object.keys(m.item.fields).map((f) => [f, fields[f] ?? read[f]])), m.item);
632
- $.match(s, {
633
- some: ($2, sv) => {
634
- if (endAs === undefined || m.end === undefined) {
635
- $2.assign(result, some(rebuild({ [m.start.name]: sv })));
636
- return;
637
- }
638
- const endName = m.end.name;
639
- const asEnd = $2.const(endAs);
640
- const e = $2.let(asEnd(end), OptionType(m.end.type));
641
- $2.match(e, {
642
- some: ($3, ev) => {
643
- $3.assign(result, some(rebuild({ [m.start.name]: sv, [endName]: ev })));
644
- },
645
- });
646
- },
647
- });
648
- return result;
649
- });
650
- })();
651
- /**
652
- * Whether a list holds an item keyed `k` (#825) — the key a move finds its
653
- * item by, so a row's list keeps its keys unique: a card whose item repeats
654
- * one, or a move onto a row already holding the moved item's key, is
655
- * refused rather than leaving two items one key names.
656
- */
657
- const holds = move === undefined ? undefined : (list, k) => list.some((_$, item) => East.equal(item[move.key], k));
658
- /**
659
- * This series' own edit on one of its entries — the row at `path` is its
660
- * own: a verdict into its field, a dropped card's item into its list, and
661
- * a moved element's item re-timed where it is, taken out of the list, or
662
- * put into it (#825).
663
- */
664
- const ownFor = (kt) => owns.get(kt, () => {
665
- if (review === undefined && edit === undefined)
666
- return undefined;
667
- const create = edit?.create !== undefined ? createFor(kt, edit.create) : undefined;
668
- return East.function([rowType, kt, PathType, PlanGestureType, PlanCarriedType], OptionType(rowType), ($, value, key, path, gesture, carried) => {
669
- const setVerdict = withVerdict === undefined ? undefined : $.const(withVerdict);
670
- const make = create === undefined ? undefined : $.const(create);
671
- const place = placed === undefined ? undefined : $.const(placed);
672
- const result = $.let(none, OptionType(rowType));
673
- $.match(gesture, {
674
- verdict: ($2, verdict) => {
675
- if (setVerdict !== undefined)
676
- $2.assign(result, some(setVerdict(value, verdict)));
677
- },
678
- drop: ($2, drop) => {
679
- if (make === undefined || edit === undefined)
680
- return;
681
- const list = $2.let(entryAccess(value)[edit.items]);
682
- const item = $2.let(make(drop, value, key), itemType);
683
- const add = ($3) => {
684
- $3(list.pushLast(item));
685
- $3.assign(result, some(value));
686
- };
687
- // With the item's key declared, a card whose item
688
- // repeats a key in the list is refused (#825).
689
- if (holds === undefined || move === undefined)
690
- add($2);
691
- else
692
- $2.if(holds(list, item[move.key]).not(), add);
693
- },
694
- move: ($2, mv) => {
695
- if (place === undefined || move === undefined || edit === undefined)
696
- return;
697
- const keyField = move.key;
698
- const itemOf = move.item;
699
- const here = $2.let(East.value(variant("entry", { series: cfg.key, path }), PlanRowIdType), PlanRowIdType);
700
- const list = $2.let(entryAccess(value)[edit.items]);
701
- // The element's item, by its key.
702
- const at = $2.let(list.firstMap(($3, item, i) => East.equal(item[keyField], mv.key).ifElse(() => East.value(some(i), OptionType(IntegerType)), () => East.value(none, OptionType(IntegerType)))), OptionType(IntegerType));
703
- $2.if(East.equal(here, mv.from).and(() => East.equal(here, mv.to)), ($3) => {
704
- // Along its row, or resized: its instants set where it is.
705
- $3.match(at, {
706
- some: ($4, i) => {
707
- const moved = $4.let(place(list.get(i), mv.start, mv.end), OptionType(itemOf));
708
- $4.match(moved, {
709
- some: ($5, item) => {
710
- $5(list.update(i, item));
711
- $5.assign(result, some(value));
712
- },
713
- });
714
- },
715
- });
716
- }).else(($3) => {
717
- // Its source: taken out of the list, and carried.
718
- $3.if(East.equal(here, mv.from), ($4) => {
719
- $4.match(at, {
720
- some: ($5, i) => {
721
- $5(carried.update(East.value(some(East.Blob.encodeBeast(list.get(i), "v2")), OptionType(BlobType))));
722
- const before = $5.let(list.slice(0n, i));
723
- const after = $5.let(list.slice(i.add(1n), list.size()));
724
- $5(list.clear());
725
- $5(list.append(before));
726
- $5(list.append(after));
727
- $5.assign(result, some(value));
728
- },
729
- });
730
- });
731
- // Its target: the carried item put in, at its new
732
- // instants — unless the list already holds its key,
733
- // when it is put nowhere and the move lands nowhere.
734
- $3.if(East.equal(here, mv.to), ($4) => {
735
- const held = $4.let(carried.get(), OptionType(BlobType));
736
- $4.match(held, {
737
- some: ($5, bytes) => {
738
- $5.if(holds(list, mv.key).not(), ($6) => {
739
- const item = $6.let(bytes.decodeBeast(itemOf, "v2"), itemOf);
740
- const moved = $6.let(place(item, mv.start, mv.end), OptionType(itemOf));
741
- $6.match(moved, {
742
- some: ($7, placedItem) => {
743
- $7(list.pushLast(placedItem));
744
- $7(carried.update(East.value(none, OptionType(BlobType))));
745
- $7.assign(result, some(value));
746
- },
747
- });
748
- });
749
- },
750
- });
751
- });
752
- });
753
- },
754
- });
755
- return result;
756
- });
757
- });
758
- /** The walk's writer — a bare `children` accessor: the rows below an entry are this series' own. */
759
- const walkWriterFor = (kt) => {
760
- const at = `${where} › children`;
761
- const of = childOf(kt);
762
- const cc = Expr.type(of).output;
763
- const { key: kc } = shapeOf(cc, at);
764
- const own = ownFor(kc);
765
- if (own === undefined)
766
- return undefined;
767
- const ref = childRefOf(rowType, kt, children);
768
- if (ref === undefined) {
769
- throw new Error(`${at}: this series takes gestures, and one on a child row is written back into its entry through ` +
770
- "`children` — which must read a field of the entry (`r => r.children`), not compute a collection");
771
- }
772
- const ops = collectionOps(cc);
773
- const collOf = (entry) => (ref.kind === "field" ? entryAccess(entry)[ref.field] : nodeOf(entry));
774
- return East.function([rowType, kt, PathType, IntegerType, StringType, PlanGestureType, PlanCarriedType], OptionType(rowType), ($, value, _key, path, depth, series, gesture, carried) => {
775
- const result = $.let(none, OptionType(rowType));
776
- // The walk's rows are this series' own, at every depth.
777
- $.if(series.equal(cfg.key), ($2) => {
778
- const write = $2.const(own);
779
- const keyOf = $2.const(segmentKeyOf(kc));
780
- const cur = $2.let(value, rowType);
781
- const d = $2.let(depth, IntegerType);
782
- const last = $2.let(path.size().subtract(1n), IntegerType);
783
- // Down to the target's parent, then the target itself.
784
- $2.while(d.less(last), ($3) => {
785
- const coll = $3.let(collOf(cur), cc);
786
- $3.assign(cur, ops.get(coll, keyOf(path.get(d))));
787
- $3.assign(d, d.add(1n));
788
- });
789
- const coll = $2.let(collOf(cur), cc);
790
- const k = $2.let(keyOf(path.get(last)), kc);
791
- const written = $2.let(write(ops.get(coll, k), k, path, gesture, carried), OptionType(rowType));
792
- $2.match(written, {
793
- some: ($3, entry) => {
794
- $3(ops.put(coll, k, entry));
795
- $3.assign(result, some(value));
796
- },
797
- });
798
- });
799
- return result;
800
- });
801
- };
802
- /** The step-downs' writer: a row below an entry is one of a step-down's series', in that step's collection. */
803
- const stepsWriterFor = (kt) => {
804
- const parts = steps.flatMap((step, i) => {
805
- const at = `${where} › children[${i}]`;
806
- const accessor = step.of;
807
- const of = building(at, kt, () => reifyAccessor([rowType, kt], onEntry(accessor)));
808
- const cc = Expr.type(of).output;
809
- const writes = step.series
810
- .map((s) => nestedSpec(s, at).writer(cc, at))
811
- .filter((w) => w !== undefined);
812
- if (writes.length === 0)
813
- return [];
814
- const ref = childRefOf(rowType, kt, accessor);
815
- if (ref === undefined) {
816
- throw new Error(`${at}: a series under this step-down takes gestures, and one on its rows is written back into ` +
817
- "the entry through `Plan.children(of, …)` — `of` must read a field of the entry (`r => r.lines`) " +
818
- "or be the entry itself (`g => g`), not compute a collection");
819
- }
820
- const { entry: childType, key: kc } = shapeOf(cc, at);
821
- return [{ ref, cc, kc, childType, writes }];
822
- });
823
- if (parts.length === 0)
824
- return undefined;
825
- return East.function([rowType, kt, PathType, IntegerType, StringType, PlanGestureType, PlanCarriedType], OptionType(rowType), ($, value, _key, path, depth, series, gesture, carried) => {
826
- const result = $.let(none, OptionType(rowType));
827
- for (const part of parts) {
828
- const ops = collectionOps(part.cc);
829
- const keyOf = $.const(segmentKeyOf(part.kc));
830
- const writes = part.writes.map((w) => $.const(w));
831
- $.if(result.hasTag("none"), ($2) => {
832
- const coll = $2.let(part.ref.kind === "field" ? entryAccess(value)[part.ref.field] : nodeOf(value), part.cc);
833
- const k = $2.let(keyOf(path.get(depth)), part.kc);
834
- $2.if(ops.has(coll, k), ($3) => {
835
- const child = $3.let(ops.get(coll, k), part.childType);
836
- for (const write of writes) {
837
- $3.if(result.hasTag("none"), ($4) => {
838
- const written = $4.let(write(child, k, path, depth.add(1n), series, gesture, carried), OptionType(part.childType));
839
- $4.match(written, {
840
- some: ($5, entry) => {
841
- $5(ops.put(coll, k, entry));
842
- $5.assign(result, some(value));
843
- },
844
- });
845
- });
846
- }
847
- });
848
- });
849
- }
850
- return result;
851
- });
852
- };
853
- /** This series' writer for entries keyed by `kt`: its own rows' edits, and the rows below them. */
854
- const writerFor = (kt) => writers.get(kt, () => {
855
- const own = ownFor(kt);
856
- const below = children === undefined ? undefined
857
- : typeof children === "function" ? walkWriterFor(kt) : stepsWriterFor(kt);
858
- if (own === undefined && below === undefined)
859
- return undefined;
860
- return East.function([rowType, kt, PathType, IntegerType, StringType, PlanGestureType, PlanCarriedType], OptionType(rowType), ($, value, key, path, depth, series, gesture, carried) => {
861
- const result = $.let(none, OptionType(rowType));
862
- $.if(depth.equal(path.size()), ($2) => {
863
- if (own === undefined)
864
- return;
865
- const write = $2.const(own);
866
- $2.if(series.equal(cfg.key), ($3) => { $3.assign(result, write(value, key, path, gesture, carried)); });
867
- }).else(($2) => {
868
- if (below === undefined)
869
- return;
870
- const write = $2.const(below);
871
- $2.assign(result, write(value, key, path, depth, series, gesture, carried));
872
- });
873
- return result;
874
- });
875
- });
876
- const spec = {
877
- key: cfg.key,
878
- title: cfg.title,
879
- arm: recipe.arm,
880
- nested,
881
- nests: children !== undefined,
882
- emitter(collection, at) {
883
- return emitters.get(collection, () => {
884
- const { entry, key: kt } = shapeOf(collection, at);
885
- assertEntry(entry, rowType, where);
886
- const row = rowFor(kt);
887
- const match = matchFor(kt);
888
- const collapsed = collapsedFor(kt);
889
- const below = childrenFor(kt);
890
- const seg = segmentOf(kt);
891
- return East.function([collection, PathType, IdOptType], PlanRowsCollectionType, ($, coll, prefix, parent) => {
892
- // Every function the loop calls, bound ONCE (see the walk).
893
- const entryRow = $.const(row);
894
- const member = match === undefined ? undefined : $.const(match);
895
- const collapse = collapsed === undefined ? undefined : $.const(collapsed);
896
- const childRows = below === undefined ? undefined : $.const(below);
897
- const out = $.let([], PlanRowsCollectionType);
898
- $.for(coll, ($2, value, key) => {
899
- const emit = ($3) => {
900
- const segs = $3.let(East.value([seg(key)], PathType), PathType);
901
- const path = $3.let(prefix.concat(segs), PathType);
902
- const id = $3.let(East.value(variant("entry", { series: cfg.key, path }), PlanRowIdType), PlanRowIdType);
903
- const fold = $3.let(collapse === undefined
904
- ? East.value(false, BooleanType)
905
- : collapse(value, key), BooleanType);
906
- if (childRows === undefined) {
907
- $3(out.pushLast(entryRow(value, key, id, parent, false, fold)));
908
- return;
909
- }
910
- // The children are built first: a row rolls up
911
- // (span bands) only when it has child rows.
912
- const sub = $3.let(childRows(value, key, id, path), PlanRowsCollectionType);
913
- $3(out.pushLast(entryRow(value, key, id, parent, sub.size().greater(0n), fold)));
914
- $3(out.append(sub));
915
- };
916
- if (member === undefined)
917
- emit($2);
918
- else
919
- $2.if(member(value, key), emit);
920
- });
921
- return out;
922
- });
923
- });
924
- },
925
- // One block of the entries' rows — what a paged canvas pages (#823).
926
- blocks(collection, at) {
927
- return blockLists.get(collection, () => oneBlock(collection, spec.emitter(collection, at), false));
928
- },
929
- entryParts(entry, kt, at) {
930
- assertEntry(entry, rowType, at);
931
- return { match: matchFor(kt), row: rowFor(kt) };
932
- },
933
- childrenFor,
934
- collapsedFor,
935
- writer(collection, at) {
936
- const { entry, key: kt } = shapeOf(collection, at);
937
- assertEntry(entry, rowType, where);
938
- return writerFor(kt);
939
- },
940
- ownFor,
941
- };
942
- return spec;
943
- }
944
- /** The build spec of a `views` series. */
945
- function viewsSpec(rowType, cfg, members) {
946
- const where = `Plan.series.views "${cfg.key}"`;
947
- if (members.length === 0)
948
- throw new Error(`${where}: a views series lists at least one member series`);
949
- const memberSpecs = members.map((m, i) => {
950
- const spec = nestedSpec(m, `${where}[${i}]`);
951
- if (spec.entryParts === undefined || spec.arm === "group") {
952
- throw new Error(`${where}: member ${nameOf(spec)} is not a row series — a view is one row per entry (span, buckets, chart, heat, table, cards or events)`);
953
- }
954
- if (spec.nests) {
955
- throw new Error(`${where}: member ${nameOf(spec)} declares \`children\` — an entry's children belong to the views (they nest under its first view row); move \`children\` there`);
956
- }
957
- return spec;
958
- });
959
- // The views' own membership, collapse and children are a data series'
960
- // envelope without a row of its own — built by the same machinery, so a
961
- // views' children nest and recurse exactly as a data series' do.
962
- const host = dataSpec(rowType, {
963
- key: cfg.key, title: cfg.title, label: () => "",
964
- ...(cfg.keyType !== undefined ? { keyType: cfg.keyType } : {}),
965
- ...(cfg.match !== undefined ? { match: cfg.match } : {}),
966
- ...(cfg.children !== undefined ? { children: cfg.children } : {}),
967
- ...(cfg.collapsed !== undefined ? { collapsed: cfg.collapsed } : {}),
968
- }, { arm: "views", kind: () => groupKind(East.value(variant("none", null), PlanGroupSummaryType)) });
969
- const emitters = new ByType();
970
- const blockLists = new ByType();
971
- const writerLists = new ByType();
972
- const spec = {
973
- key: cfg.key,
974
- title: cfg.title,
975
- arm: "views",
976
- nested: [...memberSpecs, ...host.nested],
977
- nests: cfg.children !== undefined,
978
- emitter(collection, at) {
979
- return emitters.get(collection, () => {
980
- const { entry, key: kt } = shapeOf(collection, at);
981
- assertEntry(entry, rowType, where);
982
- const parts = memberSpecs.map((m) => m.entryParts(entry, kt, `${where} › ${nameOf(m)}`));
983
- const hostParts = host.entryParts(entry, kt, where);
984
- const hostKids = host.childrenFor(kt);
985
- const hostCollapse = host.collapsedFor(kt);
986
- const seg = segmentOf(kt);
987
- return East.function([collection, PathType, IdOptType], PlanRowsCollectionType, ($, coll, prefix, parent) => {
988
- // Every function the loop calls, bound ONCE (see the data walk).
989
- const rowsOf = parts.map((p) => $.const(p.row));
990
- const showsOf = parts.map((p) => (p.match === undefined ? undefined : $.const(p.match)));
991
- const member = hostParts.match === undefined ? undefined : $.const(hostParts.match);
992
- const childRows = hostKids === undefined ? undefined : $.const(hostKids);
993
- const collapse = hostCollapse === undefined ? undefined : $.const(hostCollapse);
994
- const out = $.let([], PlanRowsCollectionType);
995
- $.for(coll, ($2, value, key) => {
996
- const emit = ($3) => {
997
- const segs = $3.let(East.value([seg(key)], PathType), PathType);
998
- const path = $3.let(prefix.concat(segs), PathType);
999
- const ids = memberSpecs.map((m) => $3.let(East.value(variant("entry", { series: m.key, path }), PlanRowIdType), PlanRowIdType));
1000
- const present = showsOf.map((shows) => (shows === undefined
1001
- ? undefined
1002
- : $3.let(shows(value, key), BooleanType)));
1003
- // The first member whose row shows — the entry's
1004
- // children nest under it.
1005
- const first = $3.let(-1n, IntegerType);
1006
- for (let i = parts.length - 1; i >= 0; i--) {
1007
- const shows = present[i];
1008
- if (shows === undefined)
1009
- $3.assign(first, BigInt(i));
1010
- else
1011
- $3.if(shows, ($4) => { $4.assign(first, BigInt(i)); });
1012
- }
1013
- let sub;
1014
- if (childRows !== undefined) {
1015
- const firstId = $3.let(ids[0], PlanRowIdType);
1016
- for (let i = 1; i < ids.length; i++) {
1017
- $3.if(first.equal(BigInt(i)), ($4) => { $4.assign(firstId, ids[i]); });
1018
- }
1019
- sub = $3.let(first.greaterEqual(0n).ifElse(() => childRows(value, key, firstId, path), () => East.value([], PlanRowsCollectionType)), PlanRowsCollectionType);
1020
- }
1021
- const fold = $3.let(collapse === undefined
1022
- ? East.value(false, BooleanType)
1023
- : collapse(value, key), BooleanType);
1024
- const noFold = $3.let(East.value(false, BooleanType), BooleanType);
1025
- parts.forEach((_p, i) => {
1026
- const isFirst = $3.let(first.equal(BigInt(i)), BooleanType);
1027
- const kids = sub;
1028
- const hasChildren = $3.let(kids === undefined
1029
- ? East.value(false, BooleanType)
1030
- : isFirst.and(() => kids.size().greater(0n)), BooleanType);
1031
- const viewRow = rowsOf[i];
1032
- const push = ($4) => {
1033
- $4(out.pushLast(viewRow(value, key, ids[i], parent, hasChildren, isFirst.ifElse(() => fold, () => noFold))));
1034
- };
1035
- const shows = present[i];
1036
- if (shows === undefined)
1037
- push($3);
1038
- else
1039
- $3.if(shows, push);
1040
- });
1041
- if (sub !== undefined)
1042
- $3(out.append(sub));
1043
- };
1044
- if (member === undefined)
1045
- emit($2);
1046
- else
1047
- $2.if(member(value, key), emit);
1048
- });
1049
- return out;
1050
- });
1051
- });
1052
- },
1053
- // One block of the entries' view rows — what a paged canvas pages (#823).
1054
- blocks(collection, at) {
1055
- return blockLists.get(collection, () => oneBlock(collection, spec.emitter(collection, at), false));
1056
- },
1057
- // An entry's view rows are its members' own (each at the entry's path,
1058
- // under its member's key), and the rows below them the views' (#880).
1059
- writer(collection, at) {
1060
- return writerLists.get(collection, () => {
1061
- const { entry, key: kt } = shapeOf(collection, at);
1062
- assertEntry(entry, rowType, where);
1063
- const owns = memberSpecs.flatMap((m) => {
1064
- const own = m.ownFor?.(kt);
1065
- return own === undefined ? [] : [{ key: m.key, own }];
1066
- });
1067
- const below = host.writer(collection, at);
1068
- if (owns.length === 0 && below === undefined)
1069
- return undefined;
1070
- return East.function([rowType, kt, PathType, IntegerType, StringType, PlanGestureType, PlanCarriedType], OptionType(rowType), ($, value, key, path, depth, series, gesture, carried) => {
1071
- const result = $.let(none, OptionType(rowType));
1072
- $.if(depth.equal(path.size()), ($2) => {
1073
- for (const o of owns) {
1074
- const write = $2.const(o.own);
1075
- $2.if(series.equal(o.key), ($3) => { $3.assign(result, write(value, key, path, gesture, carried)); });
1076
- }
1077
- }).else(($2) => {
1078
- if (below === undefined)
1079
- return;
1080
- const write = $2.const(below);
1081
- $2.assign(result, write(value, key, path, depth, series, gesture, carried));
1082
- });
1083
- return result;
1084
- });
1085
- });
1086
- },
1087
- };
1088
- return spec;
1089
- }
1090
- /** The build spec of a `section`. */
1091
- function sectionSpec(cfg, members) {
1092
- const where = `Plan.series.section "${cfg.key}"`;
1093
- const memberSpecs = members.map((m, i) => nestedSpec(m, `${where}[${i}]`));
1094
- const summary = groupSummary(cfg.summary, cfg.summaryAggregate, where);
1095
- /** The header row — at `id`, nested under `parent`. */
1096
- const header = (id, parent) => planRow({
1097
- id, parent,
1098
- gutter: planGutter({
1099
- label: cfg.title,
1100
- ...(cfg.meta !== undefined ? { meta: some(cfg.meta) } : {}),
1101
- ...(cfg.value !== undefined ? { value: some(cfg.value) } : {}),
1102
- }),
1103
- kind: groupKind(summary),
1104
- collapsed: cfg.collapsed ?? false,
1105
- ...(cfg.status !== undefined ? { status: some(resolveTag(cfg.status, StatusValueType)) } : {}),
1106
- });
1107
- const emitters = new ByType();
1108
- const blockLists = new ByType();
1109
- const writerLists = new ByType();
1110
- return {
1111
- key: cfg.key,
1112
- title: cfg.title,
1113
- arm: "section",
1114
- nested: memberSpecs,
1115
- nests: false,
1116
- emitter(collection, at) {
1117
- return emitters.get(collection, () => {
1118
- const blocks = memberSpecs.map((m) => m.emitter(collection, `${at} › ${where}`));
1119
- return East.function([collection, PathType, IdOptType], PlanRowsCollectionType, ($, coll, prefix, parent) => {
1120
- const id = $.let(East.value(variant("section", { series: cfg.key, path: prefix }), PlanRowIdType), PlanRowIdType);
1121
- const under = $.let(East.value(some(id), IdOptType), IdOptType);
1122
- const out = $.let(East.value([header(id, parent)], PlanRowsCollectionType), PlanRowsCollectionType);
1123
- for (const block of blocks)
1124
- $(out.append(block(coll, prefix, under)));
1125
- return out;
1126
- });
1127
- });
1128
- },
1129
- // The header is a FIXED block — no entry produces it, so every window
1130
- // serves it alike and the canvas draws it once — and each member lays
1131
- // out as its own blocks under it, so the series in a section page on
1132
- // their own (#823).
1133
- blocks(collection, at) {
1134
- return blockLists.get(collection, () => {
1135
- const members = memberSpecs.map((m) => m.blocks(collection, `${at} › ${where}`));
1136
- return East.function([collection, PathType, IdOptType], PlanBlocksType, ($, coll, prefix, parent) => {
1137
- const id = $.let(East.value(variant("section", { series: cfg.key, path: prefix }), PlanRowIdType), PlanRowIdType);
1138
- const under = $.let(East.value(some(id), IdOptType), IdOptType);
1139
- const head = $.let(East.value({ fixed: true, parent, rows: [header(id, parent)] }, PlanBlockType), PlanBlockType);
1140
- const out = $.let(East.value([head], PlanBlocksType), PlanBlocksType);
1141
- for (const member of members)
1142
- $(out.append(member(coll, prefix, under)));
1143
- return out;
1144
- });
1145
- });
1146
- },
1147
- // A section adds no path segment, so an entry's rows under it are its
1148
- // members' own: the first member that takes the gesture writes it
1149
- // (#880). The header is written by none.
1150
- writer(collection, at) {
1151
- return writerLists.get(collection, () => {
1152
- const writes = memberSpecs
1153
- .map((m) => m.writer(collection, `${at} › ${where}`))
1154
- .filter((w) => w !== undefined);
1155
- if (writes.length === 0)
1156
- return undefined;
1157
- const { entry, key: kt } = shapeOf(collection, at);
1158
- return East.function([entry, kt, PathType, IntegerType, StringType, PlanGestureType, PlanCarriedType], OptionType(entry), ($, value, key, path, depth, series, gesture, carried) => {
1159
- const result = $.let(none, OptionType(entry));
1160
- for (const w of writes) {
1161
- const write = $.const(w);
1162
- $.if(result.hasTag("none"), ($2) => {
1163
- $2.assign(result, write(value, key, path, depth, series, gesture, carried));
1164
- });
1165
- }
1166
- return result;
1167
- });
1168
- });
1169
- },
1170
- };
1171
- }
1172
- /** The build spec of a `rows` series — hand-built rows, named and placed. */
1173
- function rowsSpec(identity, rows) {
1174
- const emitters = new ByType();
1175
- const blockLists = new ByType();
1176
- const emitter = (collection) => emitters.get(collection, () => East.function([collection, PathType, IdOptType], PlanRowsCollectionType, (_$, _coll, prefix, parent) => REBASE_ROWS(rows, identity.key, prefix, parent)));
1177
- return {
1178
- key: identity.key,
1179
- title: identity.title,
1180
- arm: "rows",
1181
- nested: [],
1182
- nests: false,
1183
- emitter,
1184
- // A FIXED block: no entry produces hand-built rows, so every window
1185
- // serves them alike and the canvas draws them once (#823).
1186
- blocks(collection) {
1187
- return blockLists.get(collection, () => oneBlock(collection, emitter(collection), true));
1188
- },
1189
- // No entry produces them, so no gesture is written into one (#880).
1190
- writer() {
1191
- return undefined;
1192
- },
1193
- };
1194
- }
1195
- // ============================================================================
1196
- // Keys — unique across the whole series tree
1197
- // ============================================================================
1198
- /**
1199
- * Refuse two series sharing a key anywhere in a series tree — a row's id is
1200
- * its series key and its path, so a repeated key would give two rows one id.
1201
- *
1202
- * @param specs - The series, in order
1203
- * @param where - Who is asking, for the message
1204
- * @throws {Error} Naming both series and where each sits
1205
- */
1206
- function assertUniqueKeys(specs, where) {
1207
- const seen = new Map();
1208
- const walk = (list, trail) => {
1209
- list.forEach((spec, i) => {
1210
- const site = `${trail}[${i}] ${nameOf(spec)}`;
1211
- const prior = seen.get(spec.key);
1212
- if (prior !== undefined) {
1213
- throw new Error(`${where}: two series share the key "${spec.key}" — ${prior} and ${site}. A row's id is its ` +
1214
- "series key and its path, so every series key must be unique across the whole series tree.");
1215
- }
1216
- seen.set(spec.key, site);
1217
- walk(spec.nested, `${site} ›`);
1218
- });
1219
- };
1220
- walk(specs, "series");
1221
- }
1222
- // ============================================================================
1223
- // Series values — the East value, its spec beside it
1224
- // ============================================================================
1225
- /** Each spec's top-level writes, by collection type. */
1226
- const topWrites = new WeakMap();
1227
- /**
1228
- * A series' write at the top of a canvas over `collection` (#880) — what the
1229
- * series value carries as `write`: a gesture on a row of one entry, written
1230
- * into a DETACHED copy of the entry (a nested entry in place in its
1231
- * collection); `none` when the row is not the entry's, or no series in the
1232
- * tree takes the gesture on it. A move to another row carries its item
1233
- * between its two writes in `carried` (#825).
1234
- *
1235
- * @param spec - The series' build spec
1236
- * @param collection - The source's collection type
1237
- * @param where - Who is asking, for messages
1238
- * @returns `(entry, key, row, gesture, carried) → the entry written`
1239
- */
1240
- function topWrite(spec, collection, where) {
1241
- let cache = topWrites.get(spec);
1242
- if (cache === undefined) {
1243
- cache = new ByType();
1244
- topWrites.set(spec, cache);
1245
- }
1246
- return cache.get(collection, () => {
1247
- const { entry: rowType, key: kt } = shapeOf(collection, where);
1248
- const writer = spec.writer(collection, where);
1249
- const seg = segmentOf(kt);
1250
- return East.function([rowType, kt, PlanRowIdType, PlanGestureType, PlanCarriedType], OptionType(rowType), ($, entry, key, row, gesture, carried) => {
1251
- const result = $.let(none, OptionType(rowType));
1252
- if (writer === undefined)
1253
- return result;
1254
- const write = $.const(writer);
1255
- $.match(row, {
1256
- entry: ($2, id) => {
1257
- // A row's path starts with its entry's key.
1258
- const mine = $2.let(id.path.size().greater(0n).and(() => id.path.get(0n).equal(seg(key))), BooleanType);
1259
- $2.if(mine, ($3) => {
1260
- const detached = $3.let(East.Blob.encodeBeast(entry, "v2").decodeBeast(rowType, "v2"), rowType);
1261
- $3.assign(result, write(detached, key, id.path, 1n, id.series, gesture, carried));
1262
- });
1263
- },
1264
- });
1265
- return result;
1266
- });
1267
- });
1268
- }
1269
- /** Pin a series value against the instantiated series type, recording its spec. */
1270
- function seriesValue(rowType, keyType, spec, identity) {
1271
- assertUniqueKeys([spec], `Plan.series.${spec.arm} "${spec.key}"`);
1272
- const kt = keyType ?? StringType;
1273
- const source = DictType(kt, rowType);
1274
- const where = `Plan.series.${spec.arm} "${spec.key}"`;
1275
- const blocks = spec.blocks(source, where);
1276
- const derive = East.function([source], PlanBlocksType, ($, data) => {
1277
- const top = $.let(East.value([], PathType), PathType);
1278
- return blocks(data, top, East.value(none, IdOptType));
1279
- });
1280
- const value = East.value(variant(spec.arm, {
1281
- key: identity.key,
1282
- title: identity.title,
1283
- subtitle: identity.subtitle !== undefined ? some(identity.subtitle) : none,
1284
- icon: identity.icon !== undefined ? some(resolveIcon(identity.icon)) : none,
1285
- derive,
1286
- write: topWrite(spec, source, where),
1287
- }), PlanSeriesType(rowType, kt));
1288
- SPECS.set(value, spec);
1289
- return value;
1290
- }
1291
- /** Apply one series value to a source (the exhaustive-arm call) — its blocks. */
1292
- export function applySeriesValue(s, data) {
1293
- const d = data;
1294
- return s.match({
1295
- span: (_$, v) => v.derive(d),
1296
- buckets: (_$, v) => v.derive(d),
1297
- chart: (_$, v) => v.derive(d),
1298
- heat: (_$, v) => v.derive(d),
1299
- table: (_$, v) => v.derive(d),
1300
- cards: (_$, v) => v.derive(d),
1301
- events: (_$, v) => v.derive(d),
1302
- group: (_$, v) => v.derive(d),
1303
- section: (_$, v) => v.derive(d),
1304
- views: (_$, v) => v.derive(d),
1305
- rows: (_$, v) => v.derive(d),
1306
- });
1307
- }
1308
- /**
1309
- * Check a TS series list before it is applied — its keys unique across the
1310
- * whole tree. An East expression list is checked at render (a repeated id is
1311
- * a row diagnostic), since its series are not known until it runs.
1312
- *
1313
- * @param series - The `series` input
1314
- * @param where - Who is asking, for the message
1315
- */
1316
- export function checkSeries(series, where) {
1317
- if (!Array.isArray(series))
1318
- return;
1319
- const specs = series.map((s) => specOf(s)).filter((s) => s !== undefined);
1320
- assertUniqueKeys(specs, where);
1321
- }
1322
- /**
1323
- * Apply the `series` input to the source — the canvas's BLOCKS (#823): every
1324
- * series' blocks, in declared order.
1325
- *
1326
- * @remarks
1327
- * A TS array is built for the source's own collection type (so a source keyed
1328
- * by any type works with series whose accessors ignore the key); an East
1329
- * expression maps at evaluation, so a `$.const`-bound, picked or stored list
1330
- * works identically, its series built for their declared key type.
1331
- *
1332
- * The blocks stay apart so a paged canvas can page each data series on its
1333
- * own: applied to one window of a source, this is every block's share of that
1334
- * window, from one read of it.
1335
- *
1336
- * @param series - The `series` input
1337
- * @param data - The source collection (a whole `Dict`, or one paged window of it)
1338
- * @returns The blocks
1339
- */
1340
- export function applySeries(series, data) {
1341
- const collection = Expr.type(data);
1342
- if (Array.isArray(series)) {
1343
- const lists = series.map((s) => {
1344
- const spec = specOf(s);
1345
- return spec !== undefined
1346
- ? spec.blocks(collection, `Plan.series.${spec.arm} "${spec.key}"`)(data, East.value([], PathType), East.value(none, IdOptType))
1347
- : applySeriesValue(s, data);
1348
- });
1349
- return lists.reduce((acc, list) => acc.concat(list), East.value([], PlanBlocksType));
1350
- }
1351
- return series.map((_$, s) => applySeriesValue(s, data)).flatMap((_$, list) => list);
1352
- }
1353
- /** One series value's `write` (the exhaustive-arm read). */
1354
- function seriesValueWrite(s) {
1355
- return s.match({
1356
- span: (_$, v) => v.write,
1357
- buckets: (_$, v) => v.write,
1358
- chart: (_$, v) => v.write,
1359
- heat: (_$, v) => v.write,
1360
- table: (_$, v) => v.write,
1361
- cards: (_$, v) => v.write,
1362
- events: (_$, v) => v.write,
1363
- group: (_$, v) => v.write,
1364
- section: (_$, v) => v.write,
1365
- views: (_$, v) => v.write,
1366
- rows: (_$, v) => v.write,
1367
- });
1368
- }
1369
- /**
1370
- * The canvas's write (#880) — a gesture on a row of one entry, written into
1371
- * the entry by whichever series in the list made the row: `(entry, key, row,
1372
- * gesture, carried) → the entry written`, `none` when none takes it. A move
1373
- * to another row carries its item between its two writes in `carried`
1374
- * (#825).
1375
- *
1376
- * @remarks
1377
- * The `applySeries` rule: a TS array is built for the source's own collection
1378
- * type, and an East list (a `$.const` list, a pick's) writes through each
1379
- * series value's own `write`, built for its declared key type.
1380
- *
1381
- * @param series - The `series` input
1382
- * @param collection - The source's collection type (`Dict<K, R>`)
1383
- * @returns The write
1384
- */
1385
- export function seriesWriteFn(series, collection) {
1386
- const { entry: rowType, key: kt } = shapeOf(collection, "Plan");
1387
- const inputs = [rowType, kt, PlanRowIdType, PlanGestureType, PlanCarriedType];
1388
- if (Array.isArray(series)) {
1389
- const built = series.map((s) => {
1390
- const spec = specOf(s);
1391
- return spec !== undefined ? topWrite(spec, collection, `Plan.series.${spec.arm} "${spec.key}"`) : undefined;
1392
- });
1393
- return East.function([...inputs], OptionType(rowType), ($, entry, key, row, gesture, carried) => {
1394
- const result = $.let(none, OptionType(rowType));
1395
- series.forEach((s, i) => {
1396
- const own = built[i];
1397
- const write = $.const(own !== undefined ? own : seriesValueWrite(s));
1398
- $.if(result.hasTag("none"), ($2) => { $2.assign(result, write(entry, key, row, gesture, carried)); });
1399
- });
1400
- return result;
1401
- });
1402
- }
1403
- return East.function([...inputs], OptionType(rowType), ($, entry, key, row, gesture, carried) => {
1404
- const result = $.let(none, OptionType(rowType));
1405
- $.for(series, ($2, s) => {
1406
- $2.if(result.hasTag("none"), ($3) => {
1407
- const write = $3.let(seriesValueWrite(s));
1408
- $3.assign(result, write(entry, key, row, gesture, carried));
1409
- });
1410
- });
1411
- return result;
1412
- });
1413
- }
1414
- // ============================================================================
1415
- // Builders — Plan.series.*
1416
- // ============================================================================
1417
- /**
1418
- * A span series — one state-run row per entry; a row with children shows its
1419
- * own runs plus bands over its subtree's runs (`rollup`) — each band sums its
1420
- * runs' quantities unit by unit (#824).
1421
- *
1422
- * @typeParam R - The entry type
1423
- * @typeParam K - The axis kind the runs imply (inferred from `runs`; `never` when erased)
1424
- * @typeParam KT - The entries' key type (`keyType`; `String` by default)
1425
- * @param rowType - The entry type (every builder takes it first — the `Slice.config` shape)
1426
- * @param config - The accessors and nesting ({@link PlanSpanSeriesConfig})
1427
- * @returns A series value, branded with its kind
1428
- */
1429
- export function createSeriesSpan(rowType, config) {
1430
- const cfg = config;
1431
- const rollup = cfg.children !== undefined ? resolveTag(cfg.rollup ?? "union", PlanRollupType) : undefined;
1432
- const spec = dataSpec(rowType, cfg, {
1433
- arm: "span",
1434
- kind: (value, key, hasChildren) => spanKind({
1435
- runs: cfg.runs(value, key),
1436
- ...(cfg.decisions !== undefined ? { decisions: cfg.decisions(value, key) } : {}),
1437
- ...(cfg.ports !== undefined ? { ports: cfg.ports(value, key) } : {}),
1438
- }, rollup === undefined
1439
- ? East.value(none, OptionType(PlanRollupType))
1440
- // A row rolls up only when it HAS child rows — a leaf's bands
1441
- // would repeat its own runs.
1442
- : hasChildren.ifElse(() => East.value(some(rollup), OptionType(PlanRollupType)), () => East.value(none, OptionType(PlanRollupType)))),
1443
- edit: cfg.edit,
1444
- });
1445
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1446
- }
1447
- /**
1448
- * A heat series — one per-bucket cell row per entry; a row with children and
1449
- * no cells of its own shows its children's per-bucket `aggregate`.
1450
- *
1451
- * @typeParam R - The entry type
1452
- * @typeParam K - The axis kind the cells imply (inferred from `cells`; `never` when erased)
1453
- * @typeParam KT - The entries' key type
1454
- * @param rowType - The entry type
1455
- * @param config - The accessors and nesting ({@link PlanHeatSeriesConfig})
1456
- * @returns A series value, branded with its kind
1457
- */
1458
- export function createSeriesHeat(rowType, config) {
1459
- const cfg = config;
1460
- const aggregate = cfg.children !== undefined
1461
- ? East.value(some(resolveTag(cfg.aggregate ?? "mean", PlanAggregateType)), OptionType(PlanAggregateType))
1462
- : East.value(none, OptionType(PlanAggregateType));
1463
- const spec = dataSpec(rowType, cfg, {
1464
- arm: "heat",
1465
- kind: (value, key) => heatKind({
1466
- cells: cfg.cells(value, key),
1467
- ...(cfg.scale !== undefined ? { scale: cfg.scale } : {}),
1468
- }, aggregate),
1469
- });
1470
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1471
- }
1472
- /**
1473
- * A table series — one bucketed-numeral row per entry; a row with children and
1474
- * no values of its own shows per-position subtotals (`aggregate`, `format`).
1475
- *
1476
- * @typeParam R - The entry type
1477
- * @typeParam K - The axis kind the cells imply (inferred from `cells` / `series`; `never` when erased)
1478
- * @typeParam KT - The entries' key type
1479
- * @param rowType - The entry type
1480
- * @param config - The accessors and nesting ({@link PlanTableSeriesOfConfig})
1481
- * @returns A series value, branded with its kind
1482
- */
1483
- export function createSeriesTable(rowType, config) {
1484
- const cfg = config;
1485
- if (cfg.cells !== undefined && cfg.series !== undefined) {
1486
- throw new Error(`Plan.series.table "${cfg.key}": pass \`cells\` (one plain value series) OR \`series\` — not both`);
1487
- }
1488
- const aggregate = cfg.children !== undefined
1489
- ? East.value(some(resolveTag(cfg.aggregate ?? "sum", TableAggregateType)), OptionType(TableAggregateType))
1490
- : East.value(none, OptionType(TableAggregateType));
1491
- const spec = dataSpec(rowType, cfg, {
1492
- arm: "table",
1493
- kind: (value, key) => tableKind({
1494
- ...(cfg.cells !== undefined ? { cells: cfg.cells(value, key) } : {}),
1495
- ...(cfg.fold !== undefined ? { fold: cfg.fold } : {}),
1496
- ...(cfg.series !== undefined ? { series: cfg.series(value, key) } : {}),
1497
- ...(cfg.split !== undefined ? { split: cfg.split } : {}),
1498
- ...(cfg.format !== undefined ? { format: cfg.format } : {}),
1499
- ...(cfg.emphasis !== undefined ? { emphasis: cfg.emphasis } : {}),
1500
- }, aggregate),
1501
- });
1502
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1503
- }
1504
- /**
1505
- * A bucket series — one bucket row (the Planner surface) per entry.
1506
- *
1507
- * @typeParam R - The entry type
1508
- * @typeParam K - The axis kind the tiles imply (inferred from `events` / `markers`; `never` when erased)
1509
- * @typeParam KT - The entries' key type
1510
- * @param rowType - The entry type
1511
- * @param config - The accessors ({@link PlanBucketsSeriesConfig})
1512
- * @returns A series value, branded with its kind
1513
- */
1514
- export function createSeriesBuckets(rowType, config) {
1515
- const cfg = config;
1516
- const spec = dataSpec(rowType, cfg, {
1517
- arm: "buckets",
1518
- kind: (value, key) => bucketsKind({
1519
- ...(cfg.lanes !== undefined ? { lanes: cfg.lanes(value, key) } : {}),
1520
- events: cfg.events(value, key),
1521
- ...(cfg.markers !== undefined ? { markers: cfg.markers(value, key) } : {}),
1522
- }),
1523
- edit: cfg.edit,
1524
- });
1525
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1526
- }
1527
- /**
1528
- * A cards series — one cards row (Roster chips) per entry.
1529
- *
1530
- * @typeParam R - The entry type
1531
- * @typeParam K - The axis kind the chips imply (inferred from `chips`; `never` when erased)
1532
- * @typeParam KT - The entries' key type
1533
- * @param rowType - The entry type
1534
- * @param config - The accessors ({@link PlanCardsSeriesConfig})
1535
- * @returns A series value, branded with its kind
1536
- */
1537
- export function createSeriesCards(rowType, config) {
1538
- const cfg = config;
1539
- const spec = dataSpec(rowType, cfg, {
1540
- arm: "cards",
1541
- kind: (value, key) => cardsKind(cfg.chips(value, key)),
1542
- edit: cfg.edit,
1543
- });
1544
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1545
- }
1546
- /**
1547
- * An events series — one instant-mark row per entry.
1548
- *
1549
- * @typeParam R - The entry type
1550
- * @typeParam K - The axis kind the marks imply (inferred from `marks`; `never` when erased)
1551
- * @typeParam KT - The entries' key type
1552
- * @param rowType - The entry type
1553
- * @param config - The accessors ({@link PlanEventsSeriesConfig})
1554
- * @returns A series value, branded with its kind
1555
- */
1556
- export function createSeriesEvents(rowType, config) {
1557
- const cfg = config;
1558
- const spec = dataSpec(rowType, cfg, {
1559
- arm: "events",
1560
- kind: (value, key) => eventsKind(cfg.marks(value, key)),
1561
- edit: cfg.edit,
1562
- });
1563
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1564
- }
1565
- /**
1566
- * A chart series — one chart row per entry, layers built from the entry's own
1567
- * data. Kind-ERASED: a Chart layer's TS face does not expose its x type, so a
1568
- * chart series constrains no axis at compile time — the render-time
1569
- * diagnostic holds it to the axis like any row.
1570
- *
1571
- * @typeParam R - The entry type
1572
- * @typeParam KT - The entries' key type
1573
- * @param rowType - The entry type
1574
- * @param config - The accessors and shared axes ({@link PlanChartSeriesConfig})
1575
- * @returns A series value
1576
- */
1577
- export function createSeriesChart(rowType, config) {
1578
- const cfg = config;
1579
- const spec = dataSpec(rowType, cfg, {
1580
- arm: "chart",
1581
- kind: (value, key) => chartKind({
1582
- layers: cfg.layers(value, key),
1583
- ...(cfg.left !== undefined ? { left: cfg.left } : {}),
1584
- ...(cfg.right !== undefined ? { right: cfg.right } : {}),
1585
- ...(cfg.height !== undefined ? { height: cfg.height } : {}),
1586
- ...(cfg.expandedHeight !== undefined ? { expandedHeight: cfg.expandedHeight } : {}),
1587
- ...(cfg.expandable !== undefined ? { expandable: cfg.expandable } : {}),
1588
- }),
1589
- ...(cfg.pinned !== undefined
1590
- ? { pinned: (value, key) => East.value(cfg.pinned(value, key), BooleanType) }
1591
- : {}),
1592
- ...(cfg.swatches !== undefined ? { swatches: cfg.swatches } : {}),
1593
- });
1594
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1595
- }
1596
- /**
1597
- * A group series — one group strip PER ENTRY, its members the entry's
1598
- * children (#822). Collapsed, a strip rests as its summary heat strip —
1599
- * explicit `summary` cells, or the renderer-derived `summaryAggregate` — and
1600
- * its member count is derived.
1601
- *
1602
- * @remarks
1603
- * Hierarchy comes from the data's nesting: to group a flat source, reshape it
1604
- * first — inline, one East `groupToDicts` in the canvas function (the entries
1605
- * are then `Dict<String, Row>` and a group's label is its key); a paged source
1606
- * is grouped in the dataflow. The `by` form and the static
1607
- * `group(R, chrome, children)` form are gone — see `Plan.series.section` for a
1608
- * fixed titled block.
1609
- *
1610
- * @typeParam R - The entry type
1611
- * @typeParam K - The axis kind the summary cells imply
1612
- * @typeParam KT - The entries' key type
1613
- * @param rowType - The entry type
1614
- * @param config - The strip's accessors and its members ({@link PlanGroupSeriesConfig})
1615
- * @returns A series value, branded with its kind
1616
- * @throws {Error} When called with the removed `by` or static forms
1617
- */
1618
- export function createSeriesGroup(rowType, config) {
1619
- // The removed forms, named — a plain JS caller would otherwise meet an
1620
- // unhelpful "label is not a function".
1621
- if (arguments.length > 2 || "by" in config) {
1622
- throw new Error("Plan.series.group: the `by` and static `group(R, chrome, children)` forms are removed (#822) — a group " +
1623
- "strip is now one per ENTRY with its members nested in the entry (`children`); reshape a flat source " +
1624
- "with `groupToDicts` first, and use `Plan.series.section(R, { key, title }, [series…])` for a fixed block");
1625
- }
1626
- const cfg = config;
1627
- const where = `Plan.series.group "${cfg.key}"`;
1628
- if (cfg.children === undefined) {
1629
- throw new Error(`${where}: a group strip needs its members — declare \`children\``);
1630
- }
1631
- const summary = cfg.summary;
1632
- // The strip's ONE summary (#824): the per-entry cells, the declared
1633
- // aggregate, or a plain band — both at once is refused here.
1634
- const declared = summary === undefined ? groupSummary(undefined, cfg.summaryAggregate, where) : undefined;
1635
- if (summary !== undefined && cfg.summaryAggregate !== undefined) {
1636
- throw new Error(`${where}: give \`summary\` (explicit strip cells) OR \`summaryAggregate\` (cells derived from the ` +
1637
- "members) — a collapsed strip shows one or the other");
1638
- }
1639
- const spec = dataSpec(rowType, cfg, {
1640
- arm: "group",
1641
- kind: (value, key) => groupKind(declared ?? East.value(variant("cells", East.value(summary(value, key), PlanHeatCellsType)), PlanGroupSummaryType)),
1642
- });
1643
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1644
- }
1645
- /**
1646
- * A section — a fixed titled block over series: one header row, the member
1647
- * series' rows beneath it (#822). A section adds no path segment: its header's
1648
- * id is `section { series, path }` at its parent's path, and its members' rows
1649
- * keep their own.
1650
- *
1651
- * @typeParam R - The entry type (the members' — they share the section's entries)
1652
- * @typeParam K - The union of the members' axis kinds (inferred; `never` when all are erased)
1653
- * @param rowType - The entry type
1654
- * @param config - The header ({@link PlanSectionSeriesConfig})
1655
- * @param members - The member series, in order
1656
- * @returns A series value, branded with its members' kinds
1657
- */
1658
- export function createSeriesSection(rowType, config, members) {
1659
- const cfg = config;
1660
- const spec = sectionSpec(cfg, members);
1661
- return seriesValue(rowType, undefined, spec, cfg);
1662
- }
1663
- /**
1664
- * A views series — each entry gets one row per member series, adjacent and in
1665
- * declared order; the entry's children follow its view rows, nested under the
1666
- * first of them (#822). How one entity is shown several ways: a machine's jobs,
1667
- * utilisation and tonnes as three rows side by side.
1668
- *
1669
- * @remarks
1670
- * A member series' own `match` decides whether its row shows for an entry; a
1671
- * member may not declare `children` (the views own the entry's children). A
1672
- * view row's id is its member series' key and the entry's path, and a seek on
1673
- * the entry lands on its first view row.
1674
- *
1675
- * @typeParam R - The entry type
1676
- * @typeParam K - The union of the members' axis kinds (inferred; `never` when all are erased)
1677
- * @typeParam KT - The entries' key type
1678
- * @param rowType - The entry type
1679
- * @param config - Membership, collapse and children ({@link PlanViewsSeriesConfig})
1680
- * @param members - The member series — one row each per entry, in order
1681
- * @returns A series value, branded with its members' kinds
1682
- */
1683
- export function createSeriesViews(rowType, config, members) {
1684
- const cfg = config;
1685
- const spec = viewsSpec(rowType, cfg, members);
1686
- return seriesValue(rowType, cfg.keyType, spec, cfg);
1687
- }
1688
- /**
1689
- * Hand-built rows riding beside the data-driven series (a pinned KPI chart, a
1690
- * shutdown written out once) — the kind factories' streams, named by this
1691
- * series and placed as its block.
1692
- *
1693
- * @remarks
1694
- * A hand-built row's id is this series' key and the factory `key`s that lead to
1695
- * it (`Plan.ref("works", "shutdown", "elec")`); keys must be unique among a
1696
- * row's siblings, or two rows share an id and the renderer draws the second as
1697
- * a diagnostic.
1698
- *
1699
- * @typeParam R - The entry type (pins the series against its siblings)
1700
- * @typeParam K - The union of the rows' axis kinds (inferred from the kind-factory results; `never` when erased)
1701
- * @param rowType - The entry type
1702
- * @param identity - How the library lists this block ({@link PlanSeriesIdentity})
1703
- * @param rows - The hand-built rows (kind-factory results)
1704
- * @returns A series value, branded with the rows' kinds
1705
- */
1706
- export function createSeriesRows(rowType, identity, rows) {
1707
- const spec = rowsSpec(identity, normalizeRows(rows));
1708
- return seriesValue(rowType, undefined, spec, identity);
1709
- }
1710
- //# sourceMappingURL=series.js.map