@elaraai/e3-ui 1.0.103 → 1.0.105

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 (287) hide show
  1. package/dist/src/allocation/functions.d.ts +2 -1
  2. package/dist/src/allocation/functions.d.ts.map +1 -1
  3. package/dist/src/allocation/functions.js +3 -2
  4. package/dist/src/allocation/functions.js.map +1 -1
  5. package/dist/src/allocation/index.d.ts +120 -1
  6. package/dist/src/allocation/index.d.ts.map +1 -1
  7. package/dist/src/allocation/index.js +24 -4
  8. package/dist/src/allocation/index.js.map +1 -1
  9. package/dist/src/bind/data-indexed.d.ts +25 -4
  10. package/dist/src/bind/data-indexed.d.ts.map +1 -1
  11. package/dist/src/bind/data-indexed.js +58 -7
  12. package/dist/src/bind/data-indexed.js.map +1 -1
  13. package/dist/src/bind/data.d.ts +12 -14
  14. package/dist/src/bind/data.d.ts.map +1 -1
  15. package/dist/src/bind/data.js +11 -11
  16. package/dist/src/bind/data.js.map +1 -1
  17. package/dist/src/bind/func.d.ts +7 -2
  18. package/dist/src/bind/func.d.ts.map +1 -1
  19. package/dist/src/bind/func.js +10 -3
  20. package/dist/src/bind/func.js.map +1 -1
  21. package/dist/src/calendar/index.d.ts +148 -1
  22. package/dist/src/calendar/index.d.ts.map +1 -1
  23. package/dist/src/calendar/index.js +55 -5
  24. package/dist/src/calendar/index.js.map +1 -1
  25. package/dist/src/flowchart/canvas.d.ts +32 -14
  26. package/dist/src/flowchart/canvas.d.ts.map +1 -1
  27. package/dist/src/flowchart/canvas.js +21 -6
  28. package/dist/src/flowchart/canvas.js.map +1 -1
  29. package/dist/src/flowchart/details.d.ts +469 -0
  30. package/dist/src/flowchart/details.d.ts.map +1 -0
  31. package/dist/src/flowchart/details.js +1035 -0
  32. package/dist/src/flowchart/details.js.map +1 -0
  33. package/dist/src/flowchart/flowchart.d.ts +16 -72
  34. package/dist/src/flowchart/flowchart.d.ts.map +1 -1
  35. package/dist/src/flowchart/flowchart.js +10 -1
  36. package/dist/src/flowchart/flowchart.js.map +1 -1
  37. package/dist/src/flowchart/index.d.ts +282 -251
  38. package/dist/src/flowchart/index.d.ts.map +1 -1
  39. package/dist/src/flowchart/index.js +234 -220
  40. package/dist/src/flowchart/index.js.map +1 -1
  41. package/dist/src/flowchart/kinds.d.ts +438 -0
  42. package/dist/src/flowchart/kinds.d.ts.map +1 -0
  43. package/dist/src/flowchart/kinds.js +799 -0
  44. package/dist/src/flowchart/kinds.js.map +1 -0
  45. package/dist/src/flowchart/library.d.ts +154 -739
  46. package/dist/src/flowchart/library.d.ts.map +1 -1
  47. package/dist/src/flowchart/library.js +191 -673
  48. package/dist/src/flowchart/library.js.map +1 -1
  49. package/dist/src/flowchart/payload.d.ts +3652 -7843
  50. package/dist/src/flowchart/payload.d.ts.map +1 -1
  51. package/dist/src/flowchart/payload.js +331 -469
  52. package/dist/src/flowchart/payload.js.map +1 -1
  53. package/dist/src/flowchart/templates.d.ts +657 -0
  54. package/dist/src/flowchart/templates.d.ts.map +1 -0
  55. package/dist/src/flowchart/templates.js +658 -0
  56. package/dist/src/flowchart/templates.js.map +1 -0
  57. package/dist/src/flowchart/types.d.ts +2258 -214
  58. package/dist/src/flowchart/types.d.ts.map +1 -1
  59. package/dist/src/flowchart/types.js +374 -124
  60. package/dist/src/flowchart/types.js.map +1 -1
  61. package/dist/src/index.d.ts +13 -15
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +24 -29
  64. package/dist/src/index.js.map +1 -1
  65. package/dist/src/internal.d.ts +5 -7
  66. package/dist/src/internal.d.ts.map +1 -1
  67. package/dist/src/internal.js +12 -19
  68. package/dist/src/internal.js.map +1 -1
  69. package/dist/src/ontology/index.d.ts +44 -15
  70. package/dist/src/ontology/index.d.ts.map +1 -1
  71. package/dist/src/ontology/index.js +19 -11
  72. package/dist/src/ontology/index.js.map +1 -1
  73. package/dist/src/plan/event-rows.d.ts +2 -1
  74. package/dist/src/plan/event-rows.d.ts.map +1 -1
  75. package/dist/src/plan/event-rows.js +6 -4
  76. package/dist/src/plan/event-rows.js.map +1 -1
  77. package/dist/src/plan/ir.d.ts +1 -0
  78. package/dist/src/plan/ir.d.ts.map +1 -1
  79. package/dist/src/plan/plan.d.ts +145 -1
  80. package/dist/src/plan/plan.d.ts.map +1 -1
  81. package/dist/src/plan/plan.js +67 -3
  82. package/dist/src/plan/plan.js.map +1 -1
  83. package/dist/src/plan/types.d.ts +1 -0
  84. package/dist/src/plan/types.d.ts.map +1 -1
  85. package/dist/src/query/builder.d.ts +362 -315
  86. package/dist/src/query/builder.d.ts.map +1 -1
  87. package/dist/src/query/builder.js +12 -1
  88. package/dist/src/query/builder.js.map +1 -1
  89. package/dist/src/query/index.d.ts +5 -1
  90. package/dist/src/query/index.d.ts.map +1 -1
  91. package/dist/src/query/index.js +3 -1
  92. package/dist/src/query/index.js.map +1 -1
  93. package/dist/src/roster/fit.d.ts +5 -2
  94. package/dist/src/roster/fit.d.ts.map +1 -1
  95. package/dist/src/roster/fit.js +5 -3
  96. package/dist/src/roster/fit.js.map +1 -1
  97. package/dist/src/roster/index.d.ts +103 -2
  98. package/dist/src/roster/index.d.ts.map +1 -1
  99. package/dist/src/roster/index.js +45 -6
  100. package/dist/src/roster/index.js.map +1 -1
  101. package/dist/src/runtime/index.d.ts +1 -3
  102. package/dist/src/runtime/index.d.ts.map +1 -1
  103. package/dist/src/runtime/index.js +1 -3
  104. package/dist/src/runtime/index.js.map +1 -1
  105. package/dist/src/schedule/record-window.d.ts +1 -0
  106. package/dist/src/schedule/record-window.d.ts.map +1 -1
  107. package/dist/src/schematic/index.d.ts +1 -1
  108. package/dist/src/schematic/index.d.ts.map +1 -1
  109. package/dist/src/schematic/index.js +1 -1
  110. package/dist/src/schematic/index.js.map +1 -1
  111. package/dist/src/schematic/kinds.d.ts +4 -24
  112. package/dist/src/schematic/kinds.d.ts.map +1 -1
  113. package/dist/src/schematic/kinds.js +8 -212
  114. package/dist/src/schematic/kinds.js.map +1 -1
  115. package/dist/src/schematic/payload.d.ts +140 -1
  116. package/dist/src/schematic/payload.d.ts.map +1 -1
  117. package/dist/src/schematic/payload.js +38 -1
  118. package/dist/src/schematic/payload.js.map +1 -1
  119. package/dist/src/schematic/types.d.ts.map +1 -1
  120. package/dist/src/schematic/types.js +4 -36
  121. package/dist/src/schematic/types.js.map +1 -1
  122. package/dist/src/schematic/window.d.ts +9 -42
  123. package/dist/src/schematic/window.d.ts.map +1 -1
  124. package/dist/src/schematic/window.js +10 -115
  125. package/dist/src/schematic/window.js.map +1 -1
  126. package/dist/src/sheet/actions.d.ts +388 -0
  127. package/dist/src/sheet/actions.d.ts.map +1 -0
  128. package/dist/src/sheet/actions.js +594 -0
  129. package/dist/src/sheet/actions.js.map +1 -0
  130. package/dist/src/sheet/bridge.d.ts +12 -1
  131. package/dist/src/sheet/bridge.d.ts.map +1 -1
  132. package/dist/src/sheet/bridge.js +30 -6
  133. package/dist/src/sheet/bridge.js.map +1 -1
  134. package/dist/src/sheet/columns.d.ts +5 -2
  135. package/dist/src/sheet/columns.d.ts.map +1 -1
  136. package/dist/src/sheet/columns.js.map +1 -1
  137. package/dist/src/sheet/draft-bridge.d.ts +9 -4
  138. package/dist/src/sheet/draft-bridge.d.ts.map +1 -1
  139. package/dist/src/sheet/draft-bridge.js +22 -7
  140. package/dist/src/sheet/draft-bridge.js.map +1 -1
  141. package/dist/src/sheet/fields.d.ts +13 -0
  142. package/dist/src/sheet/fields.d.ts.map +1 -1
  143. package/dist/src/sheet/fields.js +3 -0
  144. package/dist/src/sheet/fields.js.map +1 -1
  145. package/dist/src/sheet/index.d.ts +32 -2
  146. package/dist/src/sheet/index.d.ts.map +1 -1
  147. package/dist/src/sheet/index.js +18 -3
  148. package/dist/src/sheet/index.js.map +1 -1
  149. package/dist/src/sheet/library.d.ts +8 -0
  150. package/dist/src/sheet/library.d.ts.map +1 -1
  151. package/dist/src/sheet/root.d.ts +23 -1
  152. package/dist/src/sheet/root.d.ts.map +1 -1
  153. package/dist/src/sheet/root.js +40 -5
  154. package/dist/src/sheet/root.js.map +1 -1
  155. package/dist/src/sheet/sheet.d.ts +7843 -4132
  156. package/dist/src/sheet/sheet.d.ts.map +1 -1
  157. package/dist/src/sheet/sheet.js +41 -2
  158. package/dist/src/sheet/sheet.js.map +1 -1
  159. package/dist/src/sheet/templates.d.ts +4 -0
  160. package/dist/src/sheet/templates.d.ts.map +1 -1
  161. package/dist/src/sheet/types.d.ts +12449 -5268
  162. package/dist/src/sheet/types.d.ts.map +1 -1
  163. package/dist/src/sheet/types.js +114 -2
  164. package/dist/src/sheet/types.js.map +1 -1
  165. package/dist/src/utils/derive.d.ts +1 -1
  166. package/dist/src/utils/derive.js +1 -1
  167. package/dist/src/utils/record-kind.d.ts +625 -0
  168. package/dist/src/utils/record-kind.d.ts.map +1 -0
  169. package/dist/src/utils/record-kind.js +450 -0
  170. package/dist/src/utils/record-kind.js.map +1 -0
  171. package/dist/src/utils/views.d.ts +55 -0
  172. package/dist/src/utils/views.d.ts.map +1 -0
  173. package/dist/src/utils/views.js +72 -0
  174. package/dist/src/utils/views.js.map +1 -0
  175. package/dist/src/utils/vocabulary.d.ts +48 -0
  176. package/dist/src/utils/vocabulary.d.ts.map +1 -0
  177. package/dist/src/utils/vocabulary.js +47 -0
  178. package/dist/src/utils/vocabulary.js.map +1 -0
  179. package/dist/test/allocation/allocation.examples.d.ts +2 -0
  180. package/dist/test/allocation/allocation.examples.d.ts.map +1 -1
  181. package/dist/test/allocation/allocation.examples.js +81 -2
  182. package/dist/test/allocation/allocation.examples.js.map +1 -1
  183. package/dist/test/bind/func/func.examples.d.ts +19 -1
  184. package/dist/test/bind/func/func.examples.d.ts.map +1 -1
  185. package/dist/test/bind/func/func.examples.js +36 -1
  186. package/dist/test/bind/func/func.examples.js.map +1 -1
  187. package/dist/test/calendar/calendar.examples.d.ts +2 -0
  188. package/dist/test/calendar/calendar.examples.d.ts.map +1 -1
  189. package/dist/test/calendar/calendar.examples.js +80 -2
  190. package/dist/test/calendar/calendar.examples.js.map +1 -1
  191. package/dist/test/decision/queue.examples.d.ts +1 -0
  192. package/dist/test/decision/queue.examples.d.ts.map +1 -1
  193. package/dist/test/decision/queue.examples.js +12 -0
  194. package/dist/test/decision/queue.examples.js.map +1 -1
  195. package/dist/test/examples-package.d.ts.map +1 -1
  196. package/dist/test/examples-package.js +5 -4
  197. package/dist/test/examples-package.js.map +1 -1
  198. package/dist/test/flowchart/flowchart.examples.d.ts +1250 -4605
  199. package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -1
  200. package/dist/test/flowchart/flowchart.examples.js +861 -512
  201. package/dist/test/flowchart/flowchart.examples.js.map +1 -1
  202. package/dist/test/ontology/ontology.examples.d.ts +2 -3
  203. package/dist/test/ontology/ontology.examples.d.ts.map +1 -1
  204. package/dist/test/ontology/ontology.examples.js +32 -21
  205. package/dist/test/ontology/ontology.examples.js.map +1 -1
  206. package/dist/test/plan/plan-events.examples.d.ts +1 -0
  207. package/dist/test/plan/plan-events.examples.d.ts.map +1 -1
  208. package/dist/test/plan/plan-events.examples.js +44 -0
  209. package/dist/test/plan/plan-events.examples.js.map +1 -1
  210. package/dist/test/plan/plan-nested.examples.d.ts +2 -2
  211. package/dist/test/plan/plan-nested.examples.js +5 -5
  212. package/dist/test/plan/plan-nested.examples.js.map +1 -1
  213. package/dist/test/plan/plan-records.examples.d.ts.map +1 -1
  214. package/dist/test/plan/plan-records.examples.js +1 -1
  215. package/dist/test/plan/plan-records.examples.js.map +1 -1
  216. package/dist/test/query/query.examples.d.ts +2 -0
  217. package/dist/test/query/query.examples.d.ts.map +1 -1
  218. package/dist/test/query/query.examples.js +37 -1
  219. package/dist/test/query/query.examples.js.map +1 -1
  220. package/dist/test/roster/roster.examples.d.ts +2 -0
  221. package/dist/test/roster/roster.examples.d.ts.map +1 -1
  222. package/dist/test/roster/roster.examples.js +76 -15
  223. package/dist/test/roster/roster.examples.js.map +1 -1
  224. package/dist/test/schematic/schematic-records.examples.d.ts.map +1 -1
  225. package/dist/test/schematic/schematic-records.examples.js +6 -4
  226. package/dist/test/schematic/schematic-records.examples.js.map +1 -1
  227. package/dist/test/schematic/schematic.examples.d.ts +1 -0
  228. package/dist/test/schematic/schematic.examples.d.ts.map +1 -1
  229. package/dist/test/schematic/schematic.examples.js +144 -0
  230. package/dist/test/schematic/schematic.examples.js.map +1 -1
  231. package/dist/test/sheet/sheet-actions.examples.d.ts +1264 -0
  232. package/dist/test/sheet/sheet-actions.examples.d.ts.map +1 -0
  233. package/dist/test/sheet/sheet-actions.examples.js +394 -0
  234. package/dist/test/sheet/sheet-actions.examples.js.map +1 -0
  235. package/dist/test/sheet/sheet.examples.d.ts +1 -0
  236. package/dist/test/sheet/sheet.examples.d.ts.map +1 -1
  237. package/dist/test/sheet/sheet.examples.js +77 -0
  238. package/dist/test/sheet/sheet.examples.js.map +1 -1
  239. package/dist/test/studio/studio.examples.d.ts +1 -0
  240. package/dist/test/studio/studio.examples.d.ts.map +1 -1
  241. package/dist/test/studio/studio.examples.js +18 -8
  242. package/dist/test/studio/studio.examples.js.map +1 -1
  243. package/package.json +12 -12
  244. package/dist/src/diff/index.d.ts +0 -407
  245. package/dist/src/diff/index.d.ts.map +0 -1
  246. package/dist/src/diff/index.js +0 -203
  247. package/dist/src/diff/index.js.map +0 -1
  248. package/dist/src/experiment/index.d.ts +0 -1033
  249. package/dist/src/experiment/index.d.ts.map +0 -1
  250. package/dist/src/experiment/index.js +0 -197
  251. package/dist/src/experiment/index.js.map +0 -1
  252. package/dist/src/experiment/types.d.ts +0 -1093
  253. package/dist/src/experiment/types.d.ts.map +0 -1
  254. package/dist/src/experiment/types.js +0 -423
  255. package/dist/src/experiment/types.js.map +0 -1
  256. package/dist/src/flowchart/over.d.ts +0 -227
  257. package/dist/src/flowchart/over.d.ts.map +0 -1
  258. package/dist/src/flowchart/over.js +0 -213
  259. package/dist/src/flowchart/over.js.map +0 -1
  260. package/dist/src/flowchart/patch.d.ts +0 -64
  261. package/dist/src/flowchart/patch.d.ts.map +0 -1
  262. package/dist/src/flowchart/patch.js +0 -67
  263. package/dist/src/flowchart/patch.js.map +0 -1
  264. package/dist/src/flowchart/values.d.ts +0 -271
  265. package/dist/src/flowchart/values.d.ts.map +0 -1
  266. package/dist/src/flowchart/values.js +0 -220
  267. package/dist/src/flowchart/values.js.map +0 -1
  268. package/dist/src/flowchart/window.d.ts +0 -306
  269. package/dist/src/flowchart/window.d.ts.map +0 -1
  270. package/dist/src/flowchart/window.js +0 -63
  271. package/dist/src/flowchart/window.js.map +0 -1
  272. package/dist/src/runtime/diff.d.ts +0 -36
  273. package/dist/src/runtime/diff.d.ts.map +0 -1
  274. package/dist/src/runtime/diff.js +0 -34
  275. package/dist/src/runtime/diff.js.map +0 -1
  276. package/dist/src/runtime/experiment.d.ts +0 -48
  277. package/dist/src/runtime/experiment.d.ts.map +0 -1
  278. package/dist/src/runtime/experiment.js +0 -10
  279. package/dist/src/runtime/experiment.js.map +0 -1
  280. package/dist/test/diff/diff.examples.d.ts +0 -313
  281. package/dist/test/diff/diff.examples.d.ts.map +0 -1
  282. package/dist/test/diff/diff.examples.js +0 -452
  283. package/dist/test/diff/diff.examples.js.map +0 -1
  284. package/dist/test/experiment/experiment.examples.d.ts +0 -1512
  285. package/dist/test/experiment/experiment.examples.d.ts.map +0 -1
  286. package/dist/test/experiment/experiment.examples.js +0 -609
  287. package/dist/test/experiment/experiment.examples.js.map +0 -1
