@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
@@ -19,12 +19,15 @@
19
19
  * The dialog itself is `src/surfaces/cf-account-picker.json`, a `jx-dialog`; this module is the
20
20
  * flow around it. It used to be a lit template rendered through `showDialog`, with its own
21
21
  * `repaint()` re-rendering the whole body into the slot's parent whenever anything landed — the
22
- * surface is reactive now, so a listing that arrives late, or a refusal, changes only what it names.
22
+ * surface is reactive now, so a listing that arrives late, or a refusal, changes only what it
23
+ * names.
23
24
  *
24
- * @docs studio/ai
25
25
  * @license MIT
26
+ * @docs studio/ai
26
27
  */
27
28
 
29
+ import { errorMessage } from "@jxsuite/schema/parse";
30
+
28
31
  import { getPlatform, hasPlatform } from "../platform";
29
32
  import { notifyCredentialsChanged } from "../settings/preferences-accounts";
30
33
  import { openCfAccountPickerSurface } from "../surfaces/cf-account-picker";
@@ -40,11 +43,6 @@ function canPick(): boolean {
40
43
  return Boolean(platform.cfAccounts && platform.cfSelectAccount);
41
44
  }
42
45
 
43
- /** What a thrown thing says, for a line the reader has to act on. */
44
- function reasonOf(error: unknown): string {
45
- return error instanceof Error ? error.message : String(error);
46
- }
47
-
48
46
  /**
49
47
  * Ask which Cloudflare account this connection should use, and store the answer.
50
48
  *
@@ -83,7 +81,7 @@ export function openCfAccountPicker(): Promise<CfAccountSummary | null> {
83
81
  accounts = (await getPlatform().cfAccounts?.()) ?? [];
84
82
  } catch (error) {
85
83
  accounts = [];
86
- failure = reasonOf(error);
84
+ failure = errorMessage(error);
87
85
  }
88
86
  /* `done` released the slot, so a late listing landing after a dismissal would otherwise be a
89
87
  write into a disposed surface. The lit version guarded the same moment by resolving its
@@ -108,7 +106,7 @@ export function openCfAccountPicker(): Promise<CfAccountSummary | null> {
108
106
  if (!settled) {
109
107
  /* The list survives a refusal, and the reason sits above it: listing again is not what
110
108
  would fix an account the broker will not accept, so this state offers no retry. */
111
- handle.update({ choosing: "", failure: reasonOf(error) });
109
+ handle.update({ choosing: "", failure: errorMessage(error) });
112
110
  }
113
111
  return;
114
112
  }
@@ -25,18 +25,22 @@
25
25
  * @docs studio/design/style-inspector
26
26
  */
27
27
 
28
+ import { isNumber, isString } from "@jxsuite/schema/guards";
29
+
28
30
  import { activeTab } from "../workspace/workspace";
29
31
  import { getEffectiveStyle } from "../site-context";
30
32
  import { resolveTokenValue, tokenRefName } from "../style/token-ref";
31
33
  import { kebabToLabel } from "../utils/studio-utils";
32
34
 
33
35
  /**
34
- * One colour the project has named, as a swatch reads it.
36
+ * One colour the project has named, as a swatch reads it — the palette a Style or Content `color`
37
+ * row offers inside its picker.
35
38
  *
36
- * `Record<string, unknown>` because it is a `$map` item: a repeater's scope is a record, and a
37
- * shape that is not one cannot be read through `$map/item/...`.
39
+ * `value` and `color` are two fields because they are two things: choosing a swatch commits
40
+ * `var(--color-accent)`, while the chip is only how that reads on screen. A swatch is a `$map`
41
+ * item, read through `$map/item/...` by member name, so every member is a value a scope can hold.
38
42
  */
