@jxsuite/studio 6.1.1 → 6.1.2

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 (637) hide show
  1. package/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
  2. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  3. package/dist/chunks/adapter-4912g339.js +4 -0
  4. package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
  5. package/dist/chunks/cf-settings-br6105tr.js +4 -0
  6. package/dist/chunks/color-28ksk2qm.js +4 -0
  7. package/dist/chunks/color-area-0fj8a4ga.js +4 -0
  8. package/dist/chunks/color-field-xch8kx2g.js +4 -0
  9. package/dist/chunks/color-slider-jxd8v350.js +4 -0
  10. package/dist/chunks/combobox-p0efwjke.js +4 -0
  11. package/dist/chunks/components-db68vsn7.js +4 -0
  12. package/dist/chunks/content-source-1449qesq.js +4 -0
  13. package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
  14. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  15. package/dist/chunks/editor-x9jn86a7.js +4 -0
  16. package/dist/chunks/entry-commands-may24cpt.js +4 -0
  17. package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
  18. package/dist/chunks/file-ops-x9v54pcj.js +4 -0
  19. package/dist/chunks/files-j3knqf0s.js +4 -0
  20. package/dist/chunks/format-host-tyre2trb.js +4 -0
  21. package/dist/chunks/fs-events-64ma9htc.js +4 -0
  22. package/dist/chunks/git-panel-84ps5dex.js +4 -0
  23. package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
  24. package/dist/chunks/icons-pnfz478q.js +4 -0
  25. package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
  26. package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
  27. package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
  28. package/dist/chunks/iframe-entry-zap785cw.js +5 -0
  29. package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
  30. package/dist/chunks/index-b8xw3vy9.js +4 -0
  31. package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
  32. package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
  33. package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
  34. package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
  35. package/dist/chunks/layers-h4xp1pss.js +4 -0
  36. package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
  37. package/dist/chunks/listbox-e74qjyq6.js +4 -0
  38. package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
  39. package/dist/chunks/media-picker-2cweexc5.js +4 -0
  40. package/dist/chunks/menu-n6yzswmy.js +4 -0
  41. package/dist/chunks/menu-ynw13y0s.js +4 -0
  42. package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
  43. package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
  44. package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
  45. package/dist/chunks/notify-cj5zbrs2.js +4 -0
  46. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  47. package/dist/chunks/parse-b7ddhr8m.js +4 -0
  48. package/dist/chunks/platform-3dfws9js.js +4 -0
  49. package/dist/chunks/popover-jt2gxmzs.js +4 -0
  50. package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
  51. package/dist/chunks/quick-search-0dajrwqg.js +4 -0
  52. package/dist/chunks/references-49qgt404.js +4 -0
  53. package/dist/chunks/right-panel-jm1bwe53.js +4 -0
  54. package/dist/chunks/section-registry-6kwc4fky.js +4 -0
  55. package/dist/chunks/select-rzds841e.js +4 -0
  56. package/dist/chunks/split-n2gfpm5m.js +4 -0
  57. package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
  58. package/dist/chunks/studio-0rt52vpq.js +5 -0
  59. package/dist/chunks/studio-18vgbhs5.js +5 -0
  60. package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
  61. package/dist/chunks/studio-24mccdrj.js +5 -0
  62. package/dist/chunks/studio-2eh507zk.js +9 -0
  63. package/dist/chunks/studio-2hcbccfv.js +5 -0
  64. package/dist/chunks/studio-2j1cb95x.js +5 -0
  65. package/dist/chunks/studio-2jbs3rxv.js +5 -0
  66. package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
  67. package/dist/chunks/studio-4h8k4dw9.js +5 -0
  68. package/dist/chunks/studio-5f6n18kx.js +5 -0
  69. package/dist/chunks/studio-5gthpky6.js +5 -0
  70. package/dist/chunks/studio-5ve6bbep.js +5 -0
  71. package/dist/chunks/studio-6ep3js6b.js +9 -0
  72. package/dist/chunks/studio-6wkmf3wz.js +9 -0
  73. package/dist/chunks/studio-841rf3cg.js +5 -0
  74. package/dist/chunks/studio-8gmwgheg.js +5 -0
  75. package/dist/chunks/studio-8qm0ep50.js +5 -0
  76. package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
  77. package/dist/chunks/studio-924p1tm1.js +6 -0
  78. package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
  79. package/dist/chunks/studio-a3shpz9y.js +5 -0
  80. package/dist/chunks/studio-amsbaaar.js +6 -0
  81. package/dist/chunks/studio-at5spjbc.js +7 -0
  82. package/dist/chunks/studio-b2xv945e.js +5 -0
  83. package/dist/chunks/studio-bn5nkafw.js +5 -0
  84. package/dist/chunks/studio-bw6q5xjf.js +9 -0
  85. package/dist/chunks/studio-c7q0t9x1.js +5 -0
  86. package/dist/chunks/studio-camnhc96.js +6 -0
  87. package/dist/chunks/studio-cffqvnzd.js +5 -0
  88. package/dist/chunks/studio-d81xfh1g.js +5 -0
  89. package/dist/chunks/studio-dgz8d0c1.js +5 -0
  90. package/dist/chunks/studio-efvfrsf8.js +5 -0
  91. package/dist/chunks/studio-er30bpcx.js +5 -0
  92. package/dist/chunks/studio-ezscgr64.js +5 -0
  93. package/dist/chunks/studio-ffrrncvz.js +5 -0
  94. package/dist/chunks/studio-fpphgn8y.js +10 -0
  95. package/dist/chunks/studio-j1kvhdjk.js +4 -0
  96. package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
  97. package/dist/chunks/studio-jjkg84nj.js +5 -0
  98. package/dist/chunks/studio-m0q32ars.js +4 -0
  99. package/dist/chunks/studio-m6bdst11.js +5 -0
  100. package/dist/chunks/studio-nv2cptd4.js +64 -0
  101. package/dist/chunks/studio-nwfrc98n.js +5 -0
  102. package/dist/chunks/studio-p1wgvp7r.js +5 -0
  103. package/dist/chunks/studio-pag2wncm.js +5 -0
  104. package/dist/chunks/studio-qvanvzfd.js +5 -0
  105. package/dist/chunks/studio-qwa64kt7.js +5 -0
  106. package/dist/chunks/studio-rk1zc4x3.js +928 -0
  107. package/dist/chunks/studio-se2r3ptc.js +5 -0
  108. package/dist/chunks/studio-sg2a0dh0.js +5 -0
  109. package/dist/chunks/studio-tjzjhe68.js +5 -0
  110. package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
  111. package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
  112. package/dist/chunks/studio-v2w7q8r1.js +7 -0
  113. package/dist/chunks/studio-v5vjq1h0.js +4 -0
  114. package/dist/chunks/studio-v8aga3vp.js +14 -0
  115. package/dist/chunks/studio-vfcdrfmv.js +5 -0
  116. package/dist/chunks/studio-vmfkgdjf.js +5 -0
  117. package/dist/chunks/studio-wt1816jj.js +5 -0
  118. package/dist/chunks/studio-wz73q5kq.js +4 -0
  119. package/dist/chunks/studio-y04qtxvp.js +7 -0
  120. package/dist/chunks/studio-y21g8zzg.js +5 -0
  121. package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
  122. package/dist/chunks/studio-ynn90f58.js +16 -0
  123. package/dist/chunks/studio-yxz682sx.js +5 -0
  124. package/dist/chunks/studio-zp7snvkq.js +5 -0
  125. package/dist/chunks/studio-zq4z6tm6.js +5 -0
  126. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  127. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  128. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  129. package/dist/chunks/toast-c9fn075p.js +4 -0
  130. package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
  131. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  132. package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
  133. package/dist/chunks/tree-mdq3v5cw.js +4 -0
  134. package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
  135. package/dist/chunks/workspace-jtfahpee.js +4 -0
  136. package/dist/chunks/ws-client-nze0k6mv.js +4 -0
  137. package/dist/iframe-entry.js +16 -16
  138. package/dist/manifest.json +63 -63
  139. package/dist/studio.js +97 -97
  140. package/package.json +6 -6
  141. package/src/about/about-modal.ts +4 -3
  142. package/src/account/action-flow.ts +45 -38
  143. package/src/account-status.ts +7 -2
  144. package/src/browse/library-layouts.ts +8 -5
  145. package/src/browse/library-model.ts +18 -6
  146. package/src/browse/library-pane.ts +37 -21
  147. package/src/browse/library-preview.ts +14 -9
  148. package/src/browse/library-source.ts +1 -1
  149. package/src/canvas/asset-refs.ts +24 -9
  150. package/src/canvas/asset-resolve.ts +19 -23
  151. package/src/canvas/canvas-helpers.ts +7 -6
  152. package/src/canvas/canvas-live-render.ts +44 -53
  153. package/src/canvas/canvas-patcher.ts +30 -30
  154. package/src/canvas/canvas-perf.ts +11 -5
  155. package/src/canvas/canvas-render.ts +62 -41
  156. package/src/canvas/canvas-surface.ts +5 -3
  157. package/src/canvas/canvas-utils.ts +90 -49
  158. package/src/canvas/dialog-path.ts +9 -4
  159. package/src/canvas/dialog-state.ts +1 -2
  160. package/src/canvas/diff-marks.ts +9 -16
  161. package/src/canvas/diff-toolbar.ts +8 -7
  162. package/src/canvas/edit-width-drag.ts +4 -1
  163. package/src/canvas/edit-width.ts +1 -3
  164. package/src/canvas/iframe-channel.ts +27 -13
  165. package/src/canvas/iframe-drop.ts +13 -12
  166. package/src/canvas/iframe-editable-root.ts +29 -16
  167. package/src/canvas/iframe-entry.ts +80 -63
  168. package/src/canvas/iframe-eval.ts +73 -49
  169. package/src/canvas/iframe-host.ts +135 -96
  170. package/src/canvas/iframe-inline-edit.ts +49 -30
  171. package/src/canvas/iframe-insert.ts +5 -4
  172. package/src/canvas/iframe-interaction.ts +30 -25
  173. package/src/canvas/iframe-overlay.ts +1 -1
  174. package/src/canvas/iframe-patch.ts +18 -15
  175. package/src/canvas/iframe-position.ts +12 -6
  176. package/src/canvas/iframe-protocol.ts +12 -16
  177. package/src/canvas/iframe-render.ts +36 -34
  178. package/src/canvas/iframe-slash.ts +24 -11
  179. package/src/canvas/iframe-subtree.ts +6 -2
  180. package/src/canvas/path-mapping.ts +19 -12
  181. package/src/canvas/popover-path.ts +7 -3
  182. package/src/canvas/popover-state.ts +1 -2
  183. package/src/canvas/serialize-scope.ts +13 -5
  184. package/src/canvas/stage-scrollbar.ts +2 -1
  185. package/src/canvas/surface-registry.ts +21 -3
  186. package/src/collab/collab-commands.ts +7 -2
  187. package/src/collab/collab-session.ts +84 -45
  188. package/src/collab/collab-state.ts +4 -3
  189. package/src/collab/monaco-binding.ts +16 -13
  190. package/src/collab/monaco-cursors.ts +5 -2
  191. package/src/commands/budget.ts +3 -3
  192. package/src/commands/command-args.ts +103 -71
  193. package/src/commands/context.ts +22 -20
  194. package/src/commands/keymap.ts +47 -43
  195. package/src/commands/levels.ts +3 -3
  196. package/src/commands/live-context.ts +7 -7
  197. package/src/commands/reference.ts +2 -1
  198. package/src/commands/registry.ts +12 -10
  199. package/src/commands/run-reported.ts +15 -10
  200. package/src/component-props.ts +46 -30
  201. package/src/content/collection-match.ts +5 -4
  202. package/src/content/draft-state.ts +4 -3
  203. package/src/content/entry-commands.ts +3 -2
  204. package/src/content/entry-editor.ts +29 -17
  205. package/src/content/entry-fields.ts +12 -7
  206. package/src/content/entry-model.ts +21 -12
  207. package/src/editor/canvas-context-menu.ts +1 -2
  208. package/src/editor/canvas-slash-bridge.ts +3 -6
  209. package/src/editor/content-slice.ts +16 -14
  210. package/src/editor/context-menu.ts +35 -22
  211. package/src/editor/convert-targets.ts +30 -35
  212. package/src/editor/convert-to-component.ts +11 -5
  213. package/src/editor/convert-to-repeater.ts +34 -22
  214. package/src/editor/editable-tags.ts +17 -2
  215. package/src/editor/file-drop-action.ts +21 -22
  216. package/src/editor/inline-edit-apply.ts +35 -17
  217. package/src/editor/inline-edit.ts +66 -50
  218. package/src/editor/inline-format.ts +59 -56
  219. package/src/editor/inline-link.ts +40 -15
  220. package/src/editor/insert-zone-action.ts +1 -1
  221. package/src/editor/merge-tags.ts +58 -19
  222. package/src/editor/repeater-scope.ts +39 -28
  223. package/src/editor/shortcuts.ts +32 -20
  224. package/src/editor/slash-menu.ts +1 -6
  225. package/src/files/asset-versions.ts +4 -4
  226. package/src/files/components.ts +15 -10
  227. package/src/files/elements.ts +5 -6
  228. package/src/files/file-ops.ts +77 -36
  229. package/src/files/files.ts +90 -95
  230. package/src/files/media-meta.ts +2 -1
  231. package/src/files/media-paths.ts +3 -0
  232. package/src/files/serialize-document.ts +2 -2
  233. package/src/format/constraints.ts +1 -1
  234. package/src/format/convert-file.ts +27 -13
  235. package/src/format/format-choices.ts +2 -1
  236. package/src/format/format-host.ts +76 -50
  237. package/src/github/github-auth-status.ts +27 -3
  238. package/src/github/github-auth.ts +19 -9
  239. package/src/github/github-publish.ts +24 -20
  240. package/src/grid/cell-editors.ts +46 -31
  241. package/src/grid/cell-popovers.ts +5 -3
  242. package/src/grid/edit-buffer.ts +10 -9
  243. package/src/grid/grid-controller.ts +20 -22
  244. package/src/grid/grid-layout.ts +21 -5
  245. package/src/grid/grid-open.ts +3 -6
  246. package/src/grid/grid-panel.ts +11 -4
  247. package/src/grid/grid-source.ts +8 -8
  248. package/src/grid/grid-view.ts +14 -17
  249. package/src/grid/redirects-grid.ts +14 -5
  250. package/src/grid/redirects.ts +16 -14
  251. package/src/grid/schema-columns.ts +25 -19
  252. package/src/grid/sources/connector-source.ts +47 -20
  253. package/src/grid/sources/content-source.ts +25 -24
  254. package/src/grid/sources/csv-file-source.ts +2 -2
  255. package/src/grid/tabulator-tables.d.ts +55 -34
  256. package/src/hosting/stage.ts +7 -7
  257. package/src/i18n/i18n-commands.ts +1 -2
  258. package/src/media/media-pane.ts +4 -1
  259. package/src/new-project/add-repo-modal.ts +20 -19
  260. package/src/new-project/import-tab.ts +10 -14
  261. package/src/new-project/location-fields.ts +2 -1
  262. package/src/new-project/new-project-modal.ts +12 -9
  263. package/src/packages/jxsuite-update.ts +4 -3
  264. package/src/packages/pull-package-sync.ts +26 -25
  265. package/src/page-params.ts +97 -68
  266. package/src/panels/activity-panel.ts +17 -9
  267. package/src/panels/ai-chat/attached-context.ts +13 -7
  268. package/src/panels/ai-chat/chat-view.ts +80 -73
  269. package/src/panels/ai-chat/composer.ts +30 -33
  270. package/src/panels/ai-chat/sessions-view.ts +1 -2
  271. package/src/panels/ai-panel.ts +23 -20
  272. package/src/panels/block-action-bar.ts +46 -35
  273. package/src/panels/bottom-dock.ts +5 -3
  274. package/src/panels/canvas-dnd-bridge.ts +31 -24
  275. package/src/panels/data-explorer.ts +62 -25
  276. package/src/panels/data-grid.ts +14 -11
  277. package/src/panels/dnd.ts +108 -118
  278. package/src/panels/editors.ts +52 -21
  279. package/src/panels/elements-panel.ts +10 -3
  280. package/src/panels/events-panel.ts +84 -69
  281. package/src/panels/formula-workspace.ts +76 -51
  282. package/src/panels/frontmatter-fields.ts +24 -19
  283. package/src/panels/frontmatter-panel.ts +44 -34
  284. package/src/panels/git-diff-open.ts +4 -4
  285. package/src/panels/git-panel.ts +49 -61
  286. package/src/panels/head-panel.ts +131 -111
  287. package/src/panels/i18n-panel.ts +10 -3
  288. package/src/panels/imports-panel.ts +23 -47
  289. package/src/panels/jump-bar.ts +48 -29
  290. package/src/panels/layers-panel.ts +97 -74
  291. package/src/panels/left-panel.ts +3 -3
  292. package/src/panels/pane-context.ts +31 -22
  293. package/src/panels/pane-grid.ts +49 -20
  294. package/src/panels/panel-registry.ts +22 -37
  295. package/src/panels/properties-panel.ts +175 -121
  296. package/src/panels/quick-search.ts +53 -31
  297. package/src/panels/right-panel.ts +3 -3
  298. package/src/panels/seo-modal.ts +13 -17
  299. package/src/panels/settings-menu.ts +15 -15
  300. package/src/panels/signals-panel.ts +153 -131
  301. package/src/panels/statement-editor.ts +230 -140
  302. package/src/panels/style-panel.ts +218 -205
  303. package/src/panels/style-utils.ts +114 -51
  304. package/src/panels/stylebook-doc.ts +57 -54
  305. package/src/panels/stylebook-layers-panel.ts +9 -9
  306. package/src/panels/stylebook-panel.ts +13 -17
  307. package/src/panels/tab-drop.ts +27 -11
  308. package/src/panels/tab-strip.ts +36 -26
  309. package/src/platform-errors.ts +57 -43
  310. package/src/platform.ts +58 -30
  311. package/src/platforms/cloud.ts +345 -175
  312. package/src/platforms/default-platform.ts +10 -4
  313. package/src/platforms/devserver.ts +129 -117
  314. package/src/platforms/read-batcher.ts +16 -8
  315. package/src/project-list.ts +2 -1
  316. package/src/publish/deploy-checklist.ts +8 -2
  317. package/src/publish/pages-service.ts +28 -13
  318. package/src/publish/publish-commands.ts +5 -4
  319. package/src/publish/publish-panel.ts +10 -6
  320. package/src/recent-projects.ts +15 -8
  321. package/src/resize-edges.ts +26 -36
  322. package/src/services/a11y-report.ts +26 -19
  323. package/src/services/agent-seed.ts +23 -11
  324. package/src/services/ai-ask.ts +9 -12
  325. package/src/services/ai-command-tools.ts +68 -62
  326. package/src/services/ai-import-tools.ts +80 -67
  327. package/src/services/ai-models.ts +17 -13
  328. package/src/services/ai-project-tools.ts +68 -32
  329. package/src/services/ai-session-store.ts +19 -10
  330. package/src/services/ai-system-prompt.ts +46 -20
  331. package/src/services/ai-tools.ts +71 -27
  332. package/src/services/ai-write-report.ts +20 -12
  333. package/src/services/ai-writes.ts +4 -4
  334. package/src/services/automation.ts +58 -31
  335. package/src/services/cem-export.ts +149 -58
  336. package/src/services/clock.ts +6 -1
  337. package/src/services/code-services.ts +37 -31
  338. package/src/services/context-manager.ts +14 -10
  339. package/src/services/context-resolver.ts +20 -8
  340. package/src/services/data-service.ts +19 -15
  341. package/src/services/directory-picker.ts +18 -12
  342. package/src/services/document-assistant.ts +39 -19
  343. package/src/services/gated-registry.ts +10 -6
  344. package/src/services/harness/chat-reducer.ts +23 -1
  345. package/src/services/import-client.ts +91 -38
  346. package/src/services/import-seed.ts +8 -2
  347. package/src/services/jx-validate.ts +28 -31
  348. package/src/services/live-preview.ts +0 -0
  349. package/src/services/live-surfaces.ts +6 -3
  350. package/src/services/model-uri.ts +10 -2
  351. package/src/services/module-preloads.ts +12 -8
  352. package/src/services/monaco-buffer.ts +43 -24
  353. package/src/services/monaco-lazy.ts +7 -8
  354. package/src/services/monaco-setup.ts +23 -16
  355. package/src/services/notify.ts +44 -17
  356. package/src/services/popover-report.ts +25 -10
  357. package/src/services/preview-eval.ts +20 -8
  358. package/src/services/profile.ts +13 -6
  359. package/src/services/project-path.ts +13 -10
  360. package/src/services/references.ts +0 -0
  361. package/src/services/render-critic.ts +8 -7
  362. package/src/services/settings/kernel.ts +13 -4
  363. package/src/services/settings/write-queue.ts +9 -9
  364. package/src/services/token-lint.ts +12 -10
  365. package/src/services/tool-executor.ts +17 -5
  366. package/src/services/tool-outcomes.ts +44 -24
  367. package/src/services/trusted-types.ts +24 -7
  368. package/src/settings/contexts-section.ts +11 -8
  369. package/src/settings/contributed-section.ts +79 -60
  370. package/src/settings/css-vars-editor.ts +37 -16
  371. package/src/settings/defs-editor.ts +38 -35
  372. package/src/settings/extension-rows.ts +16 -8
  373. package/src/settings/extension-sections.ts +23 -13
  374. package/src/settings/extensions-section.ts +4 -1
  375. package/src/settings/general-settings.ts +11 -8
  376. package/src/settings/locales-section.ts +20 -12
  377. package/src/settings/preferences-dialog.ts +9 -6
  378. package/src/settings/preferences-keymap.ts +7 -5
  379. package/src/settings/preferences-sections.ts +11 -5
  380. package/src/settings/project-sections.ts +1 -1
  381. package/src/settings/schema-field-ui.ts +9 -0
  382. package/src/settings/settings-document.ts +5 -5
  383. package/src/shell/tree.ts +6 -5
  384. package/src/shell.ts +104 -81
  385. package/src/site-context.ts +37 -22
  386. package/src/state.ts +41 -49
  387. package/src/store.ts +54 -34
  388. package/src/studio.ts +25 -75
  389. package/src/style/live-preview.ts +1 -1
  390. package/src/style/project-styles.ts +6 -7
  391. package/src/style/token-ref.ts +5 -4
  392. package/src/surfaces/about.ts +18 -19
  393. package/src/surfaces/add-repo.ts +17 -19
  394. package/src/surfaces/ai-chat.ts +31 -36
  395. package/src/surfaces/ai-credentials-form.ts +6 -16
  396. package/src/surfaces/ai-managed-connect.ts +3 -4
  397. package/src/surfaces/ai-model-picker.ts +3 -5
  398. package/src/surfaces/block-action-bar.ts +22 -11
  399. package/src/surfaces/boot-failure.ts +4 -5
  400. package/src/surfaces/bottom-dock.ts +9 -18
  401. package/src/surfaces/canvas-stage.ts +12 -11
  402. package/src/surfaces/cf-account-picker.ts +17 -18
  403. package/src/surfaces/commandbar.ts +14 -9
  404. package/src/surfaces/convert-repeater.ts +17 -19
  405. package/src/surfaces/data-actions.ts +9 -7
  406. package/src/surfaces/dialog.ts +26 -28
  407. package/src/surfaces/diff-toolbar.ts +9 -7
  408. package/src/surfaces/doc-header.ts +10 -19
  409. package/src/surfaces/empty-state.ts +7 -10
  410. package/src/surfaces/entry-editor.ts +14 -11
  411. package/src/surfaces/expression-editor.ts +11 -25
  412. package/src/surfaces/files-panel.ts +27 -14
  413. package/src/surfaces/formula-palette.ts +4 -5
  414. package/src/surfaces/git-panel.ts +7 -15
  415. package/src/surfaces/github-auth.ts +16 -20
  416. package/src/surfaces/github-publish.ts +17 -22
  417. package/src/surfaces/grid-cell.ts +30 -31
  418. package/src/surfaces/grid-open.ts +10 -14
  419. package/src/surfaces/grid-panel.ts +13 -9
  420. package/src/surfaces/grid-replace.ts +13 -13
  421. package/src/surfaces/grid-views.ts +15 -18
  422. package/src/surfaces/inspector-dock.ts +13 -12
  423. package/src/surfaces/jump-bar.ts +5 -6
  424. package/src/surfaces/jxsuite-update.ts +16 -22
  425. package/src/surfaces/library-pane.ts +19 -20
  426. package/src/surfaces/logic-panel.ts +17 -30
  427. package/src/surfaces/logic-workspace.ts +13 -15
  428. package/src/surfaces/media-browser.ts +11 -10
  429. package/src/surfaces/media-field.ts +4 -5
  430. package/src/surfaces/media-pane.ts +8 -7
  431. package/src/surfaces/menu.ts +29 -23
  432. package/src/surfaces/navigator-dock.ts +11 -12
  433. package/src/surfaces/new-project.ts +27 -26
  434. package/src/surfaces/pane-context.ts +20 -25
  435. package/src/surfaces/pane-grid.ts +15 -10
  436. package/src/surfaces/panel-activity.ts +5 -6
  437. package/src/surfaces/panel-data.ts +3 -4
  438. package/src/surfaces/panel-deploy-checklist.ts +5 -6
  439. package/src/surfaces/panel-elements.ts +5 -7
  440. package/src/surfaces/panel-i18n.ts +5 -7
  441. package/src/surfaces/panel-imports.ts +6 -13
  442. package/src/surfaces/panel-outline.ts +25 -19
  443. package/src/surfaces/panel-page.ts +11 -18
  444. package/src/surfaces/panel-problems.ts +5 -7
  445. package/src/surfaces/panel-signals.ts +20 -34
  446. package/src/surfaces/panel-stylebook-layers.ts +5 -8
  447. package/src/surfaces/preferences.ts +21 -11
  448. package/src/surfaces/progress-modal.ts +15 -9
  449. package/src/surfaces/properties-panel.json +1 -1
  450. package/src/surfaces/properties-panel.ts +20 -42
  451. package/src/surfaces/publish.ts +18 -18
  452. package/src/surfaces/push-plan.ts +7 -8
  453. package/src/surfaces/rail.ts +13 -13
  454. package/src/surfaces/reference-field.ts +11 -15
  455. package/src/surfaces/schema-builder.ts +16 -22
  456. package/src/surfaces/schema-form.ts +15 -25
  457. package/src/surfaces/secret-field.ts +9 -6
  458. package/src/surfaces/seo.ts +21 -15
  459. package/src/surfaces/settings-contexts.ts +9 -7
  460. package/src/surfaces/settings-contributed.ts +14 -10
  461. package/src/surfaces/settings-css-vars.ts +5 -12
  462. package/src/surfaces/settings-defs.json +2 -2
  463. package/src/surfaces/settings-defs.ts +17 -21
  464. package/src/surfaces/settings-deploy.ts +8 -15
  465. package/src/surfaces/settings-extensions.ts +5 -6
  466. package/src/surfaces/settings-head.ts +33 -39
  467. package/src/surfaces/settings-locales.ts +8 -20
  468. package/src/surfaces/settings-overview.ts +5 -6
  469. package/src/surfaces/settings-packages.ts +8 -7
  470. package/src/surfaces/settings-pane.ts +9 -18
  471. package/src/surfaces/settings-rawjson.ts +5 -6
  472. package/src/surfaces/shell.ts +1 -2
  473. package/src/surfaces/slash-menu.ts +19 -9
  474. package/src/surfaces/statements.ts +13 -18
  475. package/src/surfaces/statusbar.ts +17 -14
  476. package/src/surfaces/style-panel.ts +18 -31
  477. package/src/surfaces/stylebook-chrome.ts +3 -5
  478. package/src/surfaces/tab-strip.ts +14 -13
  479. package/src/surfaces/target-line.ts +6 -7
  480. package/src/surfaces/welcome.ts +5 -7
  481. package/src/tabs/patch-ops.ts +4 -3
  482. package/src/tabs/project-config.ts +32 -21
  483. package/src/tabs/selection.ts +36 -8
  484. package/src/tabs/tab.ts +52 -41
  485. package/src/tabs/transact.ts +98 -53
  486. package/src/types.ts +32 -17
  487. package/src/ui/ai-credentials-form.ts +10 -13
  488. package/src/ui/ai-model-picker.ts +3 -3
  489. package/src/ui/cf-account-picker.ts +7 -9
  490. package/src/ui/color-selector.ts +9 -5
  491. package/src/ui/dynamic-slot.ts +7 -8
  492. package/src/ui/expression-editor.ts +112 -105
  493. package/src/ui/form-controls.ts +57 -48
  494. package/src/ui/formula-catalog.ts +239 -230
  495. package/src/ui/formula-chips.ts +33 -18
  496. package/src/ui/layers.ts +44 -31
  497. package/src/ui/media-picker.ts +18 -9
  498. package/src/ui/popover-surface.ts +20 -12
  499. package/src/ui/progress-modal.ts +13 -8
  500. package/src/ui/regions.ts +7 -6
  501. package/src/ui/schema-form.ts +113 -70
  502. package/src/ui/surface.ts +71 -8
  503. package/src/ui/timing.ts +9 -0
  504. package/src/ui/value-source.ts +44 -31
  505. package/src/ui/virtual-window.ts +3 -2
  506. package/src/utils/base64.ts +3 -1
  507. package/src/utils/edit-display.ts +73 -73
  508. package/src/utils/element-selectors.ts +3 -2
  509. package/src/utils/google-fonts.ts +15 -14
  510. package/src/utils/inherited-style.ts +18 -20
  511. package/src/utils/link-target.ts +1 -1
  512. package/src/utils/preview-format.ts +25 -3
  513. package/src/utils/strip-events.ts +49 -22
  514. package/src/utils/studio-utils.ts +29 -14
  515. package/src/view.ts +2 -3
  516. package/src/workspace/pane-derive.ts +10 -12
  517. package/src/workspace/session.ts +53 -43
  518. package/src/workspace/workspace.ts +40 -36
  519. package/dist/chunks/adapter-f93pafd7.js +0 -4
  520. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  521. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  522. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  523. package/dist/chunks/color-field-embq5ctg.js +0 -4
  524. package/dist/chunks/color-fpezvnkt.js +0 -4
  525. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  526. package/dist/chunks/combobox-773hdzyj.js +0 -4
  527. package/dist/chunks/components-ax2f1fnn.js +0 -4
  528. package/dist/chunks/content-source-108aqtk1.js +0 -4
  529. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  530. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  531. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  532. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  533. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  534. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  535. package/dist/chunks/files-44vp8a2s.js +0 -4
  536. package/dist/chunks/format-host-7q1petb9.js +0 -4
  537. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  538. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  539. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  540. package/dist/chunks/icons-p44xhjf0.js +0 -4
  541. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  542. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  543. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  544. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  545. package/dist/chunks/index-wkyfjeqz.js +0 -4
  546. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  547. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  548. package/dist/chunks/layers-xd92fg8d.js +0 -4
  549. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  550. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  551. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  552. package/dist/chunks/menu-37d07z9m.js +0 -4
  553. package/dist/chunks/menu-5c55ea3d.js +0 -4
  554. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  555. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  556. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  557. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  558. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  559. package/dist/chunks/parse-897fvqah.js +0 -4
  560. package/dist/chunks/platform-v1qctbe6.js +0 -4
  561. package/dist/chunks/popover-8htra4er.js +0 -4
  562. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  563. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  564. package/dist/chunks/references-gmqp82fs.js +0 -4
  565. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  566. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  567. package/dist/chunks/select-n3v7gwas.js +0 -4
  568. package/dist/chunks/split-pff8f3ze.js +0 -4
  569. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  570. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  571. package/dist/chunks/studio-1b04pd0j.js +0 -64
  572. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  573. package/dist/chunks/studio-4tanh828.js +0 -5
  574. package/dist/chunks/studio-55h4mstj.js +0 -4
  575. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  576. package/dist/chunks/studio-60dqgb0c.js +0 -5
  577. package/dist/chunks/studio-61dp09qg.js +0 -9
  578. package/dist/chunks/studio-63epcrj2.js +0 -5
  579. package/dist/chunks/studio-74k29dy9.js +0 -5
  580. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  581. package/dist/chunks/studio-7zx31knw.js +0 -9
  582. package/dist/chunks/studio-8bxk97km.js +0 -5
  583. package/dist/chunks/studio-933e30n4.js +0 -5
  584. package/dist/chunks/studio-98wnwhbg.js +0 -5
  585. package/dist/chunks/studio-9mccjwjh.js +0 -14
  586. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  587. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  588. package/dist/chunks/studio-e81q1vb9.js +0 -5
  589. package/dist/chunks/studio-epgrmqqm.js +0 -5
  590. package/dist/chunks/studio-ery42sqr.js +0 -4
  591. package/dist/chunks/studio-g1shz58g.js +0 -5
  592. package/dist/chunks/studio-gf0fz03c.js +0 -5
  593. package/dist/chunks/studio-gjtpe62q.js +0 -6
  594. package/dist/chunks/studio-gkskhg7m.js +0 -5
  595. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  596. package/dist/chunks/studio-j03zga3y.js +0 -9
  597. package/dist/chunks/studio-jhpxeckz.js +0 -5
  598. package/dist/chunks/studio-k01r7ykp.js +0 -5
  599. package/dist/chunks/studio-kk7h30ne.js +0 -7
  600. package/dist/chunks/studio-kt1zqney.js +0 -5
  601. package/dist/chunks/studio-m3cwhvye.js +0 -5
  602. package/dist/chunks/studio-mcayt6hz.js +0 -5
  603. package/dist/chunks/studio-myjcghv3.js +0 -5
  604. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  605. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  606. package/dist/chunks/studio-nj5a01jy.js +0 -928
  607. package/dist/chunks/studio-pcgz8heb.js +0 -5
  608. package/dist/chunks/studio-qcsq0t15.js +0 -5
  609. package/dist/chunks/studio-qkstvve9.js +0 -5
  610. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  611. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  612. package/dist/chunks/studio-s8dmmz66.js +0 -5
  613. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  614. package/dist/chunks/studio-szsjbj0g.js +0 -5
  615. package/dist/chunks/studio-t1xzawhr.js +0 -16
  616. package/dist/chunks/studio-t6b6qe31.js +0 -5
  617. package/dist/chunks/studio-tdcprbqb.js +0 -5
  618. package/dist/chunks/studio-vyc0b4he.js +0 -10
  619. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  620. package/dist/chunks/studio-w3hskzqk.js +0 -5
  621. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  622. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  623. package/dist/chunks/studio-y6n42tgs.js +0 -5
  624. package/dist/chunks/studio-yb560vxr.js +0 -5
  625. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  626. package/dist/chunks/studio-yw05w8f0.js +0 -7
  627. package/dist/chunks/studio-z16sgavc.js +0 -5
  628. package/dist/chunks/studio-zyqn40w4.js +0 -5
  629. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  630. package/dist/chunks/tabs-jwthg40w.js +0 -4
  631. package/dist/chunks/textfield-spy3hc77.js +0 -4
  632. package/dist/chunks/toast-4d35zd64.js +0 -4
  633. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  634. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  635. package/dist/chunks/tree-h19v1jfz.js +0 -4
  636. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  637. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