@@ -3,188 +3,89 @@
3
3
  * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
4
4
  */
5
5
  /**
6
- * The flowchart's payload (#1244, `Flowchart Builder Spec.md` §4.1, §4.4,
7
- * §5.2): what `<Flowchart>` hands the renderer through its `Flowchart`
8
- * carrier — its canvas, where its flows come from, its narrowing, the flow it
9
- * opens first, its library's tabs, its inspector, whether it is read only, and
10
- * its name — and every refusal of its props, made when the surface is built.
6
+ * The Flowchart's payload (#1500, `Flowchart Records Spec.md` §3, R1–R4): what
7
+ * `<Flowchart>` hands the renderer through its `Flowchart` carrier — its
8
+ * canvas, its kinds, its narrowing and how a narrowed-out row draws, its
9
+ * library's tabs, whether it has an inspector, the app's own words for a
10
+ * transition's kinds (#1516), whether it is read only, and its name — and
11
+ * every refusal of its props, made when the surface is built. A kind's noun
12
+ * is its own `name`, wherever the Flowchart says it.
11
13
  *
12
- * Its flows come from one of two sources:
13
- * - `record`, an e3 record of `Flowchart.Types.Flows` — flows by name — bound
14
- * with its patch mutation. The handle crosses the payload as the query
15
- * builder's does: its `read`, its `history` and its patch write — and, for
16
- * the editing session over the flows (#1246), its Save: the session's keyed
17
- * batch committed through the patch mutation by `Record.onApply(record, {
18
- * keyed: true })`. A record always holds flows by name (ruled 2026-10-07:
19
- * e3's patch mutation writes only keyed records), so a lone flow is a
20
- * one-entry record, or the host's. With a `flows` source in its `slice`
21
- * (#1346), the Flows tab pages what the rail narrows the record to, the open
22
- * flow is read by its name, and the whole record is never read: only the
23
- * paged window, the read by name and the tab's own search's page cross;
24
- * - `data`, the host's flows by name or one flow — a value, an expression or a
25
- * bind handle — the value's type picking the arm. Given the host's
26
- * `onApply`, the arm carries the session's Save through it (#1247): the
27
- * session's batch restated as one patch of the host's value, which the
28
- * host's `onApply` takes and answers. The host's flows are never narrowed
29
- * (#1346): its `slice` holds only the sources its templates and its tabs
30
- * name.
14
+ * Its kinds are the app's records (R1, `kinds.ts`): `states`, and beside them
15
+ * `transitions`, `lanes` and `decisions`, each closed over its record behind
16
+ * East functions over beast2 bytes, so the payload is one type whatever the
17
+ * rows hold.
31
18
  *
32
- * Its narrowing is one `Slice.bindRecords` (#1340, #1346): `flows` narrows the
33
- * Flows tab, and each other source the templates list or the author's tab
34
- * that names it. The payload carries the rail's chrome (`slice`) and each
35
- * source's narrowed keys (`narrowed`), as every builder's does.
19
+ * Its narrowing is one `Slice.bindRecords` (R4): a source named `states` or
20
+ * `transitions` narrows that kind, read complete through it — or, under
21
+ * `narrowed="dim"`, every row read through it and what the narrowing leaves
22
+ * out drawn as context — and each other source the cards list, the author's
23
+ * tab or the details whose picks it weighs name (#1522). A source named
24
+ * `lanes` or `decisions` is
25
+ * refused: they are read whole. The payload's block binds each source once
26
+ * (`recordSources(…).bind($)`), and each kind reads its own source inside its
27
+ * functions; none reads a source's state, so a choice builds the Flowchart no
28
+ * more.
36
29
  *
37
- * The flowchart takes no callback for an edit (#1247, FB24): every gesture is
38
- * one transaction of its editing session, and each callback it took before is
39
- * refused when the surface is built, naming the remedy.
40
- *
41
- * Its library's tabs are the `Flowchart.library.*` calls `library` lists, on
42
- * the wire in that order: `library.ts` builds each — the Flows tab, and the
43
- * template and author's tabs, each card read from the tab's own rows — and
44
- * makes the library's refusals (#1248).
45
- *
46
- * Its inspector is on by default (#1250, ruled by the user on 2026-10-08):
47
- * the end pane, Details and Issues, unless `inspector={false}`; and
48
- * `inspector={{ state, transition }}` gives a kind its own Details in place of
49
- * its form, each an East function over the row and its writer, wrapped over
50
- * bytes as the Sheet's own Details are. The hover cards went with it: each
51
- * hover prop is refused, naming the inspector.
30
+ * Its inspector is on unless `inspector={false}`, and a kind's own Details is
31
+ * its kind's `inspector`. The props the records replace are refused when the
32
+ * surface is built, each naming the form that replaces it.
52
33
  *
53
34
  * @packageDocumentation
54
35
  */