39
- export interface ColorTokenView extends Record<string, unknown> {
43
+ export interface ColorTokenView {
40
44
  /** What choosing this swatch commits — the reference, never the literal behind it. */
41
45
  value: string;
42
46
  /** The chip's colour: how the token looks, which is not what it means. */
@@ -76,7 +80,7 @@ export function colorTokens(): ColorTokenView[] {
76
80
  const style = getEffectiveStyle(activeTab.value?.doc.document?.style);
77
81
  const tokens: ColorTokenView[] = [];
78
82
  for (const [name, value] of Object.entries(style)) {
79
- if (name.startsWith("--color") && (typeof value === "string" || typeof value === "number")) {
83
+ if (name.startsWith("--color") && (isString(value) || isNumber(value))) {
80
84
  tokens.push({ color: String(value), label: varToLabel(name), value: `var(${name})` });
81
85
  }
82
86
  }
@@ -23,8 +23,10 @@ import { cloneValue } from "../tabs/doc-op-apply";
23
23
  import { activeTab } from "../workspace/workspace";
24
24
  import { slotMode } from "./value-source";
25
25
 
26
+ import type { JxDocumentValue } from "@jxsuite/schema/types";
26
27
  import type { JsonValue } from "../types";
27
28
  import type { SlotMode } from "./value-source";
29
+ import type { SurfaceOption } from "./surface";
28
30
 
29
31
  export type { SlotCapsSource, SlotMode, SlotPosition } from "./value-source";
30
32
  export { slotCaps, slotMode } from "./value-source";
@@ -96,7 +98,10 @@ function isTextEditRung(mode: SlotMode): boolean {
96
98
  * The rung to render this field at: the one it is already being edited at when a text edit could
97
99
  * explain the difference, otherwise whatever the document value says. Records its answer.
98
100
  */
99
- export function effectiveSlotMode(fieldKey: string, value: unknown): SlotMode {
101
+ export function effectiveSlotMode(
102
+ fieldKey: string,
103
+ value: JxDocumentValue | JsonValue | undefined,
104
+ ): SlotMode {
100
105
  const key = fieldScopeKey(fieldKey);
101
106
  const sniffed = slotMode(value);
102
107
  const previous = slotModeRendered.get(key);
@@ -108,18 +113,12 @@ export function effectiveSlotMode(fieldKey: string, value: unknown): SlotMode {
108
113
  return mode;
109
114
  }
110
115
 
111
- /** One pointer the From data… rung may offer, as a picker option. */
112
- export interface SignalOption {
113
- value: string;
114
- label: string;
115
- }
116
-
117
116
  /** Where a rung's seed value comes from — the subset of a slot's options that decides one. */
118
117
  export interface SlotSeedSources {
119
118
  /** State keys the position may point at; the first is what a fresh binding lands on. */
120
119
  stateDefs: readonly string[];
121
120
  /** Extra pointers beyond `#/state/*` — route params, `$map/item`. */
122
- extraSignals?: readonly SignalOption[] | null;
121
+ extraSignals?: readonly SurfaceOption[] | null;
123
122
  /** What Fixed value restores to. */
124
123
  literalDefault?: JsonValue | undefined;
125
124
  }
@@ -33,7 +33,14 @@
33
33
  * @docs studio/logic/formulas
34
34
  */
35
35
  import { PURE_METHOD_OPS } from "@jxsuite/runtime/expression";
36
- import { isJsonObject, isRef } from "@jxsuite/schema/guards";
36
+ import {
37
+ isBoolean,
38
+ isJsonObject,
39
+ isNonNullObject,
40
+ isNumber,
41
+ isRef,
42
+ isString,
43
+ } from "@jxsuite/schema/guards";
37
44
  import { formulaChipStrip } from "./formula-chips";
38
45
  import { applyCatalogPick, calleeEntry, formulaCatalog } from "./formula-catalog";
39
46
  import { openFormulaPalette } from "../surfaces/formula-palette";
@@ -43,17 +50,11 @@ import {
43
50
  renderExpressionEditorSurface,
44
51
  } from "../surfaces/expression-editor";
45
52
 
46
- import type {
47
- ExprOption,
48
- ExprRowView,
49
- ExprSelectGroup,
50
- ExpressionActions,
51
- } from "../surfaces/expression-editor";
52
- import type {
53
- JxExpressionNode,
54
- JxExpressionOperand,
55
- JxStateDefinition,
56
- } from "@jxsuite/schema/types";
53
+ import type { ExprRowView, ExpressionActions } from "../surfaces/expression-editor";
54
+ import type { ExpressionFields, ExpressionValue } from "./formula-chips";
55
+ import type { JxExpressionOperand, JxStateDefinition } from "@jxsuite/schema/types";
56
+ import type { SurfaceOption, SurfaceOptionGroup } from "./surface";
57
+ import type { ExpressionPreview } from "../services/preview-eval";
57
58
 
58
59
  // ─── Operator Categories ────────────────────────────────────────────────────
59
60
 
@@ -76,6 +77,22 @@ const BINARY_OPS = new Set([
76
77
  ]);
77
78
  const ASSIGN_OPS = new Set(["=", "+=", "-=", "*=", "/="]);
78
79
 
80
+ /**
81
+ * A value's members by name when it is an object, or `null` for a primitive, `null` or absence.
82
+ *
83
+ * Arrays come through as objects, as they always did here: the walk reads named members only, and
84
+ * an array has none of the ones it reads, so it walks as a node whose every slot is empty.
85
+ */
86
+ function fieldsOf(value: ExpressionValue | undefined): ExpressionFields | null {
87
+ if (!isNonNullObject(value)) {
88
+ return null;
89
+ }
90
+ /* SAFETY: every object an ExpressionValue admits is a record of document values keyed by member
91
+ name (or an array, read by name only), so each member read off it is an ExpressionValue or
92
+ absent. */
93
+ return value as ExpressionFields;
94
+ }
95
+
79
96
  /**
80
97
  * Does this expression node DO something rather than compute something?
81
98
  *
@@ -83,9 +100,9 @@ const ASSIGN_OPS = new Set(["=", "+=", "-=", "*=", "/="]);
83
100
  * value. The Data panel needs the distinction to know whether a row has a value column at all —
84
101
  * labelling `setBeds0` "pending" reads as "still loading" for a thing that will never load.
85
102
  */
86
- export function isActionExpression(node: unknown): boolean {
87
- const op = (node as { operator?: unknown } | null | undefined)?.operator;
88
- return typeof op === "string" && ASSIGN_OPS.has(op);
103
+ export function isActionExpression(node: ExpressionValue | undefined): boolean {
104
+ const op = fieldsOf(node)?.operator;
105
+ return isString(op) && ASSIGN_OPS.has(op);
89
106
  }
90
107
  const NO_ARG_OPS = new Set(["pop", "shift"]);
91
108
  const ONE_ARG_OPS = new Set(["push", "unshift"]);
@@ -164,7 +181,7 @@ const OPERATOR_GROUPS = [
164
181
  * names the group in the accessibility tree and the legend inside it is what a reader sees, which
165
182
  * is the pair `<sp-menu-divider>` plus a header span was standing in for.
166
183
  */
167
- const OPERATOR_SELECT_GROUPS: ExprSelectGroup[] = OPERATOR_GROUPS.map((group) => ({
184
+ const OPERATOR_SELECT_GROUPS: SurfaceOptionGroup[] = OPERATOR_GROUPS.map((group) => ({
168
185
  id: group.label,
169
186
  label: group.label,
170
187
  rows: group.ops.map((op) => ({ label: op, value: op })),
@@ -177,23 +194,23 @@ const OPERATOR_SELECT_GROUPS: ExprSelectGroup[] = OPERATOR_GROUPS.map((group) =>
177
194
  * operator that gains a group, or moves between two, keeps its label and its neighbours here
178
195
  * without anybody remembering to say so twice.
179
196
  */
180
- function restrictGroups(operators: readonly string[]): ExprSelectGroup[] {
197
+ function restrictGroups(operators: readonly string[]): SurfaceOptionGroup[] {
181
198
  const allowed = new Set(operators);
182
- return OPERATOR_SELECT_GROUPS.map((group) => ({
183
- ...group,
184
- rows: group.rows.filter((row) => allowed.has(row.value)),
185
- })).filter((group) => group.rows.length > 0);
199
+ return OPERATOR_SELECT_GROUPS.flatMap((group) => {
200
+ const rows = group.rows.filter((row) => allowed.has(row.value));
201
+ return rows.length > 0 ? [{ ...group, rows }] : [];
202
+ });
186
203
  }
187
204
 
188
205
  /** The three rungs of the value ladder, spelled the way `ui/value-source.ts` spells them (§6.6). */
189
- const SOURCE_OPTIONS: ExprOption[] = [
206
+ const SOURCE_OPTIONS: SurfaceOption[] = [
190
207
  { label: VALUE_SOURCE_LABELS.literal, value: "literal" },
191
208
  { label: VALUE_SOURCE_LABELS.ref, value: "ref" },
192
209
  { label: VALUE_SOURCE_LABELS.expression, value: "expression" },
193
210
  ];
194
211
 
195
212
  /** What a literal may be. Abbreviated because the picker sits beside the value it types. */
196
- const TYPE_OPTIONS: ExprOption[] = [
213
+ const TYPE_OPTIONS: SurfaceOption[] = [
197
214
  { label: "str", value: "string" },
198
215
  { label: "num", value: "number" },
199
216
  { label: "bool", value: "boolean" },
@@ -207,7 +224,7 @@ const TYPE_OPTIONS: ExprOption[] = [
207
224
  * type is what the value IS, and the control is what edits it — `null` is a type with no control at
208
225
  * all, drawn as an inert word.
209
226
  */
210
- const LITERAL_CONTROLS: Record<string, string> = {
227
+ const LITERAL_CONTROLS = {
211
228
  boolean: "bool",
212
229
  null: "null",
213
230
  number: "number",
@@ -300,11 +317,11 @@ function operatorInfo(op: string): OperatorInfo {
300
317
  * Properties, Style and Logic tabs give, and they are spelled the same way — `ui/value-source.ts`
301
318
  * owns the words, so `lit / $ref / expr` is gone from the operand picker (§6.6).
302
319
  *
303
- * @param {unknown} operand
320
+ * @param {ExpressionValue | undefined} operand
304
321
  * @returns {"ref" | "expression" | "literal"}
305
322
  */
306
- function operandMode(operand: unknown) {
307
- if (operand && typeof operand === "object") {
323
+ function operandMode(operand: ExpressionValue | undefined) {
324
+ if (isNonNullObject(operand)) {
308
325
  if ("$ref" in operand) {
309
326
  return "ref";
310
327
  }
@@ -317,7 +334,7 @@ function operandMode(operand: unknown) {
317
334
 
318
335
  /** Positional-arg labels for a `call` node, from the callee's catalog entry when resolvable. */
319
336
  function calleeParamLabels(
320
- target: unknown,
337
+ target: ExpressionValue | undefined,
321
338
  state?: Record<string, JxStateDefinition> | null,
322
339
  ): string[] {
323
340
  const ref = isRef(target) ? target.$ref : "";
@@ -342,17 +359,17 @@ function defaultForMode(mode: string): JxExpressionOperand {
342
359
  // ─── Literal Type Detection ─────────────────────────────────────────────────
343
360
 
344
361
  /**
345
- * @param {unknown} val
362
+ * @param {ExpressionValue | undefined} val
346
363
  * @returns {"string" | "number" | "boolean" | "null"}
347
364
  */
348
- function literalType(val: unknown) {
365
+ function literalType(val: ExpressionValue | undefined) {
349
366
  if (val === null || val === undefined) {
350
367
  return "null";
351
368
  }
352
- if (typeof val === "boolean") {
369
+ if (isBoolean(val)) {
353
370
  return "boolean";
354
371
  }
355
- if (typeof val === "number") {
372
+ if (isNumber(val)) {
356
373
  return "number";
357
374
  }
358
375
  return "string";
@@ -378,20 +395,21 @@ function defaultForLiteralType(type: string): JxExpressionOperand {
378
395
  // ─── Hint (one-line summary for signal rows) ────────────────────────────────
379
396
 
380
397
  /**
381
- * @param {unknown} node
398
+ * @param {ExpressionValue | undefined} node
382
399
  * @returns {string}
383
400
  */
384
- export function expressionHint(node: unknown) {
385
- if (!isJsonObject(node) || typeof node.operator !== "string") {
401
+ export function expressionHint(node: ExpressionValue | undefined) {
402
+ const fields = fieldsOf(node);
403
+ const op = fields?.operator;
404
+ if (fields === null || !isString(op)) {
386
405
  return "$expression";
387
406
  }
388
- const expr = node as unknown as JxExpressionNode;
389
- const op = expr.operator;
390
- const { target } = expr;
407
+ const { target } = fields;
408
+ const targetOp = fieldsOf(target)?.operator;
391
409
  const targetLabel = isRef(target)
392
410
  ? target.$ref.replace("#/state/", "")
393
- : isJsonObject(target) && typeof target.operator === "string"
394
- ? `(${target.operator}…)`
411
+ : isString(targetOp)
412
+ ? `(${targetOp}…)`
395
413
  : String(target ?? "?");
396
414
 
397
415
  if (ASSIGN_OPS.has(op) || ONE_ARG_OPS.has(op)) {
@@ -423,18 +441,11 @@ export function expressionHint(node: unknown) {
423
441
 
424
442
  // ─── What the editor is handed ──────────────────────────────────────────────
425
443
 
426
- /** Preview data computed by services/preview-eval.ts — display strings keyed by node path. */
427
- export interface EditorPreview {
428
- values: Map<string, string>;
429
- error: string | null;
430
- mutating: boolean;
431
- }
432
-
433
444
  export interface ExpressionEditorOpts {
434
445
  stateDefs: string[];
435
446
  allowEventRef: boolean;
436
447
  depth?: number;
437
- preview?: EditorPreview | null;
448
+ preview?: ExpressionPreview | null;
438
449
  path?: (string | number)[];
439
450
  /** Full state defs map — resolves named-formula catalog entries (call labels, palette). */
440
451
  stateEntries?: Record<string, JxStateDefinition> | null;
@@ -491,7 +502,7 @@ export interface ExpressionProjection {
491
502
  /** The walk's own state: the options it was given, plus what it has emitted so far. */
492
503
  interface Walk {
493
504
  opts: ExpressionEditorOpts;
494
- preview: EditorPreview | null;
505
+ preview: ExpressionPreview | null;
495
506
  rows: ExprRowView[];
496
507
  plans: Map<string, RowPlan>;
497
508
  chipPaths: Map<string, (string | number)[]>;
@@ -513,6 +524,9 @@ type RowPatch = { [K in keyof ExprRowView]?: ExprRowView[K] | undefined };
513
524
  * to no case at all, so a partial row is a row that silently draws nothing.
514
525
  */
515
526
  function blankRow(row: RowPatch & { key: string; kind: ExprRowView["kind"] }) {
527
+ /* SAFETY: every caller hands in only defined values (each is computed with its own default), so
528
+ each key of the result is either the patch's value or the default beside it, and both have the
529
+ type ExprRowView declares for that key. */
516
530
  return {
517
531
  badge: "",
518
532
  catalog: false,
@@ -550,7 +564,7 @@ function indentAt(depth: number): string {
550
564
  }
551
565
 
552
566
  /** The live value at a node path, and whether the preview holds one at all. */
553
- function badgeAt(walk: Walk, key: string): { badge: string; hasBadge: boolean } {
567
+ function badgeAt(walk: Walk, key: string) {
554
568
  const text = walk.preview?.values.get(key);
555
569
  return { badge: text ?? "", hasBadge: text !== undefined };
556
570
  }
@@ -590,13 +604,14 @@ interface OperandSlot {
590
604
  */
591
605
  function walkOperand(
592
606
  walk: Walk,
593
- operand: unknown,
594
- commit: (next: unknown) => void,
607
+ operand: ExpressionValue | undefined,
608
+ commit: (next: ExpressionValue) => void,
595
609
  slot: OperandSlot,
596
610
  ): void {
597
611
  const { allowEventRef, stateDefs } = walk.opts;
598
- const stateRefs = (stateDefs || []).map((k) => `#/state/${k}`);
599
- const refValue = ((operand as Record<string, unknown> | null)?.$ref as string) ?? "";
612
+ const stateRefs = stateDefs.map((k) => `#/state/${k}`);
613
+ // Shown as written: a malformed (non-string) pointer is coerced the way the picker would show it.
614
+ const refValue = String(fieldsOf(operand)?.$ref ?? "");
600
615
  const plan: RowPlan = {
601
616
  setRef: (value) => commit({ $ref: value }),
602
617
  };
@@ -693,16 +708,14 @@ function walkOperand(
693
708
  /** The rows of a positional-args list (`splice`, `call`), plus the row that grows it. */
694
709
  function walkArgs(
695
710
  walk: Walk,
696
- args: unknown,
697
- commit: (next: unknown[]) => void,
711
+ args: ExpressionValue | undefined,
712
+ commit: (next: ExpressionValue[]) => void,
698
713
  depth: number,
699
714
  path: (string | number)[],
700
715
  naming: { labels: string[]; fallbackLabel: string },
701
716
  ): void {
702
- /* `Array.isArray` narrows an `unknown` to `any[]`, so every spread of it reads as unsafe to
703
- the type-aware lint. The elements ARE unknown — each is an operand this walk discriminates
704
- — so saying so restores the check rather than silencing it. */
705
- const safeArgs: unknown[] = Array.isArray(args) ? args : [];
717
+ // Anything but a list is no args yet: each element is an operand the walk discriminates.
718
+ const safeArgs: ExpressionValue[] = Array.isArray(args) ? args : [];
706
719
  for (const [idx, arg] of safeArgs.entries()) {
707
720
  const argPath = [...path, "value", idx];
708
721
  const label = naming.labels[idx] ?? naming.fallbackLabel;
@@ -749,16 +762,14 @@ function walkArgs(
749
762
  /** The case rows of a `switch` node: matched value → result operand, the default, and `+ Add case`. */
750
763
  function walkSwitchCases(
751
764
  walk: Walk,
752
- safeNode: Record<string, unknown>,
753
- onChange: (node: unknown) => void,
765
+ safeNode: ExpressionFields,
766
+ onChange: (node: ExpressionValue) => void,
754
767
  depth: number,
755
768
  path: (string | number)[],
756
769
  ): void {
757
- const cases = isJsonObject(safeNode.cases)
758
- ? (safeNode.cases as Record<string, unknown>)
759
- : ({} as Record<string, unknown>);
770
+ const cases: ExpressionFields = isJsonObject(safeNode.cases) ? safeNode.cases : {};
760
771
  const entries = Object.entries(cases);
761
- const setCases = (next: Record<string, unknown>) => onChange({ ...safeNode, cases: next });
772
+ const setCases = (next: ExpressionFields) => onChange({ ...safeNode, cases: next });
762
773
 
763
774
  for (const [caseKey, operand] of entries) {
764
775
  const casePath = [...path, "cases", caseKey];
@@ -782,7 +793,7 @@ function walkSwitchCases(
782
793
  if (newKey === caseKey) {
783
794
  return;
784
795
  }
785
- const next: Record<string, unknown> = {};
796
+ const next: ExpressionFields = {};
786
797
  for (const [k, v] of entries) {
787
798
  next[k === caseKey ? newKey : k] = v;
788
799
  }
@@ -829,16 +840,16 @@ function walkSwitchCases(
829
840
  }
830
841
 
831
842
  /** What replacing the operator means for the rest of the node. */
832
- function reoperate(safeNode: Record<string, unknown>, newOp: string): Record<string, unknown> {
843
+ function reoperate(safeNode: ExpressionFields, newOp: string): ExpressionFields {
833
844
  const newInfo = operatorInfo(newOp);
834
- const updated: Record<string, unknown> = { operator: newOp, target: safeNode.target };
845
+ const updated: ExpressionFields = { operator: newOp, target: safeNode.target };
835
846
  if (newInfo.targetMustBeRef && operandMode(safeNode.target) !== "ref") {
836
847
  updated.target = { $ref: "" };
837
848
  }
838
849
  if (newInfo.needsValue) {
839
850
  if (newInfo.valueIsNode) {
840
- const val = safeNode.value as Record<string, unknown> | null;
841
- updated.value = val?.operator ? safeNode.value : { operator: "!", target: null };
851
+ const valueNode = fieldsOf(safeNode.value);
852
+ updated.value = valueNode?.operator ? valueNode : { operator: "!", target: null };
842
853
  } else if (newInfo.spliceArray) {
843
854
  updated.value = Array.isArray(safeNode.value) ? safeNode.value : [null];
844
855
  } else {
@@ -863,16 +874,14 @@ function reoperate(safeNode: Record<string, unknown>, newOp: string): Record<str
863
874
  /** Emit every row one expression node reads as, deepest last. */
864
875
  function walkExpression(
865
876
  walk: Walk,
866
- node: unknown,
867
- onChange: (node: unknown) => void,
877
+ node: ExpressionValue | undefined,
878
+ onChange: (node: ExpressionValue) => void,
868
879
  depth: number,
869
880
  path: (string | number)[],
870
881
  ): void {
871
- const safeNode: Record<string, unknown> =
872
- node && typeof node === "object"
873
- ? (node as Record<string, unknown>)
874
- : { operator: "=", target: null };
875
- const op = (safeNode.operator as string) || "=";
882
+ const safeNode = fieldsOf(node) ?? { operator: "=", target: null };
883
+ // Shown as written: a malformed (non-string) operator is coerced the way the picker would show it.
884
+ const op = String(safeNode.operator || "=");
876
885
  const info = operatorInfo(op);
877
886
  const pathKey = path.join("/");
878
887
  const sub = (...segs: (string | number)[]) => [...path, ...segs].join("/");
@@ -914,23 +923,22 @@ function walkExpression(
914
923
  would be a second door onto the operators the select has just stopped offering. */
915
924
  const grammar = depth === 0 ? opts.operators : undefined;
916
925
  const operatorKey = `${pathKey}::operator`;
917
- walk.plans.set(operatorKey, {
918
- ...(grammar
919
- ? {}
920
- : {
921
- browse: (anchor: HTMLElement) =>
922
- openFormulaPalette({
923
- anchor,
924
- entries: formulaCatalog(opts.stateEntries),
925
- onPick: (entry) =>
926
- applyCatalogPick(entry, onChange, {
927
- onInsertDef: opts.onInsertDef,
928
- stateEntries: opts.stateEntries,
929
- }),
930
- }),
931
- }),
926
+ const operatorPlan: RowPlan = {
932
927
  setOperator: (newOp) => onChange(reoperate(safeNode, newOp)),
933
- });
928
+ };
929
+ if (!grammar) {
930
+ operatorPlan.browse = (anchor: HTMLElement) =>
931
+ openFormulaPalette({
932
+ anchor,
933
+ entries: formulaCatalog(opts.stateEntries),
934
+ onPick: (entry) =>
935
+ applyCatalogPick(entry, onChange, {
936
+ onInsertDef: opts.onInsertDef,
937
+ stateEntries: opts.stateEntries,
938
+ }),
939
+ });
940
+ }
941
+ walk.plans.set(operatorKey, operatorPlan);
934
942
  walk.rows.push(
935
943
  blankRow({
936
944
  ...rootBadge,
@@ -980,11 +988,10 @@ function walkExpression(
980
988
  prop: "value",
981
989
  }),
982
990
  );
991
+ const valueNode = fieldsOf(safeNode.value);
983
992
  walkExpression(
984
993
  walk,
985
- (safeNode.value as Record<string, unknown> | null)?.operator
986
- ? safeNode.value
987
- : { operator: "!", target: null },
994
+ valueNode?.operator ? valueNode : { operator: "!", target: null },
988
995
  (v) => onChange({ ...safeNode, value: v }),
989
996
  depth + 1,
990
997
  [...path, "value"],
@@ -1047,8 +1054,8 @@ function newWalk(opts: ExpressionEditorOpts): Walk {
1047
1054
 
1048
1055
  /** The projection one expression reads as: the rows, and what each key commits. */
1049
1056
  export function flattenExpression(
1050
- node: unknown,
1051
- onChange: (node: unknown) => void,
1057
+ node: ExpressionValue | undefined,
1058
+ onChange: (node: ExpressionValue) => void,
1052
1059
  opts: ExpressionEditorOpts,
1053
1060
  ): ExpressionProjection {
1054
1061
  const walk = newWalk(opts);
@@ -1061,8 +1068,8 @@ export function flattenExpression(
1061
1068
  * `dispatchEvent` detail (spec.md §20). The same rows, with no operator row above them.
1062
1069
  */
1063
1070
  export function flattenOperand(
1064
- operand: unknown,
1065
- onChange: (next: unknown) => void,
1071
+ operand: ExpressionValue | undefined,
1072
+ onChange: (next: ExpressionValue) => void,
1066
1073
  opts: ExpressionEditorOpts & { label?: string; prop?: string },
1067
1074
  ): ExpressionProjection {
1068
1075
  const walk = newWalk(opts);
@@ -1151,8 +1158,8 @@ function paint(host: HTMLElement, projection: ExpressionProjection, opts: Expres
1151
1158
  */
1152
1159
  export function mountExpressionEditor(
1153
1160
  host: HTMLElement,
1154
- node: unknown,
1155
- onChange: (node: unknown) => void,
1161
+ node: ExpressionValue | undefined,
1162
+ onChange: (node: ExpressionValue) => void,
1156
1163
  opts: ExpressionEditorOpts,
1157
1164
  ): void {
1158
1165
  paint(host, flattenExpression(node, onChange, opts), opts);
@@ -1165,8 +1172,8 @@ export function mountExpressionEditor(
1165
1172
  */
1166
1173
  export function mountOperandEditor(
1167
1174
  host: HTMLElement,
1168
- operand: unknown,
1169
- onChange: (next: unknown) => void,
1175
+ operand: ExpressionValue | undefined,
1176
+ onChange: (next: ExpressionValue) => void,
1170
1177
  opts: ExpressionEditorOpts & { label?: string; prop?: string },
1171
1178
  ): void {
1172
1179
  paint(host, flattenOperand(operand, onChange, opts), opts);