@@ -39,7 +39,7 @@ import {
39
39
  attachInstruction,
40
40
  extractInstruction,
41
41
  } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
42
- import { isJsonObject } from "@jxsuite/schema/guards";
42
+ import { isJsonObject, isNumber, isString } from "@jxsuite/schema/guards";
43
43
  import { mountExpressionEditor, mountOperandEditor } from "../ui/expression-editor";
44
44
  import { openMenu } from "../surfaces/menu";
45
45
  import { disposeDetachedStatementEditors, renderStatementsSurface } from "../surfaces/statements";
@@ -47,12 +47,14 @@ import { disposeDetachedStatementEditors, renderStatementsSurface } from "../sur
47
47
  import type {
48
48
  CemEvent,
49
49
  JxDispatchStatement,
50
+ JxDocumentValue,
50
51
  JxIfStatement,
51
52
  JxStatement,
52
53
  JxStateDefinition,
53
54
  JxSwitchStatement,
54
55
  } from "@jxsuite/schema/types";
55
- import type { StatementFieldView, StatementRowView, StatementOption } from "../surfaces/statements";
56
+ import type { StatementFieldView, StatementRowView } from "../surfaces/statements";
57
+ import type { SurfaceOption } from "../ui/surface";
56
58
 
57
59
  // ─── Options ─────────────────────────────────────────────────────────────────