55
- import { ArrayType, AsyncFunctionType, BlobType, BooleanType, DictType, East, Expr, FunctionType, OptionType, PatchType, StringType, StructType, VariantType, dictPatchOpsType, isTypeEqual, isValueOf, none, printType, some, variant, } from "@elaraai/east";
56
- import { RecordCommitInfoType } from "@elaraai/e3-types";
57
- import { EastUI, Editing, RowSourceType } from "@elaraai/east-ui";
36
+ import { ArrayType, BooleanType, DictType, East, Expr, OptionType, StringType, StructType, isTypeEqual, none, some, variant, } from "@elaraai/east";
37
+ import { EastUI, RowSourceType } from "@elaraai/east-ui";
58
38
  import { RecordSlicesChromeType, isRecordSlices } from "@elaraai/east-ui/internal";
59
- import { Record as RecordBind, RecordOutcomeType } from "../bind/record.js";
60
- import { recordSources, sliceSourceNames } from "../utils/record-sources.js";
61
- import { RowInspectorType, rowInspector } from "../utils/row-inspector.js";
62
- import { buildCanvas, FlowchartCanvasType } from "./canvas.js";
63
- import { FlowchartLibraryTabType, buildLibrary, checkTemplatesSources, librarySources } from "./library.js";
64
- import { FlowchartFlowType, FlowchartFlowsType, FlowchartLinkType, FlowchartStateType } from "./types.js";
65
- import { FlowchartReadEntryType, FlowchartSearchType, FlowchartWindowType, flowchartWindow } from "./window.js";
66
- // ============================================================================
67
- // Where the flows come from
68
- // ============================================================================
69
- /** A record's commits, newest first: who changed it last, and when. */
70
- export const FlowchartHistoryType = FunctionType([], OptionType(ArrayType(RecordCommitInfoType)));
71
- /**
72
- * The editing session's Save (#1246, #1247, FB22): the session's keyed batch —
73
- * the open flow's insert, update or delete by name — as the session hands it,
74
- * bytes of `Editing.Types.ChangeSet(Flowchart.Types.Flow, String)`, sent as
75
- * one commit and answered as the session's Save is: over a record, one patch
76
- * through its patch mutation by `Record.onApply(record, { keyed: true })`;
77
- * over the host's flows or flow, one patch of that value through the host's
78
- * `onApply`, handed the batch's request id with it (#1275).
79
- */
80
- export const FlowchartSessionApplyType = AsyncFunctionType([BlobType], Editing.Types.ApplyResult);
81
- /**
82
- * A record of flows by name, bound with its patch mutation — what the
83
- * renderer reads the flows from and commits to, as the query builder's
84
- * `QueriesHandleType` is the saved queries record's.
85
- *
86
- * @property read - The record's flows
87
- * @property history - Its commits, newest first
88
- * @property commit - Its patch write, awaited: a request id and the patch, answered by the outcome
89
- * @property apply - The editing session's Apply through that patch write ({@link FlowchartSessionApplyType})
90
- */
91
- export const FlowchartFlowsHandleType = StructType({
92
- read: FunctionType([], FlowchartFlowsType),
93
- history: FlowchartHistoryType,
94
- commit: StructType({ patch: AsyncFunctionType([StringType, PatchType(FlowchartFlowsType)], RecordOutcomeType) }),
95
- apply: FlowchartSessionApplyType,
96
- });
97
- /**
98
- * The host's commit of its flows' edits (#1247, #1275): the session's request
99
- * id and one patch of the flows, as a record's patch write takes them, answered
100
- * as the editing session's Save is. A Retry after a write with no answer hands
101
- * the same id again, so a host that keys its write by it — as e3's `commit.patch`
102
- * does — writes once.
103
- */
104
- export const FlowchartFlowsApplyType = AsyncFunctionType([StringType, PatchType(FlowchartFlowsType)], Editing.Types.ApplyResult);
105
- /**
106
- * The host's commit of its one flow's edits (#1247, #1275): the session's
107
- * request id and the flow's own patch, answered as the editing session's Save
108
- * is — a Retry handing the same id again.
109
- */
110
- export const FlowchartFlowApplyType = AsyncFunctionType([StringType, PatchType(FlowchartFlowType)], Editing.Types.ApplyResult);
111
- /**
112
- * The host's flows: its value, of either type, and — when the host takes the
113
- * flowchart's edits — the session's Save through the host's `onApply` (#1247,
114
- * FB22), which hands the host the batch's request id and one patch of its own
115
- * value's type (#1275).
116
- *
117
- * @property flows - Flows by name
118
- * @property flow - One flow
119
- */
120
- export const FlowchartDataType = VariantType({
121
- flows: StructType({ value: FlowchartFlowsType, apply: OptionType(FlowchartSessionApplyType) }),
122
- flow: StructType({ value: FlowchartFlowType, apply: OptionType(FlowchartSessionApplyType) }),
123
- });
124
- /**
125
- * Where a flowchart's flows come from.
126
- *
127
- * @property record - A record of flows by name, bound with its patch mutation, read whole
128
- * @property paged - A record of flows by name its slice's `flows` source pages (#1346): the record's identity, the
129
- * window of the flows the rail narrows it to, a flow read by its name whatever the narrowing, a page of a narrowing
130
- * of the Flows tab's own search, the record's commits and the session's Save
131
- * @property data - The host's flows by name, or one flow: the arm its value's type picked
132
- */
133
- export const FlowchartSourceType = VariantType({
134
- record: FlowchartFlowsHandleType,
135
- paged: StructType({
136
- recordId: StringType,
137
- window: FlowchartWindowType,
138
- entry: FlowchartReadEntryType,
139
- search: FlowchartSearchType,
140
- history: FlowchartHistoryType,
141
- apply: FlowchartSessionApplyType,
142
- }),
143
- data: FlowchartDataType,
144
- });
39
+ import { typeText } from "../schedule/window.js";
40
+ import { recordSources, sliceSourceNames, templatesSource } from "../utils/record-sources.js";
41
+ import { vocabularyWord } from "../utils/vocabulary.js";
42
+ import { FlowchartCanvasType, buildCanvas } from "./canvas.js";
43
+ import { flowchartIndexedRows } from "./details.js";
44
+ import { isFlowchartKind, } from "./kinds.js";
45
+ import { FlowchartLibraryTabType, buildFlowchartLibrary, flowchartTabSources } from "./library.js";
46
+ import { FlowchartDecisionKindType, FlowchartLaneKindType, FlowchartNarrowedType, FlowchartStateKindType, FlowchartTransitionKindType, } from "./types.js";
145
47
  // ============================================================================
