@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
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { postMessageChannel } from "./iframe-channel";
9
9
  import { rectOf } from "../utils/geometry";
10
- import { displayTagName } from "@jxsuite/schema/guards";
10
+ import { displayTagName, isNonNullObject } from "@jxsuite/schema/guards";
11
11
  import {
12
12
  applyCanvasDialogOpen,
13
13
  applyCanvasPopoverOpen,
@@ -59,16 +59,17 @@ import {
59
59
  import { resolveAssetRef } from "./asset-resolve";
60
60
  import type { AssetContext } from "./asset-resolve";
61
61
  import { KIT_LOADERS } from "@jxsuite/ui/loaders";
62
- import type { IframeChannel } from "./iframe-channel";
62
+ import type { CanvasEnvelope, IframeChannel } from "./iframe-channel";
63
63
  import type {
64
64
  CanvasMode,
65
+ DragOverMsg,
65
66
  DragSrcKind,
66
67
  FileDropHit,
67
68
  IframeToParent,
68
69
  LayoutHit,
69
70
  ParentToIframe,
70
71
  } from "./iframe-protocol";
71
- import type { JxDocument, JxMutableNode, JxStyle } from "@jxsuite/schema/types";
72
+ import type { JxDocument, JxMutableNode } from "@jxsuite/schema/types";
72
73
  import type { IframeRenderCtx, RenderHandle } from "./iframe-render";
73
74
  import { setBundleBase } from "../services/bundle-base";
74
75
 
@@ -153,12 +154,12 @@ export function fileDropHitFor(
153
154
  targetEl: HTMLElement,
154
155
  shadowDoc: JxMutableNode | null,
155
156
  ): FileDropHit | null {
156
- const serialized = targetEl.dataset?.jxPath;
157
+ const serialized = targetEl.dataset.jxPath;
157
158
  if (serialized == null) {
158
159
  return null;
159
160
  }
160
161
  const path = parseJxPath(serialized);
161
- const node = shadowDoc ? (getNodeAtPath(shadowDoc, path as JxPath) as JxMutableNode) : undefined;
162
+ const node = shadowDoc ? getNodeAtPath(shadowDoc, path) : undefined;
162
163
  return {
163
164
  path,
164
165
  rect: rectFor(targetEl),
@@ -186,7 +187,8 @@ export function layoutHitFor(target: EventTarget | null): LayoutHit | null {
186
187
  return null;
187
188
  }
188
189
  return {
189
- className: typeof el.className === "string" ? el.className : "",
190
+ // An `HTMLElement`'s `className` is always the string form (only SVG's is an animated value).
191
+ className: el.className,
190
192
  layoutFile: el.dataset.jxLayoutFile ?? "",
191
193
  layoutPath: parseJxPath(el.dataset.jxLayoutPath ?? "[]"),
192
194
  rect: rectFor(el),
@@ -194,6 +196,34 @@ export function layoutHitFor(target: EventTarget | null): LayoutHit | null {
194
196
  };
195
197
  }
196
198
 
199
+ /**
200
+ * The text a failed patch or render reports: the thrown value's `message` when it has one, the
201
+ * value itself otherwise.
202
+ */
203
+ function failureText(cause: unknown): string {
204
+ const message = isNonNullObject(cause) && "message" in cause ? cause.message : undefined;
205
+ return String(message ?? cause);
206
+ }
207
+
208
+ /** The edge-hold auto-scroll loop's last cursor, and the drag it belongs to. */
209
+ interface AutoScrollCursor {
210
+ x: number;
211
+ y: number;
212
+ dragSeq: number;
213
+ withCursor: boolean;
214
+ src?: DragSrcKind;
215
+ gen?: number;
216
+ }
217
+
218
+ /**
219
+ * The two document APIs the `idle` sample reads, as a frame may or may not provide them. lib.dom
220
+ * declares both unconditionally; happy-dom implements neither.
221
+ */
222
+ interface IdleProbeDocument {
223
+ getAnimations?: Document["getAnimations"];
224
+ fonts?: FontFaceSet;
225
+ }
226
+
197
227
  /** Set-key keys the patcher applies IN PLACE (never a subtree re-render) — safe under a live edit. */
198
228
  const IN_PLACE_KEYS = new Set(["style", "textContent"]);
199
229
 
@@ -317,14 +347,7 @@ export function startCanvasIframe(opts: {
317
347
  // (the parent has no pointer of its own then). Parent-driven flows (1/2/4) leave `src` undefined
318
348
  // And `withCursor` false — the tick falls back to `dragSrc`/`dragGen` and the parent moves the
319
349
  // Ghost from its own raw pointer.
320
- let autoScrollCursor: {
321
- x: number;
322
- y: number;
323
- dragSeq: number;
324
- withCursor: boolean;
325
- src?: DragSrcKind;
326
- gen?: number;
327
- } | null = null;
350
+ let autoScrollCursor: AutoScrollCursor | null = null;
328
351
  const win = container.ownerDocument.defaultView;
329
352
 
330
353
  function stopAutoScroll(): void {
@@ -353,16 +376,17 @@ export function startCanvasIframe(opts: {
353
376
  return;
354
377
  }
355
378
  const preview = previewAt(autoScrollCursor, src, shadowDoc, container.ownerDocument);
356
- channel.post({
357
- // Flow 3 (withCursor) re-posts the cursor so the parent keeps tracking the ghost at an edge-hold.
358
- ...(autoScrollCursor.withCursor
359
- ? { cursor: { x: autoScrollCursor.x, y: autoScrollCursor.y } }
360
- : {}),
379
+ const over: DragOverMsg = {
361
380
  dragSeq: autoScrollCursor.dragSeq,
362
381
  gen: autoScrollCursor.gen ?? dragGen,
363
382
  kind: "dragOver",
364
383
  preview,
365
- });
384
+ };
385
+ // Flow 3 (withCursor) re-posts the cursor so the parent keeps tracking the ghost at an edge-hold.
386
+ if (autoScrollCursor.withCursor) {
387
+ over.cursor = { x: autoScrollCursor.x, y: autoScrollCursor.y };
388
+ }
389
+ channel.post(over);
366
390
  autoScrollFrame = win.requestAnimationFrame(autoScrollTick);
367
391
  }
368
392
 
@@ -381,13 +405,12 @@ export function startCanvasIframe(opts: {
381
405
  stopAutoScroll();
382
406
  return;
383
407
  }
384
- autoScrollCursor = {
385
- dragSeq,
386
- withCursor: flow3 != null,
387
- x: cursor.x,
388
- y: cursor.y,
389
- ...(flow3 ? { gen: flow3.gen, src: flow3.src } : {}),
390
- };
408
+ const next: AutoScrollCursor = { dragSeq, withCursor: flow3 != null, x: cursor.x, y: cursor.y };
409
+ if (flow3) {
410
+ next.gen = flow3.gen;
411
+ next.src = flow3.src;
412
+ }
413
+ autoScrollCursor = next;
391
414
  if (!autoScrollFrame) {
392
415
  autoScrollFrame = win.requestAnimationFrame(autoScrollTick);
393
416
  }
@@ -522,13 +545,11 @@ export function startCanvasIframe(opts: {
522
545
  }
523
546
 
524
547
  function sampleIdle(): Extract<IframeToParent, { kind: "idle" }> {
525
- const running =
526
- typeof frameDoc.getAnimations === "function"
527
- ? frameDoc.getAnimations().filter((a) => a.playState === "running").length
528
- : 0;
548
+ const probe: IdleProbeDocument = frameDoc;
549
+ const running = probe.getAnimations?.().filter((a) => a.playState === "running").length ?? 0;
529
550
  return {
530
551
  animations: running,
531
- fonts: frameDoc.fonts ? frameDoc.fonts.status === "loaded" : true,
552
+ fonts: probe.fonts ? probe.fonts.status === "loaded" : true,
532
553
  gen: renderedGen,
533
554
  images: pendingImageRetries(),
534
555
  kind: "idle",
@@ -750,12 +771,7 @@ export function startCanvasIframe(opts: {
750
771
  // The wrong scope); the parent additionally gen-gates the reply against its own state.
751
772
  const results =
752
773
  msg.gen === renderedGen && renderCtx && shadowDoc
753
- ? evaluateLiveExprs(
754
- msg.exprs,
755
- renderCtx.defs as Record<string, unknown>,
756
- shadowDoc,
757
- msg.contextPath,
758
- )
774
+ ? evaluateLiveExprs(msg.exprs, renderCtx.defs, shadowDoc, msg.contextPath)
759
775
  : [];
760
776
  channel.post({ gen: msg.gen, kind: "evalResult", reqId: msg.reqId, results });
761
777
  return;
@@ -820,11 +836,7 @@ export function startCanvasIframe(opts: {
820
836
  channel.post({ gen, kind: "patchComplete" });
821
837
  armIdleWatch();
822
838
  } catch (error) {
823
- channel.post({
824
- gen,
825
- kind: "patchError",
826
- message: String((error as Error)?.message ?? error),
827
- });
839
+ channel.post({ gen, kind: "patchError", message: failureText(error) });
828
840
  }
829
841
  return;
830
842
  }
@@ -835,14 +847,10 @@ export function startCanvasIframe(opts: {
835
847
  if (msg.gen !== renderedGen || !shadowDoc) {
836
848
  return;
837
849
  }
838
- (shadowDoc as { style?: JxStyle }).style = msg.style as JxStyle;
850
+ shadowDoc.style = msg.style;
839
851
  const rootEl = container.firstElementChild;
840
852
  if (rootEl instanceof HTMLElement) {
841
- reapplyStyle(
842
- rootEl,
843
- msg.style as JxStyle,
844
- (shadowDoc as { $media?: Record<string, string> }).$media ?? {},
845
- );
853
+ reapplyStyle(rootEl, msg.style, shadowDoc.$media ?? {});
846
854
  }
847
855
  return;
848
856
  }
@@ -945,7 +953,10 @@ export function startCanvasIframe(opts: {
945
953
  if (msg.kind === "redefineElement") {
946
954
  /* The canvas half of embedding.md §7. The definition is replaced in THIS realm; instances
947
955
  already on the canvas keep the old one until the host's next render replaces them. */
948
- void redefineElement(msg.doc as never, msg.base);
956
+ /* SAFETY: The host posts only the component definition a save just wrote
957
+ (`redefineElementOnCanvases`), a whole `.json` element document, and `redefineElement`
958
+ itself rejects one whose `tagName` is not a hyphenated literal. */
959
+ void redefineElement(msg.doc as JxDocument, msg.base);
949
960
  return;
950
961
  }
951
962
  if (msg.kind === "setLocale") {
@@ -988,6 +999,8 @@ export function startCanvasIframe(opts: {
988
999
  // A document with no format, where the studio's own element metadata answers on its own.
989
1000
  setEditableVerdicts(msg.editableTags ?? null);
990
1001
  const { gen, mapperCtx } = msg;
1002
+ /* SAFETY: The host posts `shadowDoc` as a JSON round-trip of the tab's raw page document (or of
1003
+ the stylebook specimen), so it is a `JxMutableNode` in the forward-op coordinate space. */
991
1004
  const rawDoc = msg.shadowDoc as JxMutableNode;
992
1005
  void (async () => {
993
1006
  try {
@@ -1002,9 +1015,11 @@ export function startCanvasIframe(opts: {
1002
1015
  than a theoretical one. It used to be exactly that, one orphaned `<style>` per styled
1003
1016
  element per render. */
1004
1017
  resetDocumentStyles(container.ownerDocument);
1005
- handle = await renderResolvedDocument({
1018
+ const renderOpts: Parameters<typeof renderResolvedDocument>[0] = {
1006
1019
  assets: versionedAssets(msg.assets ?? null),
1007
1020
  container,
1021
+ /* SAFETY: The host posts `doc` as a JSON round-trip of `resolveCanvasDocument`'s render
1022
+ document (or the stylebook specimen), which is the resolved `JxDocument` it renders. */
1008
1023
  doc: msg.doc as JxDocument,
1009
1024
  docBase: msg.docBase,
1010
1025
  mapperCtx: {
@@ -1019,8 +1034,11 @@ export function startCanvasIframe(opts: {
1019
1034
  popoverOpen: msg.popoverOpen ? serializeJxPath(msg.popoverOpen) : null,
1020
1035
  dialogOpen: msg.dialogOpen ? serializeJxPath(msg.dialogOpen) : null,
1021
1036
  siteStyle: msg.siteStyle,
1022
- ...(msg.allowAutoRequests ? { allowAutoRequests: true } : {}),
1023
- });
1037
+ };
1038
+ if (msg.allowAutoRequests) {
1039
+ renderOpts.allowAutoRequests = true;
1040
+ }
1041
+ handle = await renderResolvedDocument(renderOpts);
1024
1042
  if (gen === latestGen) {
1025
1043
  /* A render replaces the DOM, so the open attribute goes with it. The host sends the value
1026
1044
  on the render message for exactly this reason; a frame that kept only its own copy
@@ -1042,7 +1060,7 @@ export function startCanvasIframe(opts: {
1042
1060
  // BuildScope returns, and serializeDataScope reads defs[key], so the effect tracks those
1043
1061
  // Refs and RE-POSTS an updated snapshot when the data settles (the host gen-gates stale
1044
1062
  // Ones). Isolated in try/catch: a serialization failure never breaks the render ack above.
1045
- const defs = handle.ctx.defs as Record<string, unknown>;
1063
+ const { defs } = handle.ctx;
1046
1064
  stopDataScopeWatch = observeScope(() => {
1047
1065
  try {
1048
1066
  channel.post({ gen, kind: "dataScope", scope: serializeDataScope(defs) });
@@ -1054,11 +1072,7 @@ export function startCanvasIframe(opts: {
1054
1072
  postContentHeight();
1055
1073
  }
1056
1074
  } catch (error) {
1057
- channel.post({
1058
- gen,
1059
- kind: "renderError",
1060
- message: String((error as Error)?.message ?? error),
1061
- });
1075
+ channel.post({ gen, kind: "renderError", message: failureText(error) });
1062
1076
  }
1063
1077
  })();
1064
1078
  });
@@ -1094,7 +1108,9 @@ export function startCanvasIframe(opts: {
1094
1108
  interface BootWindow {
1095
1109
  location: { search: string };
1096
1110
  document: { querySelector: (selectors: string) => Element | null; body: HTMLElement };
1097
- parent: { postMessage: (message: unknown, targetOrigin: string) => void };
1111
+ parent: {
1112
+ postMessage: (message: CanvasEnvelope<IframeToParent>, targetOrigin: string) => void;
1113
+ };
1098
1114
  addEventListener: (type: "message", listener: (event: MessageEvent) => void) => void;
1099
1115
  removeEventListener: (type: "message", listener: (event: MessageEvent) => void) => void;
1100
1116
  }
@@ -1122,8 +1138,9 @@ export function bootCanvasIframe(win: BootWindow): () => void {
1122
1138
  "The parent origin did not round-trip; the channel relies on the shared token alone.",
1123
1139
  );
1124
1140
  }
1125
- const container = (win.document.querySelector("#jx-canvas-root") ??
1126
- win.document.body) as HTMLElement;
1141
+ // `canvas.html` draws `#jx-canvas-root` as a `<div>`; a page without it renders into `<body>`.
1142
+ const root = win.document.querySelector("#jx-canvas-root");
1143
+ const container = root instanceof HTMLElement ? root : win.document.body;
1127
1144
  const channel = postMessageChannel<IframeToParent, ParentToIframe>({
1128
1145
  acceptOrigin: parentOrigin,
1129
1146
  source: win,
@@ -1136,5 +1153,5 @@ export function bootCanvasIframe(win: BootWindow): () => void {
1136
1153
 
1137
1154
  // Boot only when actually loaded as the iframe document (has a real parent frame), never in tests.
1138
1155
  if (typeof window !== "undefined" && window.parent !== window) {
1139
- bootCanvasIframe(window as unknown as BootWindow);
1156
+ bootCanvasIframe(window);
1140
1157
  }
@@ -13,22 +13,39 @@
13
13
 
14
14
  import { evaluateExpression } from "@jxsuite/runtime/expression";
15
15
  import { resolveRef } from "@jxsuite/runtime";
16
+ import { isFunction, isJsonObject, isNonNullObject, isRef } from "@jxsuite/schema/guards";
16
17
  import { formatPreviewValue } from "../utils/preview-format";
18
+ import type { PreviewValue } from "../utils/preview-format";
17
19
 
18
- import type { ExpressionNode } from "@jxsuite/runtime/expression";
20
+ import type { JxScope } from "@jxsuite/runtime/types";
21
+ import type {
22
+ JsonValue,
23
+ JxDocumentValue,
24
+ JxExpressionNode,
25
+ JxMutableNode,
26
+ JxStateDefinition,
27
+ } from "@jxsuite/schema/types";
19
28
  import type { EvalExprResult } from "./iframe-protocol";
20
29
 
21
- type Scope = Record<string, unknown>;
30
+ /**
31
+ * Whether the raw (document) state entry is a pure named-formula (`$expression` + parameters).
32
+ *
33
+ * Looser than `isNamedFormulaDef`: an empty `parameters` array, or an `$expression` that is not an
34
+ * object, still qualifies.
35
+ */
36
+ function isNamedFormulaEntry(
37
+ entry: JxStateDefinition | undefined,
38
+ ): entry is JxStateDefinition & { parameters: JxDocumentValue[] } {
39
+ return isJsonObject(entry) && "$expression" in entry && Array.isArray(entry["parameters"]);
40
+ }
22
41
 
23
- /** Whether the raw (document) state entry is a pure named-formula (`$expression` + parameters). */
24
- function isNamedFormulaEntry(entry: unknown): boolean {
25
- return (
26
- typeof entry === "object" &&
27
- entry !== null &&
28
- !Array.isArray(entry) &&
29
- "$expression" in entry &&
30
- Array.isArray((entry as { parameters?: unknown }).parameters)
31
- );
42
+ /** A structured clone of `value`, or null when it holds something uncloneable (a function, a node). */
43
+ function cloneOrNull<T>(value: T): T | null {
44
+ try {
45
+ return structuredClone(value);
46
+ } catch {
47
+ return null;
48
+ }
32
49
  }
33
50
 
34
51
  /**
@@ -38,21 +55,27 @@ function isNamedFormulaEntry(entry: unknown): boolean {
38
55
  * callable (event handlers, structured-body functions, server fns) is dropped so a stray `call`
39
56
  * can't run a side effect against the live canvas.
40
57
  */
41
- export function cloneLiveScope(defs: Scope, rawState: Record<string, unknown> | null): Scope {
42
- const out: Scope = {};
58
+ export function cloneLiveScope(
59
+ defs: JxScope,
60
+ rawState: Record<string, JxStateDefinition> | null,
61
+ ): JxScope {
62
+ const out: JxScope = {};
43
63
  for (const key of Object.keys(defs)) {
44
64
  try {
45
65
  // Reading through the reactive proxy auto-unwraps a top-level ref/computed — and can throw (a
46
66
  // Computed getter that throws), which maps the key to null instead of aborting the clone.
47
67
  const value = defs[key];
48
- if (typeof value === "function") {
68
+ if (isFunction(value)) {
49
69
  if (isNamedFormulaEntry(rawState?.[key])) {
50
70
  out[key] = value; // A pure formula callable — safe (and needed) for `call` nodes.
51
71
  }
52
72
  continue;
53
73
  }
54
- const json = JSON.stringify(value);
55
- out[key] = json === undefined ? null : (JSON.parse(json) as unknown);
74
+ /* SAFETY: A widening. `JSON.stringify` answers undefined for undefined, a symbol or a function,
75
+ which lib.d.ts's `string` return type leaves out. */
76
+ const json = JSON.stringify(value) as string | undefined;
77
+ // SAFETY: `json` is JSON.stringify's own output above, so it parses back to JSON data.
78
+ out[key] = json === undefined ? null : (JSON.parse(json) as JsonValue);
56
79
  } catch {
57
80
  out[key] = null;
58
81
  }
@@ -69,44 +92,41 @@ export function cloneLiveScope(defs: Scope, rawState: Record<string, unknown> |
69
92
  * chain naturally (an inner `items` ref may read the outer `$map/item`).
70
93
  */
71
94
  export function bindRepeaterContext(
72
- scope: Scope,
73
- shadowDoc: unknown,
95
+ scope: JxScope,
96
+ shadowDoc: JxMutableNode | null,
74
97
  contextPath: (string | number)[] | null,
75
- ): Scope {
98
+ ): JxScope {
76
99
  if (!contextPath || contextPath.length === 0) {
77
100
  return scope;
78
101
  }
79
- let node: unknown = shadowDoc;
102
+ let node: JxDocumentValue | undefined = shadowDoc;
80
103
  let bound = scope;
81
104
  for (const seg of contextPath) {
82
- if (!node || typeof node !== "object") {
105
+ if (!isNonNullObject(node)) {
83
106
  break;
84
107
  }
85
- const rec = node as Record<string, unknown>;
86
- if (rec.$prototype === "Array" && seg === "map") {
108
+ /* SAFETY: The shadow doc is JSON, so every non-null object on the walk is a document object or
109
+ array, and indexing either by a path segment yields another document value or undefined. */
110
+ const rec = node as Record<string, JxDocumentValue | undefined>;
111
+ if (rec["$prototype"] === "Array" && seg === "map") {
87
112
  // Entering the repeater's template — bind the first item's context before descending.
88
- const itemsDef = rec.items;
89
- const items: unknown =
90
- itemsDef && typeof itemsDef === "object" && "$ref" in itemsDef
91
- ? resolveRef((itemsDef as { $ref: string }).$ref, bound)
92
- : itemsDef;
113
+ const itemsDef = rec["items"];
114
+ const items = isRef(itemsDef) ? resolveRef(itemsDef.$ref, bound) : itemsDef;
93
115
  if (Array.isArray(items) && items.length > 0) {
94
- let item: unknown;
95
- try {
96
- // Items resolved from the shadow doc (a literal array) must not be mutable through the
97
- // Preview scope — clone; scope-resolved items are already clone data, so this is free.
98
- item = structuredClone(items[0]);
99
- } catch {
100
- item = null;
101
- }
102
- const child = Object.create(bound) as Scope;
103
- child.$map = { index: 0, item };
116
+ const [first] = items;
117
+ // Items resolved from the shadow doc (a literal array) must not be mutable through the
118
+ // Preview scope — clone; scope-resolved items are already clone data, so this is free.
119
+ const item = cloneOrNull(first);
120
+ /* SAFETY: `Object.create(bound)` is an empty object whose prototype is the scope built so far,
121
+ so it is a scope that reads every outer key through and owns only the three set below. */
122
+ const child = Object.create(bound) as JxScope;
123
+ child["$map"] = { index: 0, item };
104
124
  child["$map/item"] = item;
105
125
  child["$map/index"] = 0;
106
126
  bound = child;
107
127
  }
108
128
  }
109
- node = rec[seg as keyof typeof rec];
129
+ node = rec[seg];
110
130
  }
111
131
  return bound;
112
132
  }
@@ -118,30 +138,34 @@ export function bindRepeaterContext(
118
138
  */
119
139
  export function evaluateLiveExprs(
120
140
  exprs: { id: string; node: unknown }[],
121
- defs: Scope,
122
- shadowDoc: unknown,
141
+ defs: JxScope,
142
+ shadowDoc: JxMutableNode | null,
123
143
  contextPath: (string | number)[] | null,
124
144
  ): EvalExprResult[] {
125
- const rawState =
126
- shadowDoc && typeof shadowDoc === "object"
127
- ? ((shadowDoc as { state?: Record<string, unknown> }).state ?? null)
128
- : null;
145
+ const rawState = shadowDoc?.state ?? null;
129
146
  return exprs.map(({ id, node }) => {
130
147
  const values = new Map<string, string>();
131
148
  // A fresh scope per expression: a mutating operator writes into this clone only, and can never
132
149
  // Leak into the next expression's evaluation (or the live canvas).
133
- let scope: Scope;
150
+ let scope: JxScope;
134
151
  try {
135
152
  scope = bindRepeaterContext(cloneLiveScope(defs, rawState), shadowDoc, contextPath);
136
153
  } catch (error) {
137
154
  return { error: error instanceof Error ? error.message : String(error), id, values: [] };
138
155
  }
139
156
  try {
140
- if (!node || typeof node !== "object" || !("operator" in node)) {
157
+ if (!isNonNullObject(node) || !("operator" in node)) {
141
158
  throw new Error("not an expression node");
142
159
  }
143
- evaluateExpression(node as ExpressionNode, scope, null, undefined, {
144
- report: (path, value) => values.set(path.join("/"), formatPreviewValue(value)),
160
+ /* SAFETY: `operator` is the key every expression node carries, and `evaluateExpression`
161
+ validates the operator itself, throwing on an unknown one into the catch below. */
162
+ void evaluateExpression(node as JxExpressionNode, scope, null, undefined, {
163
+ report: (path, value) => {
164
+ /* SAFETY: the trace reports raw runtime values, and PreviewValue names every category a JS
165
+ value falls in (primitive, bigint, symbol, function, array, record); formatting relies on
166
+ nothing beyond what JSON.stringify and String() accept for any value. */
167
+ values.set(path.join("/"), formatPreviewValue(value as PreviewValue));
168
+ },
145
169
  });
146
170
  return { id, values: [...values.entries()] };
147
171
  } catch (error) {