58
60
 
@@ -91,8 +93,15 @@ type LanePath = (string | number)[];
91
93
 
92
94
  // ─── Statement Kind Detection ────────────────────────────────────────────────
93
95
 
94
- /** Discriminate a statement's kind, mirroring the runtime's detection order (`spec.md` §20.2). */
95
- export function statementKind(stmt: unknown): "expression" | "if" | "switch" | "dispatch" {
96
+ /**
97
+ * Discriminate a statement's kind, mirroring the runtime's detection order (`spec.md` §20.2).
98
+ *
99
+ * Takes any document value, not only a well-formed statement: a body is read from a document, and
100
+ * whatever an entry holds falls back to `"expression"` rather than throwing.
101
+ */
102
+ export function statementKind(
103
+ stmt: JxDocumentValue | undefined,
104
+ ): "expression" | "if" | "switch" | "dispatch" {
96
105
  if (isJsonObject(stmt)) {
97
106
  if ("operator" in stmt) {
98
107
  return "expression";
@@ -112,8 +121,23 @@ export function statementKind(stmt: unknown): "expression" | "if" | "switch" | "
112
121
 
113
122
  const ASSIGN_OPS = new Set(["=", "+=", "-=", "*=", "/="]);
114
123
 
124
+ /** A statement {@link statementKind} reads as an `if`/`then`/`else` branch. */
125
+ function isIfStatement(stmt: JxStatement): stmt is JxIfStatement {
126
+ return statementKind(stmt) === "if";
127
+ }
128
+
129
+ /** A statement {@link statementKind} reads as a `$switch`/`cases` multiway branch. */
130
+ function isSwitchStatement(stmt: JxStatement): stmt is JxSwitchStatement {
131
+ return statementKind(stmt) === "switch";
132
+ }
133
+
134
+ /** A statement {@link statementKind} reads as a WHATWG `dispatchEvent`. */
135
+ function isDispatchStatement(stmt: JxStatement): stmt is JxDispatchStatement {
136
+ return statementKind(stmt) === "dispatch";
137
+ }
138
+
115
139
  /** Card header label — ECMA/WHATWG naming (`spec.md` §20.2). */
116
- function kindLabel(stmt: unknown): string {
140
+ function kindLabel(stmt: JxStatement): string {
117
141
  switch (statementKind(stmt)) {
118
142
  case "if": {
119
143
  return "If / Else";
@@ -139,22 +163,25 @@ function kindLabel(stmt: unknown): string {
139
163
 
140
164
  // ─── Add-statement Seeds (spec.md §20 shapes) ────────────────────────────────
141
165
 
142
- const STATEMENT_SEEDS: Record<string, () => JxStatement> = {
143
- call: () => ({ operator: "call", target: { $ref: "" }, value: [] }),
144
- dispatch: () => ({ dispatchEvent: "" }),
145
- if: () => ({
146
- if: { operator: "===", target: { $ref: "" }, value: null },
147
- then: [],
148
- }),
149
- set: () => ({ operator: "=", target: { $ref: "" }, value: null }),
150
- switch: () => ({ $switch: { $ref: "" }, cases: {} }),
151
- };
166
+ const STATEMENT_SEEDS = new Map<string, () => JxStatement>([
167
+ ["call", () => ({ operator: "call", target: { $ref: "" }, value: [] })],
168
+ ["dispatch", () => ({ dispatchEvent: "" })],
169
+ [
170
+ "if",
171
+ () => ({
172
+ if: { operator: "===", target: { $ref: "" }, value: null },
173
+ then: [],
174
+ }),
175
+ ],
176
+ ["set", () => ({ operator: "=", target: { $ref: "" }, value: null })],
177
+ ["switch", () => ({ $switch: { $ref: "" }, cases: {} })],
178
+ ]);
152
179
 
153
180
  /**
154
181
  * The add-statement menu, in the order the rows read. One list, and this is it
155
182
  * (`studio-ui-guidelines.md` §12.5).
156
183
  */
157
- const STATEMENT_CHOICES: readonly StatementOption[] = [
184
+ const STATEMENT_CHOICES: readonly SurfaceOption[] = [
158
185
  { label: "Set state", value: "set" },
159
186
  { label: "Call function", value: "call" },
160
187
  { label: "If / Else", value: "if" },
@@ -164,34 +191,84 @@ const STATEMENT_CHOICES: readonly StatementOption[] = [
164
191
 
165
192
  // ─── Lane Addressing (immutable read/write through nested statement lists) ───
166
193
 
194
+ /**
195
+ * The lane one statement holds under a lane-path step: `then`/`else` on an `if`, a named case or
196
+ * `default` on a `$switch`. Undefined for any other step, which is how a stale path reads.
197
+ */
198
+ function laneUnder(
199
+ stmt: JxStatement,
200
+ key: string | number | undefined,
201
+ caseKey: string | number | undefined,
202
+ ): JxStatement[] | undefined {
203
+ if (isIfStatement(stmt)) {
204
+ if (key === "then") {
205
+ return stmt.then;
206
+ }
207
+ if (key === "else") {
208
+ return stmt.else;
209
+ }
210
+ }
211
+ if (isSwitchStatement(stmt)) {
212
+ if (key === "default") {
213
+ return stmt.default;
214
+ }
215
+ if (key === "cases" && isString(caseKey) && isJsonObject(stmt.cases)) {
216
+ return stmt.cases[caseKey];
217
+ }
218
+ }
219
+ return undefined;
220
+ }
221
+
222
+ /** How many entries a lane path's first step consumes: three for a case, two otherwise. */
223
+ function stepLength(key: string | number | undefined): number {
224
+ return key === "cases" ? 3 : 2;
225
+ }
226
+
167
227
  /** Resolve the statement list a lane path points at; null when the path is stale. */
168
228
  export function laneListAt(list: JxStatement[], path: LanePath): JxStatement[] | null {
169
229
  if (path.length === 0) {
170
230
  return list;
171
231
  }
172
- const [idx, key] = path;
173
- /*
174
- * `unknown`, not a cast to `Record<string, unknown>`. A `JxStatement` is a union of interfaces
175
- * with no index signature, so asserting one into an open bag is a lie TypeScript rightly refuses
176
- * — and it was buying nothing, because `isJsonObject` takes `unknown` and narrows to exactly the
177
- * open bag this wants. The guard on the next line is the real check either way.
178
- */
179
- const stmt: unknown = typeof idx === "number" ? list[idx] : null;
180
- if (!isJsonObject(stmt) || typeof key !== "string") {
232
+ const [idx, key, caseKey] = path;
233
+ const stmt = isNumber(idx) ? list[idx] : undefined;
234
+ if (stmt === undefined) {
181
235
  return null;
182
236
  }
183
- if (key === "cases") {
184
- const caseKey = path.at(2);
185
- const { cases } = stmt;
186
- if (typeof caseKey !== "string" || !isJsonObject(cases) || !Array.isArray(cases[caseKey])) {
187
- return null;
237
+ /* A lane is document data, so the array check stays: a `then` the document holds as anything
238
+ else is a stale path here, not a list to walk. */
239
+ const lane = laneUnder(stmt, key, caseKey);
240
+ return Array.isArray(lane) ? laneListAt(lane, path.slice(stepLength(key))) : null;
241
+ }
242
+
243
+ /**
244
+ * The statement with the lane at one lane-path step rewritten, or null when the statement holds no
245
+ * lane there. The step's key stays where it was in the statement, or is appended when new.
246
+ */
247
+ function withLaneUnder(
248
+ stmt: JxStatement,
249
+ key: string | number | undefined,
250
+ caseKey: string | number | undefined,
251
+ rewrite: (lane: JxStatement[]) => JxStatement[],
252
+ ): JxStatement | null {
253
+ if (isIfStatement(stmt)) {
254
+ if (key === "then") {
255
+ return { ...stmt, then: rewrite(Array.isArray(stmt.then) ? stmt.then : []) };
256
+ }
257
+ if (key === "else") {
258
+ return { ...stmt, else: rewrite(stmt.else ?? []) };
188
259
  }
189
- return laneListAt(cases[caseKey] as unknown as JxStatement[], path.slice(3));
190
260
  }
191
- if (!Array.isArray(stmt[key])) {
192
- return null;
261
+ if (isSwitchStatement(stmt)) {
262
+ if (key === "default") {
263
+ return { ...stmt, default: rewrite(stmt.default ?? []) };
264
+ }
265
+ if (key === "cases" && isString(caseKey)) {
266
+ const cases = { ...stmt.cases };
267
+ cases[caseKey] = rewrite(cases[caseKey] ?? []);
268
+ return { ...stmt, cases };
269
+ }
193
270
  }
194
- return laneListAt(stmt[key] as unknown as JxStatement[], path.slice(2));
271
+ return null;
195
272
  }
196
273
 
197
274
  /** Rebuild the statement tree with the lane at `path` replaced by `next` — fully immutable. */
@@ -203,22 +280,18 @@ export function withLaneList(
203
280
  if (path.length === 0) {
204
281
  return next;
205
282
  }
206
- const idx = path[0] as number;
207
- const key = path[1] as string;
208
- const stmt = list[idx] as unknown as Record<string, unknown>;
209
- let updated: Record<string, unknown>;
210
- if (key === "cases") {
211
- const caseKey = path[2] as string;
212
- const cases = { ...(stmt.cases as Record<string, JxStatement[]>) };
213
- cases[caseKey] = withLaneList(cases[caseKey] ?? [], path.slice(3), next);
214
- updated = { ...stmt, cases };
215
- } else {
216
- updated = {
217
- ...stmt,
218
- [key]: withLaneList((stmt[key] as JxStatement[] | undefined) ?? [], path.slice(2), next),
219
- };
283
+ const [idx, key, caseKey] = path;
284
+ const stmt = isNumber(idx) ? list[idx] : undefined;
285
+ const updated =
286
+ stmt === undefined
287
+ ? null
288
+ : withLaneUnder(stmt, key, caseKey, (lane) =>
289
+ withLaneList(lane, path.slice(stepLength(key)), next),
290
+ );
291
+ if (updated === null) {
292
+ throw new RangeError(`No statement lane at ${JSON.stringify(path)}`);
220
293
  }
221
- return list.map((s, i) => (i === idx ? (updated as unknown as JxStatement) : s));
294
+ return list.map((s, i) => (i === idx ? updated : s));
222
295
  }
223
296
 
224
297
  // ─── The plan: what every key in the projection addresses ────────────────────
@@ -391,45 +464,57 @@ export function flattenStatements(
391
464
  /** The operands of one card, and the plans that commit them. */
392
465
  function fieldsOf(cardKey: string, plan: CardPlan): StatementFieldView[] {
393
466
  const { commit, stmt } = plan;
394
- const kind = statementKind(stmt);
395
467
  const field = (prop: string) => `${cardKey}::${prop}`;
396
- if (kind === "if") {
397
- const s = stmt as JxIfStatement;
468
+ /* Every operand editor below reports what its own controls built — a `{ $ref }`, a JSON literal
469
+ or an expression node, the `JxExpressionOperand` members an operand admits — so each
470
+ assertion back to a statement only restores the operand type `mountOperandEditor` erases. */
471
+ if (isIfStatement(stmt)) {
398
472
  fields.set(field("if"), {
399
473
  paint: (host) =>
400
- mountOperandEditor(host, s.if, (v) => commit({ ...s, if: v } as JxStatement), {
401
- ...operandOpts(opts),
402
- label: "If",
403
- prop: "if",
404
- }),
474
+ mountOperandEditor(
475
+ host,
476
+ stmt.if,
477
+ // SAFETY: `v` is an operand the operand editor built (see above), so this is an `if`.
478
+ (v) => commit({ ...stmt, if: v } as JxIfStatement),
479
+ {
480
+ ...operandOpts(opts),
481
+ label: "If",
482
+ prop: "if",
483
+ },
484
+ ),
405
485
  });
406
486
  return [emptyField({ key: field("if"), kind: "control", label: "If", prop: "if" })];
407
487
  }
408
- if (kind === "switch") {
409
- const s = stmt as JxSwitchStatement;
488
+ if (isSwitchStatement(stmt)) {
410
489
  fields.set(field("$switch"), {
411
490
  paint: (host) =>
412
- mountOperandEditor(host, s.$switch, (v) => commit({ ...s, $switch: v } as JxStatement), {
413
- ...operandOpts(opts),
414
- label: "Switch on",
415
- prop: "$switch",
416
- }),
491
+ mountOperandEditor(
492
+ host,
493
+ stmt.$switch,
494
+ // SAFETY: `v` is an operand the operand editor built (see above), so this is a `$switch`.
495
+ (v) => commit({ ...stmt, $switch: v } as JxSwitchStatement),
496
+ {
497
+ ...operandOpts(opts),
498
+ label: "Switch on",
499
+ prop: "$switch",
500
+ },
501
+ ),
417
502
  });
418
503
  return [
419
504
  emptyField({ key: field("$switch"), kind: "control", label: "Switch on", prop: "$switch" }),
420
505
  ];
421
506
  }
422
- if (kind === "dispatch") {
423
- const s = stmt as JxDispatchStatement;
507
+ if (isDispatchStatement(stmt)) {
424
508
  fields.set(field("dispatchEvent"), {
425
- set: (value) => commit({ ...s, dispatchEvent: value } as JxStatement),
509
+ set: (value) => commit({ ...stmt, dispatchEvent: value }),
426
510
  });
427
511
  fields.set(field("detail"), {
428
512
  paint: (host) =>
429
513
  mountOperandEditor(
430
514
  host,
431
- s.detail ?? null,
432
- (v) => commit({ ...s, detail: v } as JxStatement),
515
+ stmt.detail ?? null,
516
+ // SAFETY: `v` is an operand the operand editor built (see above), a valid `detail`.
517
+ (v) => commit({ ...stmt, detail: v } as JxDispatchStatement),
433
518
  {
434
519
  ...operandOpts(opts),
435
520
  label: "Detail",
@@ -439,8 +524,16 @@ export function flattenStatements(
439
524
  });
440
525
  fields.set(field("eventInit"), {
441
526
  flag: (name, checked) => {
442
- const { [name as "bubbles"]: _removed, ...rest } = s;
443
- commit((checked ? { ...rest, [name]: true } : rest) as JxStatement);
527
+ // The two CustomEventInit members the Options row draws, and nothing else.
528
+ if (name === "bubbles" || name === "composed") {
529
+ // Removed, then re-added, so a checked flag lands last, where it always has.
530
+ const next: JxDispatchStatement = { ...stmt };
531
+ delete next[name];
532
+ if (checked) {
533
+ next[name] = true;
534
+ }
535
+ commit(next);
536
+ }
444
537
  },
445
538
  });
446
539
  return [
@@ -451,18 +544,19 @@ export function flattenStatements(
451
544
  options: emitNames.map((n) => ({ label: n, value: n })),
452
545
  placeholder: "event-name",
453
546
  prop: "dispatchEvent",
454
- value: s.dispatchEvent ?? "",
547
+ // The document may hold anything under the key `statementKind` found; only a string shows.
548
+ value: isString(stmt.dispatchEvent) ? stmt.dispatchEvent : "",
455
549
  }),
456
550
  emptyField({ key: field("detail"), kind: "control", label: "Detail", prop: "detail" }),
457
551
  emptyField({
458
552
  flags: [
459
553
  {
460
- checked: Boolean(s.bubbles),
554
+ checked: Boolean(stmt.bubbles),
461
555
  key: `${field("eventInit")}::bubbles`,
462
556
  label: "Bubbles",
463
557
  },
464
558
  {
465
- checked: Boolean(s.composed),
559
+ checked: Boolean(stmt.composed),
466
560
  key: `${field("eventInit")}::composed`,
467
561
  label: "Composed",
468
562
  },
@@ -476,11 +570,18 @@ export function flattenStatements(
476
570
  }
477
571
  fields.set(field("expression"), {
478
572
  paint: (host) =>
479
- mountExpressionEditor(host, stmt, (n) => commit(n as JxStatement), {
480
- allowEventRef: opts.allowEventRef,
481
- stateDefs: opts.stateDefs,
482
- stateEntries: opts.stateEntries ?? null,
483
- }),
573
+ mountExpressionEditor(
574
+ host,
575
+ stmt,
576
+ /* SAFETY: the expression editor reports the node it was handed with one operand or its
577
+ operator replaced, so the expression statement it was given comes back as one. */
578
+ (n) => commit(n as JxStatement),
579
+ {
580
+ allowEventRef: opts.allowEventRef,
581
+ stateDefs: opts.stateDefs,
582
+ stateEntries: opts.stateEntries ?? null,
583
+ },
584
+ ),
484
585
  });
485
586
  /* No label: the card header already names the statement, and the expression editor draws its
486
587
  own Operator / Target / Value rows underneath. The surface hides an empty label node. */
@@ -523,35 +624,33 @@ export function flattenStatements(
523
624
  title: "Delete statement",
524
625
  });
525
626
 
526
- const kind = statementKind(stmt);
527
- if (kind === "if") {
528
- const s = stmt as JxIfStatement;
627
+ if (isIfStatement(stmt)) {
529
628
  const thenPath = [...path, index, "then"];
530
- const thenPlan = lanePlan(thenPath, s.then ?? []);
629
+ // A document's `then` is whatever it holds; anything but a list draws as an empty lane.
630
+ const thenList = Array.isArray(stmt.then) ? stmt.then : [];
631
+ const thenPlan = lanePlan(thenPath, thenList);
531
632
  laneRow(thenPlan, depth + 1, "Then");
532
- walk(s.then ?? [], thenPath, depth + 1, thenPlan.commit);
533
- if (Array.isArray(s.else)) {
633
+ walk(thenList, thenPath, depth + 1, thenPlan.commit);
634
+ if (Array.isArray(stmt.else)) {
534
635
  const elsePath = [...path, index, "else"];
535
636
  const elsePlan: LanePlan = {
536
- ...lanePlan(elsePath, s.else),
637
+ ...lanePlan(elsePath, stmt.else),
537
638
  remove: () => {
538
- const { else: _else, ...rest } = s;
539
- commit(rest as JxStatement);
639
+ const { else: _else, ...rest } = stmt;
640
+ commit(rest);
540
641
  },
541
642
  };
542
643
  laneRow(elsePlan, depth + 1, "Else", { title: "Remove branch" });
543
- walk(s.else, elsePath, depth + 1, elsePlan.commit);
644
+ walk(stmt.else, elsePath, depth + 1, elsePlan.commit);
544
645
  } else {
545
646
  actionRow(`act:${cardKey}:else`, depth + 1, "Add else", () =>
546
- commit({ ...s, else: [] } as JxStatement),
647
+ commit({ ...stmt, else: [] }),
547
648
  );
548
649
  }
549
- } else if (kind === "switch") {
550
- const s = stmt as JxSwitchStatement;
551
- const cases = isJsonObject(s.cases) ? (s.cases as Record<string, JxStatement[]>) : {};
650
+ } else if (isSwitchStatement(stmt)) {
651
+ const cases: Record<string, JxStatement[]> = isJsonObject(stmt.cases) ? stmt.cases : {};
552
652
  const entries = Object.entries(cases);
553
- const setCases = (next: Record<string, JxStatement[]>) =>
554
- commit({ ...s, cases: next } as JxStatement);
653
+ const setCases = (next: Record<string, JxStatement[]>) => commit({ ...stmt, cases: next });
555
654
  for (const [caseKey, caseList] of entries) {
556
655
  const casePath = [...path, index, "cases", caseKey];
557
656
  const list_ = Array.isArray(caseList) ? caseList : [];
@@ -577,18 +676,18 @@ export function flattenStatements(
577
676
  walk(list_, casePath, depth + 1, casePlan.commit);
578
677
  }
579
678
  const defaultPath = [...path, index, "default"];
580
- const defaultList = Array.isArray(s.default) ? s.default : [];
679
+ const defaultList = Array.isArray(stmt.default) ? stmt.default : [];
581
680
  const defaultPlan: LanePlan = {
582
681
  ...lanePlan(defaultPath, defaultList),
583
682
  commit: (next) => {
584
683
  /* The key goes with its last statement. A `default: []` left behind is a branch the
585
684
  runtime still matches, so an emptied lane has to delete the key rather than clear it. */
586
685
  if (next.length === 0) {
587
- const { default: _default, ...rest } = s;
588
- commit(rest as JxStatement);
686
+ const { default: _default, ...rest } = stmt;
687
+ commit(rest);
589
688
  return;
590
689
  }
591
- commit({ ...s, default: next } as JxStatement);
690
+ commit({ ...stmt, default: next });
592
691
  },
593
692
  };
594
693
  laneRow(defaultPlan, depth + 1, "Default");
@@ -636,45 +735,38 @@ function registerStatementsDnD(
636
735
  dndRegistrations.get(root)?.();
637
736
  const cleanups: (() => void)[] = [];
638
737
 
639
- for (const row of root.querySelectorAll("[data-stmt-row]") as NodeListOf<HTMLElement>) {
738
+ for (const row of root.querySelectorAll<HTMLElement>("[data-stmt-row]")) {
640
739
  const laneId = row.dataset.stmtLane ?? "[]";
641
740
  const index = Math.trunc(Number(row.dataset.stmtIndex)) || 0;
642
741
  const handle = row.querySelector('[part="drag"]');
742
+ const dragArgs: Parameters<typeof draggable>[0] = {
743
+ element: row,
744
+ getInitialData() {
745
+ return { index, lane: laneId, type: "statement" };
746
+ },
747
+ onGenerateDragPreview({ nativeSetDragImage }) {
748
+ disableNativeDragPreview({ nativeSetDragImage });
749
+ },
750
+ onDragStart() {
751
+ row.dataset.dragging = "";
752
+ },
753
+ onDrop() {
754
+ delete row.dataset.dragging;
755
+ },
756
+ };
757
+ if (handle) {
758
+ dragArgs.dragHandle = handle;
759
+ }
643
760
 
644
761
  cleanups.push(
645
762
  combine(
646
- draggable({
647
- element: row,
648
- ...(handle ? { dragHandle: handle } : {}),
649
- getInitialData() {
650
- return { index, lane: laneId, type: "statement" };
651
- },
652
- onGenerateDragPreview({
653
- nativeSetDragImage,
654
- }: {
655
- nativeSetDragImage: ((image: Element, x: number, y: number) => void) | null;
656
- }) {
657
- disableNativeDragPreview({ nativeSetDragImage });
658
- },
659
- onDragStart() {
660
- row.dataset.dragging = "";
661
- },
662
- onDrop() {
663
- delete row.dataset.dragging;
664
- },
665
- }),
763
+ draggable(dragArgs),
666
764
  dropTargetForElements({
667
765
  element: row,
668
- canDrop({ source }: { source: { data: Record<string, unknown> } }) {
766
+ canDrop({ source }) {
669
767
  return source.data.type === "statement" && source.data.lane === laneId;
670
768
  },
671
- getData({
672
- input,
673
- element,
674
- }: {
675
- input: Parameters<typeof attachInstruction>[1]["input"];
676
- element: Element;
677
- }) {
769
+ getData({ input, element }) {
678
770
  return attachInstruction(
679
771
  { index },
680
772
  {
@@ -685,22 +777,16 @@ function registerStatementsDnD(
685
777
  input,
686
778
  mode: "standard",
687
779
  },
688
- ) as Record<string | symbol, unknown>;
780
+ );
689
781
  },
690
- onDrag({ self }: { self: { data: Record<string, unknown> } }) {
782
+ onDrag({ self }) {
691
783
  const instruction = extractInstruction(self.data);
692
784
  markDrop(row, instruction?.type);
693
785
  },
694
786
  onDragLeave() {
695
787
  markDrop(row);
696
788
  },
697
- onDrop({
698
- self,
699
- source,
700
- }: {
701
- self: { data: Record<string, unknown> };
702
- source: { data: Record<string, unknown> };
703
- }) {
789
+ onDrop({ self, source }) {
704
790
  markDrop(row);
705
791
  const instruction = extractInstruction(self.data);
706
792
  if (
@@ -709,10 +795,14 @@ function registerStatementsDnD(
709
795
  ) {
710
796
  return;
711
797
  }
712
- const from = source.data.index as number;
798
+ // `canDrop` admitted only this lane's statement rows, whose data carries a number.
799
+ const from = source.data.index;
800
+ /* SAFETY: `laneId` is this row's `data-stmt-lane`, which the surface writes from the
801
+ row's `lane`: `JSON.stringify` of a LanePath in flattenStatements, or the "[]"
802
+ fallback above. */
713
803
  const lanePath = JSON.parse(laneId) as LanePath;
714
804
  const lane = laneListAt(statements, lanePath);
715
- if (!lane || from === index) {
805
+ if (!lane || !isNumber(from) || from === index) {
716
806
  return;
717
807
  }
718
808
  let insertAt = instruction.type === "reorder-above" ? index : index + 1;
@@ -815,7 +905,7 @@ export function mountStatementEditor(
815
905
  title: choice.label,
816
906
  })),
817
907
  run: (id) => {
818
- const seed = STATEMENT_SEEDS[id];
908
+ const seed = STATEMENT_SEEDS.get(id);
819
909
  if (seed) {
820
910
  plan.commit([...plan.list, seed()]);
821
911
  }