146
- // The inspector
48
+ // The payload
147
49
  // ============================================================================
50
+ /** Each source's shown keys on the wire, by the source's name. */
51
+ const ShownType = DictType(StringType, RowSourceType(ArrayType(StringType)));
148
52
  /**
149
- * The inspector pane on the wire (#1250, `Flowchart Builder Spec.md` §5.3,
150
- * FB35–FB38, FB44, FB45): each kind's own Details, where the author gives them
151
- * — a state's, a transition's — in place of that kind's form, as the Sheet's
152
- * own Details (SB58) and a Plan event kind's inspector are: the row as bytes,
153
- * and the writer that takes the edited row back as bytes.
53
+ * The app's own words for what the Flowchart draws of its own (#1516), every one resolved: a transition's kinds. A
54
+ * kind's noun is its own `name` (ruled 5 Nov 2026), so these are the words no kind names.
154
55
  *
155
- * @property state - A state's own Details; `none`, its form
156
- * @property transition - A transition's own Details; `none`, its form
56
+ * @property planned - A transition as it was designed (`Planned`)
57
+ * @property observed - A transition as it was seen to run (`Observed`)
157
58
  */
158
- export const FlowchartInspectorType = StructType({
159
- state: OptionType(RowInspectorType),
160
- transition: OptionType(RowInspectorType),
161
- });
162
- // ============================================================================
163
- // The payload
164
- // ============================================================================
165
- /** Each source's narrowed keys on the wire, by the source's name. */
166
- const NarrowedType = DictType(StringType, RowSourceType(ArrayType(StringType)));
59
+ export const FlowchartVocabularyType = StructType({ planned: StringType, observed: StringType });
167
60
  /**
168
- * The `Flowchart` renderer's payload: the flowchart's interface.
61
+ * The `Flowchart` renderer's payload: the Flowchart's interface (§3).
169
62
  *
170
- * @property canvas - What the canvas draws its flow with ({@link FlowchartCanvasType})
171
- * @property source - Where the flows come from: a record of flows by name, read whole or paged through the slice's `flows` source, or the host's flows or flow
172
- * @property open - Over many flows, the one opened first
63
+ * @property canvas - What the canvas draws with besides its kinds ({@link FlowchartCanvasType})
64
+ * @property states - The states, each a card in its lane
65
+ * @property transitions - The transitions between them; `none`, no transitions
66
+ * @property lanes - The lanes, the canvas's columns; `none`, one column
67
+ * @property decisions - The decisions, each a lettered diamond on the transitions that name it; `none`, no decisions
173
68
  * @property library - The library pane's tabs, in the order `library` lists them; none, no library pane
174
- * @property slice - The narrowing's chrome: one rail over its `Slice.bindRecords` (#1346) — `flows`, and each source a templates list or a tab names; `none`, no rail
175
- * @property narrowed - Each source's narrowed keys, paged through its own data, by the source's name: what a templates list's and a tab's cards follow
176
- * @property inspector - The inspector pane — on by default — with each kind's own Details the author gives ({@link FlowchartInspectorType}); `none`, no inspector pane (`inspector={false}`)
177
- * @property readOnly - No gesture edits, no drop lands, the inspector edits nothing
178
- * @property name - Names the flowchart, when a surface holds two
69
+ * @property slice - The rail's chrome over the one `Slice.bindRecords`; `none`, no rail
70
+ * @property shown - Each source's shown keys, paged through its own data, by the source's name: what a cards list's and a tab's cards follow, and what dims a narrowed-out row
71
+ * @property narrowed - How a narrowed-out row draws: hidden, or dimmed as context
72
+ * @property inspector - Whether the inspector pane shows: on unless `inspector={false}`
73
+ * @property vocabulary - The app's words for a transition's kinds (#1516)
74
+ * @property readOnly - No gesture, drop or inspector edit; selection stays
75
+ * @property name - Keeps the Flowchart's state apart, when a surface holds two
179
76
  */
180
77
  export const FlowchartPayloadType = StructType({
181
78
  canvas: FlowchartCanvasType,
182
- source: FlowchartSourceType,
183
- open: OptionType(StringType),
79
+ states: FlowchartStateKindType,
80
+ transitions: OptionType(FlowchartTransitionKindType),
81
+ lanes: OptionType(FlowchartLaneKindType),
82
+ decisions: OptionType(FlowchartDecisionKindType),
184
83
  library: ArrayType(FlowchartLibraryTabType),
185
84
  slice: OptionType(RecordSlicesChromeType),
186
- narrowed: NarrowedType,
187
- inspector: OptionType(FlowchartInspectorType),
85
+ shown: ShownType,
86
+ narrowed: FlowchartNarrowedType,
87
+ inspector: BooleanType,
88
+ vocabulary: FlowchartVocabularyType,
188
89
  readOnly: BooleanType,
189
90
  name: OptionType(StringType),
190
91
  });
@@ -196,378 +97,339 @@ export const FlowchartPayloadType = StructType({
196
97
  */
197
98
  export const FlowchartComponent = EastUI.component("Flowchart", FlowchartPayloadType, { optional: true });
198
99
  // ============================================================================
199
- // The flowchart's shared keys
100
+ // The Flowchart's shared keys
200
101
  // ============================================================================
201
102
  /**
202
- * The names a flowchart keeps its viewer's state under, by its `name`: its
203
- * frame's panes — their open tab and collapsed state (#1245) — the flow open
204
- * in it, its library's id, LR · TD (#1246), and its drop target, where its
205
- * library's cards land (#1249).
103
+ * The names a Flowchart keeps its viewer's state under, by its `name`: its
104
+ * frame's panes — their open tab and collapsed state — its library's id, LR ·
105
+ * TD, and its drop surface, where its library's cards land.
206
106
  *
207
107
  * @remarks
208
- * As the Plan's `planKeys` and the Sheet's `sheetKeys`: two flowcharts on one
209
- * surface keep apart only when each is named, and two of one name open one
210
- * flow together, and turn together, as the query builder's open query is
211
- * shared by its id.
108
+ * As the Plan's `planKeys` and the Schematic's `schematicKeys`: two
109
+ * Flowcharts on one surface keep apart only when each is named.
212
110
  *
213
- * @param name - The flowchart's name, when a surface holds more than one; omitted, the one flowchart
111
+ * @param name - The Flowchart's name, when a surface holds more than one; omitted, the one Flowchart
214
112
  * @returns The keys
215
113
  */
216
114
  export function flowchartKeys(name) {
217
115
  const suffix = name === undefined ? "" : `.${name}`;
218
116
  return {
219
117
  frame: `flowchart${suffix}.frame`,
220
- flow: `flowchart${suffix}.flow`,
221
118
  library: `flowchart.library${suffix}`,
222
119
  orientation: `flowchart${suffix}.orientation`,
223
120
  surface: `flowchart${suffix}.surface`,
224
121
  };
225
122
  }
226
- /** The tables and row mappers the flowchart took before it held flows, which `Flowchart.over` takes now. */
227
- const TABLES = ["states", "links", "lanes", "triggers", "state", "link", "lane", "trigger"];
228
- /** The sizes the flowchart took before it filled the box it is given (#1245). */
229
- const SIZES = ["height", "maxHeight"];
230
- /**
231
- * The refusal of `density`, which the flowchart took and never drew by (#1251,
232
- * ruled by the user on 2026-10-09: "Remove it"): the canvas draws at one
233
- * rhythm, the spec's.
234
- */
235
- const DENSITY = "Flowchart: `density` is not a prop — the canvas draws at one rhythm, the spec's 116×40 state cards in their lanes; leave `density` out";
236
- /** The callbacks the flowchart took for its edits before each gesture was a transaction of its editing session (#1247, FB24). */
237
- const EDIT_CALLBACKS = ["linkMode", "onCreateLink", "onDeleteLink", "onAddLane", "onRenameLane", "onDeleteLane", "onAddState", "onEditState", "onMoveState"];
123
+ /** The refusal of the flows: the kinds over the app's records replace them (R1). */
124
+ const RECORDS = "the Flowchart takes no `record`, `data`, `flow` or `onApply` — its records are its kinds: " +
125
+ "states={Flowchart.states(Record.bind(steps), { label, lane, order })}, transitions={Flowchart.transitions(Record.bind(moves), { from, to })}, " +
126
+ "lanes={Flowchart.lanes(Data.bind(phases), { label })} and decisions={Flowchart.decisions(Data.bind(rules), { label })}";
127
+ /** The refusal of a row mapper: a kind maps its record's fields to its roles (R2). */
128
+ const MAPPERS = "a kind maps its record's fields to its roles — Flowchart.states(record, { label, lane, order }), " +
129
+ "Flowchart.transitions(record, { from, to, decision }), Flowchart.lanes(record, { label, order }) and Flowchart.decisions(record, { label })";
130
+ /** The refusal of a callback for an edit: the editing session's gestures replace them. */
131
+ const SESSION = "every gesture is a transaction of the Flowchart's editing session, and Save writes each record through its patch door — " +
132
+ "bind a kind with Record.bind(record), its record declaring patch: mutation.patch(), to edit it";
133
+ /** The refusal of a hover card: the inspector replaces them. */
134
+ const HOVER = "the inspector shows what is selected, and a kind's own Details is its kind's `inspector`: " +
135
+ "Flowchart.states(record, { …, inspector: East.function([RowType, FunctionType([RowType], NullType)], UIComponentType, ($, row, update) => …) })";
136
+ /** The refusal of a size: the Flowchart fills the box it is given. */
137
+ const SIZE = "the Flowchart fills the box it is given — give it a box of its own height: <Box height=\"560px\"><Flowchart … /></Box>";
138
+ /** Each prop the records and the editing session replace, with the form that replaces it. */
139
+ const REMOVED = {
140
+ record: RECORDS,
141
+ data: RECORDS,
142
+ flow: RECORDS,
143
+ onApply: RECORDS,
144
+ window: "the states and the transitions read through their sources of the slice, `states` and `transitions` — " +
145
+ "slice={{ slice: Slice.bindRecords(key, { states: { source: Data.bindPaged(steps, { indexes }) } }) }}",
146
+ links: "the transitions are `transitions`: transitions={Flowchart.transitions(record, { from, to })}",
147
+ triggers: "the decisions are `decisions`: decisions={Flowchart.decisions(record, { label })}",
148
+ state: MAPPERS,
149
+ link: MAPPERS,
150
+ lane: MAPPERS,
151
+ trigger: MAPPERS,
152
+ height: SIZE,
153
+ maxHeight: SIZE,
154
+ density: "the canvas draws at one rhythm — leave `density` out",
155
+ linkMode: SESSION,
156
+ onCreateLink: SESSION,
157
+ onDeleteLink: SESSION,
158
+ onAddLane: SESSION,
159
+ onRenameLane: SESSION,
160
+ onDeleteLane: SESSION,
161
+ onAddState: SESSION,
162
+ onEditState: SESSION,
163
+ onMoveState: SESSION,
164
+ stateHover: HOVER,
165
+ linkHover: HOVER,
166
+ triggerHover: HOVER,
167
+ affordances: "it moved into `slice`: slice={{ slice: Slice.bindRecords(key, { … }), affordances }}",
168
+ };
169
+ /** Every prop `<Flowchart>` takes. */
170
+ const PROPS = new Set([
171
+ "states", "transitions", "lanes", "decisions", "slice", "narrowed", "library", "inspector", "vocabulary", "readOnly", "name",
172
+ "orientation", "freshness", "minimap", "legend", "onSelectState", "onSelectLink", "onSelectTrigger", "onTracePath", "canConnect", "narrow",
173
+ ]);
174
+ /** The canvas's props, which the payload's `canvas` carries. */
175
+ const CANVAS = [
176
+ "orientation", "freshness", "minimap", "legend", "onSelectState", "onSelectLink", "onSelectTrigger", "onTracePath", "canConnect", "narrow",
177
+ ];
178
+ /** The declaration each kind's prop takes, as a refusal names it. */
179
+ const DECLARE = {
180
+ states: "Flowchart.states(record, { label, lane?, order? })",
181
+ transitions: "Flowchart.transitions(record, { from, to, decision? })",
182
+ lanes: "Flowchart.lanes(record, { label, order? })",
183
+ decisions: "Flowchart.decisions(record, { label, owner?, queue? })",
184
+ };
238
185
  /**
239
- * The hover cards the flowchart took before its inspector showed what is
240
- * selected (#1250, FB46, ruled by the user on 2026-10-08), each with its
241
- * remedy: a state's or a transition's own Details, or a decision's form.
186
+ * Reads one kind's prop, checked to hold a kind of its sort.
187
+ *
188
+ * @param sort - The prop
189
+ * @param given - What it was given
190
+ * @returns The kind; `undefined` when it is left out
191
+ * @throws {Error} When it holds anything but a kind of its sort, naming the declaration it takes — and the prop the kind it holds belongs under
242
192
  */
243
- const HOVERS = {
244
- stateHover: "give a state its own Details with inspector={{ state: East.function([Flowchart.Types.State, FunctionType([Flowchart.Types.State], NullType)], UIComponentType, ($, state, update) => …) }}",
245
- linkHover: "give a transition its own Details with inspector={{ transition: East.function([Flowchart.Types.Link, FunctionType([Flowchart.Types.Link], NullType)], UIComponentType, ($, link, update) => …) }}",
246
- triggerHover: "a decision's Details are its form — every field, and the transitions it governs",
247
- };
248
- /** The refusal of `window`, which the `flows` source of `slice` replaced (#1346). */
249
- const WINDOW = "Flowchart: `window={Slice.rows(slice)}` is gone — the Flows tab pages the `flows` source of `slice`: slice={{ slice: Slice.bindRecords(key, { flows: { source: Data.bindPaged(record, { indexes }), fields } }) }}";
250
- /** The refusal of a `slice` that is not `{ slice }` — the bare handle a flow from the host's tables was narrowed by (#1346). */
251
- const SLICE = "Flowchart: `slice` takes { slice } — slice={{ slice: Slice.bindRecords(key, { flows, … }) }} over a record of flows; the bare handle is gone, and a flow built from the host's tables (Flowchart.over over `data`) is never narrowed: narrow its rows in the task that builds them";
252
- /** What the flowchart's slice narrows, as the refusal of a source nothing names says it. */
253
- const NARROWS = "its flows, and the templates lists and tabs that name a source";
193
+ function kindOf(sort, given) {
194
+ if (given === undefined)
195
+ return undefined;
196
+ if (isFlowchartKind(given, sort))
197
+ return given;
198
+ const other = ["states", "transitions", "lanes", "decisions"].find((s) => isFlowchartKind(given, s));
199
+ throw new Error(`Flowchart: \`${sort}\` is ${DECLARE[sort]} over the app's record` + (other === undefined ? "" : ` — and this is ${DECLARE[other]}: give it as \`${other}\``));
200
+ }
254
201
  /**
255
- * The refusal of a kind's own Details of another type than its row's.
202
+ * How a narrowed-out row draws, on the wire; and whether it is dimmed, when
203
+ * each kind read through its source reads every row and the renderer draws
204
+ * what the narrowing leaves out as context.
256
205
  *
257
- * @param kind - The kind, as `inspector` names it
258
- * @param type - Its row's type, as `Flowchart.Types` names it
259
- * @param row - What the function calls its row
260
- * @returns The refusal
206
+ * @param narrowed - The Flowchart's `narrowed`
207
+ * @returns It on the wire, and whether a narrowed-out row is dimmed
208
+ * @throws {Error} For a `narrowed` of another form, naming the forms it takes
261
209
  */
262
- function rowRefusal(kind, type, row) {
263
- return `Flowchart: \`inspector.${kind}\` is a ${kind}'s own Details — an East function over the ${kind} and its writer: East.function([Flowchart.Types.${type}, FunctionType([Flowchart.Types.${type}], NullType)], UIComponentType, ($, ${row}, update) => …)`;
210
+ function narrowedOf(narrowed) {
211
+ if (narrowed !== undefined && narrowed !== "hide" && narrowed !== "dim") {
212
+ throw new Error("Flowchart: `narrowed` is \"hide\" (the default), which leaves what the narrowing leaves out off the canvas, or \"dim\", which draws it as context");
213
+ }
214
+ const dim = narrowed === "dim";
215
+ return { wire: East.value(variant(dim ? "dim" : "hide", null), FlowchartNarrowedType), dim };
264
216
  }
265
217
  /**
266
- * The inspector pane on the wire (#1250, FB44, FB45): on by default, or given
267
- * `true`; none for `false`; and each kind's own Details where `{ state,
268
- * transition }` gives them, checked against the row's type and wrapped over
269
- * bytes, as the Sheet's own Details are.
218
+ * The inspector pane: on unless `false`.
270
219
  *
271
- * @param inspector - The flowchart's `inspector`
272
- * @returns The pane, or none
273
- * @throws {Error} Naming the prop and the remedy: an `inspector` of another
274
- * kind, a key other than `state` and `transition`, and a function of another
275
- * type than `(Row, (Row) => Null) => UIComponentType`
220
+ * @param inspector - The Flowchart's `inspector`
221
+ * @returns Whether the pane shows
222
+ * @throws {Error} For an `inspector` that is no Boolean — the `{ state, transition }` the Flowchart took before among
223
+ * them — naming the kind's own `inspector`, the one way to give it Details
276
224
  */
277
225
  function inspectorOf(inspector) {
226
+ if (inspector === undefined || inspector === true)
227
+ return true;
278
228
  if (inspector === false)
279
- return East.value(none, OptionType(FlowchartInspectorType));
280
- if (inspector === undefined || inspector === true) {
281
- return East.value(some({ state: none, transition: none }), OptionType(FlowchartInspectorType));
282
- }
283
- if (inspector === null || typeof inspector !== "object" || inspector instanceof Expr || Array.isArray(inspector)) {
284
- throw new Error("Flowchart: `inspector` is on by default — inspector={false} removes the pane, and inspector={{ state, transition }} gives a state or a transition its own Details, each an East function over the row and its writer");
285
- }
286
- const given = inspector;
287
- for (const key of Object.keys(given)) {
288
- if (key !== "state" && key !== "transition") {
289
- throw new Error(`Flowchart: \`inspector\` gives a state or a transition its own Details — { state, transition } — and \`${key}\` is neither: every other kind's Details are its form`);
290
- }
291
- }
292
- const state = given.state === undefined ? none : some(rowInspector(given.state, FlowchartStateType, rowRefusal("state", "State", "state")));
293
- const transition = given.transition === undefined ? none : some(rowInspector(given.transition, FlowchartLinkType, rowRefusal("transition", "Link", "link")));
294
- return East.value(some({ state, transition }), OptionType(FlowchartInspectorType));
295
- }
296
- /** The refusal of a record not bound with its patch mutation. */
297
- const UNBOUND = "Flowchart: `record` is an e3 record bound with its patch mutation — Record.bind(record), its record declaring patch: mutation.patch()";
298
- /** A field of a struct type, or `undefined`. */
299
- function fieldOf(type, name) {
300
- return type?.type === "Struct" ? type.fields[name] : undefined;
229
+ return false;
230
+ throw new Error("Flowchart: `inspector` is true or false — on unless false — and a kind's own Details is its kind's `inspector`: " +
231
+ "Flowchart.states(record, { …, inspector: East.function([RowType, FunctionType([RowType], NullType)], UIComponentType, ($, row, update) => …) })");
301
232
  }
233
+ /** Each kind's noun as the vocabulary would give it, by the kind its own `name` names instead. */
234
+ const KIND_WORDS = new Map([["state", "states"], ["transition", "transitions"], ["lane", "lanes"], ["decision", "decisions"]]);
235
+ /** Each kind's declaration, its `name` among its options, as a refusal of a kind's noun in the vocabulary shows it. */
236
+ const NAMED = {
237
+ states: "Flowchart.states(record, { label, name })",
238
+ transitions: "Flowchart.transitions(record, { from, to, name })",
239
+ lanes: "Flowchart.lanes(record, { label, name })",
240
+ decisions: "Flowchart.decisions(record, { label, name })",
241
+ };
302
242
  /**
303
- * A `Record.bind` handle over flows by name, bound with its patch mutation,
304
- * checked — and the editing session's Apply through its patch door. A record
305
- * of one flow is refused: e3's patch mutation writes only keyed records (ruled
306
- * 2026-10-07), so a lone flow is a one-entry record, or the host's `data`.
243
+ * The Flowchart's words, resolved: a transition's kinds, each the app's or its default.
244
+ *
245
+ * @param given - The Flowchart's `vocabulary`
246
+ * @returns Both words
247
+ * @throws {Error} For a `vocabulary` that is no object; an entry naming a kind's noun, naming the kind's `name` that
248
+ * gives it; an entry the Flowchart has no word for; and an entry given empty
249
+ * @internal
307
250
  */
308
- function checkedRecord(record) {
309
- if (!(record instanceof Expr))
310
- throw new Error(UNBOUND);
311
- const type = Expr.type(record);
312
- const read = fieldOf(type, "read");
313
- if (read === undefined || read.type !== "Function" || read.inputs.length !== 0
314
- || fieldOf(type, "history")?.type !== "Function" || fieldOf(type, "binding") === undefined) {
315
- throw new Error(UNBOUND);
251
+ export function flowchartVocabulary(given) {
252
+ if (given !== undefined && (typeof given !== "object" || given === null || given instanceof Expr)) {
253
+ throw new Error("Flowchart: `vocabulary` takes the app's words for a transition's kinds — vocabulary={{ planned?, observed? }}");
316
254
  }
317
- const recordType = read.output;
318
- if (isTypeEqual(recordType, FlowchartFlowType)) {
319
- throw new Error("Flowchart: `record` holds flows by name, Flowchart.Types.Flows — e3's patch mutation writes only keyed records — and this record holds one flow: make it a record of flows with one entry (Flowchart.values({ [name]: flow })), or pass the flow as `data`");
320
- }
321
- if (!isTypeEqual(recordType, FlowchartFlowsType)) {
322
- throw new Error(`Flowchart: \`record\` holds flows by name, Flowchart.Types.Flows — declare it with that type — and this record holds ${printType(recordType)}`);
323
- }
324
- // The patch door: the record's mutation.patch(), the mutation named `patch` taking
325
- // the record's patch.
326
- const door = fieldOf(fieldOf(type, "commit"), "patch");
327
- if (door === undefined || !isTypeEqual(door, AsyncFunctionType([StringType, PatchType(FlowchartFlowsType)], RecordOutcomeType))) {
328
- throw new Error(`${UNBOUND}, and this binding ${door === undefined ? "has no `patch`" : "has a `patch` that takes another patch than the record's"}`);
255
+ const words = (given ?? {});
256
+ for (const entry of Object.keys(words)) {
257
+ const kind = KIND_WORDS.get(entry);
258
+ if (kind !== undefined) {
259
+ throw new Error(`Flowchart: \`vocabulary.${entry}\` is not one of its words — a kind's noun is its own \`name\`: ${NAMED[kind]}`);
260
+ }
261
+ if (entry !== "planned" && entry !== "observed") {
262
+ throw new Error(`Flowchart: \`vocabulary.${entry}\` is not one of its words — it takes \`planned\` and \`observed\`, a transition's kinds, and a kind's noun is its own \`name\``);
263
+ }
329
264
  }
330
- // The session's Apply (#1246): its keyed batch, decoded at its own type
331
- // and committed as it is — each flow's insert, update or delete by name —
332
- // through the patch door, by Record.onApply's keyed form.
333
- const keyed = RecordBind.onApply(record, { keyed: true });
334
- const batchType = Editing.Types.ChangeSet(FlowchartFlowType, StringType);
335
- const apply = East.asyncFunction([BlobType], Editing.Types.ApplyResult, ($, blob) => {
336
- const commit = $.const(keyed);
337
- return commit(blob.decodeBeast(batchType, "v2"));
338
- });
339
- return { handle: record, apply };
340
- }
341
- /** The record arm: the checked record, its read, its history, its patch write and the session's Apply through it, read whole. */
342
- function recordArm(record) {
343
- const { handle, apply } = checkedRecord(record);
344
265
  return {
345
- many: true,
346
- source: variant("record", { read: handle.read, history: handle.history, commit: { patch: handle.commit.patch }, apply }),
266
+ planned: vocabularyWord("Flowchart", "planned", words.planned, "Planned"),
267
+ observed: vocabularyWord("Flowchart", "observed", words.observed, "Observed"),
347
268
  };
348
269
  }
349
270
  /**
350
- * The paged arm (#1346): the checked record — its identity, its history and
351
- * the session's Apply through its patch door — and the `flows` source's reads,
352
- * each over the source alone, as the payload's block bound it: the Flows
353
- * tab's window, a flow by its name, and the tab's own search's page. The whole
354
- * record is never read.
355
- */
356
- function pagedArm(record, flows) {
357
- const { handle, apply } = checkedRecord(record);
358
- const view = flowchartWindow(flows.part, flows.rows);
359
- return { many: true, source: variant("paged", { recordId: handle.binding.name, ...view, history: handle.history, apply }) };
360
- }
361
- /** The host's flows as an expression: an expression, a bind handle's read, or a value of either type. */
362
- function dataValue(data) {
363
- if (data instanceof Expr) {
364
- const read = fieldOf(Expr.type(data), "read");
365
- return read !== undefined && read.type === "Function" && read.inputs.length === 0
366
- ? data.read()
367
- : data;
368
- }
369
- if (isValueOf(data, FlowchartFlowsType))
370
- return East.value(data, FlowchartFlowsType);
371
- if (isValueOf(data, FlowchartFlowType))
372
- return East.value(data, FlowchartFlowType);
373
- throw new Error("Flowchart: `data` is Flowchart.Types.Flows, flows by name, or Flowchart.Types.Flow, one flow — a value, an expression or a bind handle of either; Flowchart.over builds one flow from an app's tables — and this value is neither");
374
- }
375
- /** The host's `onApply`, checked against a request id and the patch of its flows' type. */
376
- function applyOf(onApply, applyType, value) {
377
- const apply = (onApply instanceof Expr ? onApply : East.value(onApply, applyType));
378
- const type = Expr.type(apply);
379
- if (!isTypeEqual(type, applyType)) {
380
- throw new Error(`Flowchart: \`onApply\` commits \`data\`'s edits, one patch of the value at a time — an East.asyncFunction from the session's request id and PatchType(${value}), [StringType, PatchType(${value})], to Editing.Types.ApplyResult; a Retry hands the same id again — and this one is ${printType(type)}`);
381
- }
382
- return apply;
383
- }
384
- /**
385
- * The data arm: the host's flows, of either type, and — when the host takes
386
- * the edits — the session's Save through its `onApply` (#1247, FB22). The
387
- * session's batch is keyed by name, as over a record: over flows by name it is
388
- * restated as one patch of the flows, each change the open flow's insert,
389
- * update or delete by name, as `Record.onApply(record, { keyed: true })`
390
- * restates it for a record — never the whole value replaced, so the host's
391
- * other flows stay as they are; over one flow, its one change is the flow's
392
- * own patch. The host's `onApply` is handed the batch's request id with it
393
- * (#1275) — the same id on a Retry, which resends the same batch — and answers
394
- * the session.
271
+ * The rows a source of the slice narrows (#1522): its binding's joined row,
272
+ * from the type of the binding its part holds.
273
+ *
274
+ * @param narrowing - The Flowchart's `slice`, a `Slice.bindRecords`
275
+ * @param source - The source
276
+ * @returns The row's struct; `undefined` where the part's binding pages no such rows
395
277
  */
396
- function dataArm(data, onApply) {
397
- const value = dataValue(data);
398
- const type = Expr.type(value);
399
- const many = isTypeEqual(type, FlowchartFlowsType);
400
- if (!many && !isTypeEqual(type, FlowchartFlowType)) {
401
- throw new Error(`Flowchart: \`data\` is Flowchart.Types.Flows, flows by name, or Flowchart.Types.Flow, one flow — a value, an expression or a bind handle of either; Flowchart.over builds one flow from an app's tables — and this is ${printType(type)}`);
402
- }
403
- if (onApply === undefined)
404
- return { many, source: variant("data", variant(many ? "flows" : "flow", { value, apply: none })) };
405
- // The host's commit, its patch opaque here, as in `Record.onApply`; its runtime type is exact.
406
- const host = applyOf(onApply, many ? FlowchartFlowsApplyType : FlowchartFlowApplyType, many ? "Flowchart.Types.Flows" : "Flowchart.Types.Flow");
407
- const batchType = Editing.Types.ChangeSet(FlowchartFlowType, StringType);
408
- const apply = many
409
- ? East.asyncFunction([BlobType], Editing.Types.ApplyResult, ($, blob) => {
410
- const commit = $.const(host);
411
- const batch = $.const(blob.decodeBeast(batchType, "v2"));
412
- // Each change is its flow's insert, update or delete, by name: the
413
- // batch's own values and patches, carrying what the flow was when
414
- // the edit began.
415
- const ops = $.let(new Map(), DictType(StringType, dictPatchOpsType(FlowchartFlowType)));
416
- $.for(batch.changes, ($, change) => {
417
- $.match(change.patch, {
418
- replace: ($, swap) => {
419
- $.match(swap.after, {
420
- some: ($, after) => {
421
- $.match(swap.before, {
422
- none: ($) => { $(ops.insert(change.id, variant("insert", after))); },
423
- some: ($, before) => { $(ops.insert(change.id, variant("update", East.diff(before, after)))); },
424
- });
425
- },
426
- none: ($) => {
427
- $.match(swap.before, { some: ($, before) => { $(ops.insert(change.id, variant("delete", before))); } });
428
- },
429
- });
430
- },
431
- patch: ($, entry) => {
432
- $.match(entry, { some: ($, update) => { $(ops.insert(change.id, variant("update", update))); } });
433
- },
434
- });
435
- });
436
- return commit(batch.requestId, variant("patch", ops));
437
- })
438
- : East.asyncFunction([BlobType], Editing.Types.ApplyResult, ($, blob) => {
439
- const commit = $.const(host);
440
- const batch = $.const(blob.decodeBeast(batchType, "v2"));
441
- // One flow is one entry, changed in place: its change is the flow's own patch.
442
- const result = $.let(variant("rejected", [{ entry: "", row: none, field: none,
443
- message: "One flow is changed in place: Save never adds or removes it" }]), Editing.Types.ApplyResult);
444
- $.for(batch.changes, ($, change) => {
445
- $.match(change.patch, {
446
- replace: ($, swap) => {
447
- $.match(swap.before, {
448
- some: ($, before) => {
449
- $.match(swap.after, { some: ($, after) => { $.assign(result, commit(batch.requestId, East.diff(before, after))); } });
450
- },
451
- });
452
- },
453
- patch: ($, entry) => {
454
- $.match(entry, { some: ($, update) => { $.assign(result, commit(batch.requestId, update)); } });
455
- },
456
- });
457
- });
458
- return result;
459
- });
460
- return { many, source: variant("data", variant(many ? "flows" : "flow", { value, apply: some(apply) })) };
278
+ function sliceSourceRows(narrowing, source) {
279
+ const handle = East.value(narrowing.slice);
280
+ const sources = Expr.type(handle).fields["sources"];
281
+ const part = sources?.type === "Struct" ? sources.fields[source] : undefined;
282
+ const binding = part?.type === "Struct" ? part.fields["source"] : undefined;
283
+ return binding === undefined ? undefined : flowchartIndexedRows(binding)?.row;
461
284
  }
462
285
  /**
463
- * Creates the flowchart's payload alone — what `<Flowchart>` returns through
286
+ * Creates the Flowchart's payload alone — what `<Flowchart>` returns through
464
287
  * the `Flowchart` carrier — for the tests and the renderer's fixtures, which
465
288
  * read it whole.
466
289
  *
467
- * @param props - The flowchart's props, as `<Flowchart>` takes them
290
+ * @param props - The Flowchart's props ({@link FlowchartProps})
468
291
  * @returns An East expression of {@link FlowchartPayloadType}
469
- * @throws {Error} Naming the prop and the remedy: flows from both `record` and
470
- * `data`, or from neither; `onApply` over a record; `window`, which the
471
- * `flows` source of `slice` replaced; a `slice` that is not `{ slice }` —
472
- * the bare handle a flow from the host's tables was narrowed by — or not
473
- * `Slice.bindRecords`, or holding a source nothing names, or the brush;
474
- * `affordances` outside `slice`; a `flows` source over `data`, whose flows
475
- * are the host's; a templates list written in the code — naming no source
476
- * of the slice — or naming `flows`, and the two templates lists naming one
477
- * source; `flow` over one flow; a record of one flow, or of another type
478
- * than `Flowchart.Types.Flows`, or not bound with its patch mutation;
479
- * `data` of neither flow type; an `onApply` that does not take a request id
480
- * and the patch of `data`'s type; a table or row mapper, which
481
- * `Flowchart.over` takes; `height` or `maxHeight`, which the box the
482
- * flowchart fills sets; a callback for an edit, or `linkMode`, which the
483
- * editing session's gestures replace; a hover card's builder (`stateHover`,
484
- * `linkHover`, `triggerHover`), which the inspector replaces; `density`,
485
- * which the canvas's one rhythm replaces; an `inspector` of another kind
486
- * than a Boolean or `{ state, transition }`, a key other than those two, or
487
- * a kind's own Details of another type than `(Row, (Row) => Null) =>
488
- * UIComponentType`; and each of the library's refusals (`library.ts`'s
489
- * `buildLibrary`): a tab listed twice, the Flows tab over one flow, a tab's
490
- * source the slice lacks, a data tab's rows of neither an Array nor a
491
- * `Dict<String, T>` — a record's for a templates list or a tab that follows
492
- * a source — and a `drop` of another type than its tab's
292
+ * @throws {Error} Naming the prop and the remedy (§3): `record`, `data`, `flow` and `onApply`, which its kinds replace;
293
+ * `window`; the tables and row mappers; `height` and `maxHeight`; `density`; a callback for an edit and `linkMode`;
294
+ * a hover card's builder; `affordances` outside `slice`; a prop the Flowchart doesn't take; no states; a kind's prop
295
+ * holding no kind of its sort; a state's lane with no lanes, and lanes beside states that name none; a transition's
296
+ * decision with no decisions; a `slice` that is not `{ slice }`, or not `Slice.bindRecords`, or holding a source
297
+ * nothing names, a `lanes` or `decisions` source, or the brush; a cards list naming no source of the slice, or its
298
+ * kind's own; details naming no source of the slice, a kind's own, or one over rows of another type than theirs
299
+ * (#1522); a `narrowed` of another form; an `inspector` that is no Boolean, and `inspector={false}` beside a
300
+ * details' read shown in the inspector alone; each of `vocabulary`'s refusals ({@link flowchartVocabulary}); a
301
+ * `name` that is no string; each of the library's refusals (`library.ts`); and each kind's refusals of its binding
302
+ * and its details (`kinds.ts`, `details.ts`)
493
303
  * @internal
494
304
  */
495
305
  export function createFlowchartPayload(props) {
496
- const { record, window, data, onApply, flow, library, slice, inspector, readOnly, name, ...canvas } = props;
497
- for (const table of TABLES) {
498
- if (table in canvas) {
499
- throw new Error(`Flowchart: \`${table}\` is one of the tables, or the row mappers, Flowchart.over builds a flow from — pass data={Flowchart.over(states, { … })}, or bind a record of flows as \`record\``);
500
- }
306
+ const given = props;
307
+ for (const [prop, remedy] of Object.entries(REMOVED)) {
308
+ if (prop in given)
309
+ throw new Error(`Flowchart: \`${prop}\` is gone — ${remedy}`);
501
310
  }
502
- for (const size of SIZES) {
503
- if (size in canvas) {
504
- throw new Error(`Flowchart: \`${size}\` is not a prop — the flowchart fills the box it is given; give it a box of its own height: <Box height="560px"><Flowchart … /></Box>`);
311
+ for (const prop of Object.keys(given)) {
312
+ if (!PROPS.has(prop) && !(prop === "children" && given[prop] === undefined)) {
313
+ throw new Error(`Flowchart: \`${prop}\` is not a prop of <Flowchart> — it takes ${[...PROPS].join(", ")}`);
505
314
  }
506
315
  }
507
- if ("density" in canvas)
508
- throw new Error(DENSITY);
509
- for (const callback of EDIT_CALLBACKS) {
510
- if (callback in canvas) {
511
- throw new Error(`Flowchart: \`${callback}\` is not a prop — every gesture is a transaction of the flowchart's editing session, and Save commits them as one patch: over \`record\`, through its patch mutation; over \`data\`, through the host's \`onApply\``);
512
- }
316
+ // The kinds (R1): the states, and beside them the transitions, the lanes and the decisions.
317
+ const states = kindOf("states", given.states);
318
+ if (states === undefined)
319
+ throw new Error(`Flowchart: needs its states — states={${DECLARE.states}}, over the app's record`);
320
+ const transitions = kindOf("transitions", given.transitions);
321
+ const lanes = kindOf("lanes", given.lanes);
322
+ const decisions = kindOf("decisions", given.decisions);
323
+ // A role naming another kind's key needs that kind (R3).
324
+ if (states.lane && lanes === undefined) {
325
+ throw new Error("Flowchart: a state's lane names a lane — give lanes={Flowchart.lanes(…)}, or drop lane");
513
326
  }
514
- for (const [hover, remedy] of Object.entries(HOVERS)) {
515
- if (hover in canvas) {
516
- throw new Error(`Flowchart: \`${hover}\` is not a prop — the hover cards went, and the inspector, on by default, shows what is selected: ${remedy}`);
517
- }
327
+ if (lanes !== undefined && !states.lane) {
328
+ throw new Error("Flowchart: the lanes are columns: give the states their lane — Flowchart.states(record, { label, lane })");
329
+ }
330
+ if (transitions?.decision === true && decisions === undefined) {
331
+ throw new Error("Flowchart: a transition's decision names a decision — give decisions={Flowchart.decisions(…)}, or drop decision");
332
+ }
333
+ const kinds = [
334
+ { sort: "states", kind: states },
335
+ ...(transitions === undefined ? [] : [{ sort: "transitions", kind: transitions }]),
336
+ ...(lanes === undefined ? [] : [{ sort: "lanes", kind: lanes }]),
337
+ ...(decisions === undefined ? [] : [{ sort: "decisions", kind: decisions }]),
338
+ ];
339
+ // The narrowing (R4): one Slice.bindRecords, its states and transitions sources each named after its kind.
340
+ const slice = given.slice;
341
+ if (slice !== undefined && (slice instanceof Expr || typeof slice !== "object" || slice === null || !("slice" in slice))) {
342
+ throw new Error("Flowchart: `slice` takes { slice } — slice={{ slice: Slice.bindRecords(key, { … }), affordances?, persist? }}, " +
343
+ "its sources `states` and `transitions` each named after the kind it narrows");
518
344
  }
519
- // The narrowing's props #1346 retired, each refused by name for an app that still passes it.
520
- if (window !== undefined)
521
- throw new Error(WINDOW);
522
- if ("affordances" in canvas)
523
- throw new Error("Flowchart: `affordances` moved into `slice` — slice={{ slice, affordances }}");
524
- if (slice !== undefined && (slice instanceof Expr || typeof slice !== "object" || slice === null || !("slice" in slice)))
525
- throw new Error(SLICE);
526
345
  const narrowing = slice;
527
346
  if (narrowing?.affordances?.includes("brush") === true) {
528
347
  throw new Error("Flowchart: `slice`'s affordances list \"brush\", and a flowchart has no continuous axis to brush along — mount fields, search, presets or summary");
529
348
  }
530
- if (record !== undefined && data !== undefined) {
531
- throw new Error("Flowchart: takes its flows from `record` or from `data`, never both");
349
+ const sliceNames = sliceSourceNames(narrowing);
350
+ for (const whole of ["lanes", "decisions"]) {
351
+ if (sliceNames.includes(whole))
352
+ throw new Error(`Flowchart: the ${whole} are read whole: drop the ${whole} source`);
532
353
  }
533
- if (record === undefined && data === undefined) {
534
- throw new Error("Flowchart: needs its flows — `record`, an e3 record of Flowchart.Types.Flows bound with its patch mutation, or `data`: flows by name or one flow, as a value, an expression or a bind handle");
354
+ // Each kind's cards are a record of their own, their list naming its source of the slice — refused with the change
355
+ // to make before a source no list names is.
356
+ const cardSources = [];
357
+ if (narrowing === undefined || isRecordSlices(narrowing.slice)) {
358
+ for (const { sort, kind } of kinds) {
359
+ if (!kind.hasTemplates)
360
+ continue;
361
+ const source = templatesSource("Flowchart", "Flowchart.templates(rows, { …, source })", kind.templatesSource, sliceNames);
362
+ if (source === "states" || source === "transitions") {
363
+ throw new Error(`Flowchart: the ${sort}' cards name the source '${source}', which narrows the ${source} — ` +
364
+ "a kind's cards are a record of their own, and their own source of the slice");
365
+ }
366
+ cardSources.push(source);
367
+ }
535
368
  }
536
- if (record !== undefined && onApply !== undefined) {
537
- throw new Error("Flowchart: `onApply` commits `data`'s edits — a flowchart over `record` commits through the record's patch mutation; leave `onApply` out");
369
+ // The details the rail's picks weigh (#1522, R44): each names a source of the slice over the details' own record.
370
+ const weighing = [];
371
+ if (narrowing === undefined || isRecordSlices(narrowing.slice)) {
372
+ for (const { sort, kind } of kinds) {
373
+ const by = sort === "states" || sort === "transitions" ? kind.weighedBy : undefined;
374
+ if (by === undefined)
375
+ continue;
376
+ if (by.source === "states" || by.source === "transitions") {
377
+ throw new Error(`Flowchart: the ${sort}' details name the source '${by.source}', which narrows the ${by.source} — the picks that ` +
378
+ "weigh details are a source of the slice over the details' own record");
379
+ }
380
+ if (narrowing === undefined || !sliceNames.includes(by.source)) {
381
+ throw new Error(`Flowchart: the ${sort}' details name the source '${by.source}', ` +
382
+ `${narrowing === undefined ? "and the Flowchart has no slice" : `which is none of the slice's sources (${sliceNames.join(", ")})`} — ` +
383
+ `slice={{ slice: Slice.bindRecords(key, { …, ${by.source}: { source: Data.bindPaged(record, { indexes }), fields } }) }}`);
384
+ }
385
+ const rows = sliceSourceRows(narrowing, by.source);
386
+ if (rows !== undefined && !isTypeEqual(rows, by.rowType)) {
387
+ throw new Error(`Flowchart: the ${sort}' details name the source '${by.source}', whose rows are ${typeText(rows)} — and the details' ` +
388
+ `are ${typeText(by.rowType)}: name the source over the details' record`);
389
+ }
390
+ weighing.push(by.source);
391
+ }
538
392
  }
539
- // Templates are records (#1340, ruling 9): each list names its source of the slice, and a list written in the code
540
- // names none — refused before a source no list names is, so the refusal says the change to make. A slice of
541
- // another kind is refused below, as such.
542
- if (narrowing === undefined || isRecordSlices(narrowing.slice))
543
- checkTemplatesSources(library, sliceSourceNames(narrowing));
544
- // The slice's sources: its flows, and each a templates list or a tab names.
545
- const named = librarySources(library);
393
+ const tabSources = flowchartTabSources(given.library);
394
+ const names = [...new Set(["states", ...(transitions === undefined ? [] : ["transitions"]), ...cardSources, ...tabSources, ...weighing])];
546
395
  const sources = recordSources(narrowing, {
547
- builder: "Flowchart", names: ["flows", ...named.filter((source) => source !== "flows")], what: NARROWS,
548
- takes: (source) => source === "flows" || named.includes(source),
396
+ builder: "Flowchart", names,
397
+ what: "its states and its transitions, each by the source named after it, and the cards lists, tabs and details that name a source",
398
+ });
399
+ const library = buildFlowchartLibrary(given.library, {
400
+ kinds: kinds.map(({ sort, kind }) => ({ sort, rowType: kind.rowType, templates: kind.hasTemplates })),
401
+ sources: sources.names,
549
402
  });
550
- const pagesFlows = sources.names.includes("flows");
551
- if (pagesFlows && record === undefined) {
552
- throw new Error("Flowchart: `slice`'s `flows` source pages a record of flows, and these flows are the host's, which nothing narrows — bind the record as record={Record.bind(record), its record declaring patch: mutation.patch()}, or leave `flows` out of the slice");
403
+ const inspector = inspectorOf(given.inspector);
404
+ // A details' read shown in the inspector alone is drawn nowhere without its pane (#1507).
405
+ if (!inspector && (states.inspectorReads || transitions?.inspectorReads === true)) {
406
+ throw new Error("Flowchart: the inspector's reads have no pane — drop inspector={false}, or show them on the canvas");
553
407
  }
408
+ const vocabulary = flowchartVocabulary(given.vocabulary);
409
+ const narrowed = narrowedOf(given.narrowed);
410
+ const name = given.name;
411
+ if (name !== undefined && (typeof name !== "string" || name === "")) {
412
+ throw new Error("Flowchart: `name` keeps the Flowchart's state apart — a string, needed only when one surface holds two");
413
+ }
414
+ const canvas = buildCanvas(Object.fromEntries(CANVAS.filter((prop) => given[prop] !== undefined).map((prop) => [prop, given[prop]])));
554
415
  return Expr.block(($) => {
416
+ // Each source bound once: a kind reads its own source inside its functions.
555
417
  const bound = sources.bind($);
556
- const narrowed = East.value(new Map(Object.entries(bound.keys)), NarrowedType);
557
- const arm = pagesFlows ? pagedArm(record, { part: bound.parts["flows"], rows: bound.data["flows"] })
558
- : record !== undefined ? recordArm(record) : dataArm(data, onApply);
559
- if (flow !== undefined && !arm.many) {
560
- throw new Error("Flowchart: `flow` opens one of many flows first, and this `data` is one flow, Flowchart.Types.Flow — leave `flow` out");
561
- }
418
+ const shown = East.value(new Map(Object.entries(bound.keys)), ShownType);
419
+ // Dimmed, a kind read through its source reads every row: the renderer draws what the narrowing leaves out as context.
562
420
  return East.value({
563
- canvas: buildCanvas(canvas),
564
- source: arm.source,
565
- open: flow === undefined ? none : some(flow),
566
- library: buildLibrary(library, arm.many, sources.names),
421
+ canvas,
422
+ states: states.build(bound.parts["states"], narrowed.dim),
423
+ transitions: transitions === undefined ? none : some(transitions.build(bound.parts["transitions"], narrowed.dim)),
424
+ lanes: lanes === undefined ? none : some(lanes.build(undefined, false)),
425
+ decisions: decisions === undefined ? none : some(decisions.build(undefined, false)),
426
+ library,
567
427
  slice: sources.chrome,
568
- narrowed,
569
- inspector: inspectorOf(inspector),
570
- readOnly: readOnly ?? false,
428
+ shown,
429
+ narrowed: narrowed.wire,
430
+ inspector,
431
+ vocabulary,
432
+ readOnly: given.readOnly ?? false,
571
433
  name: name === undefined ? none : some(name),
572
434
  }, FlowchartPayloadType);
573
435
  });