@jxsuite/studio 6.1.1 → 8.0.0

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 (785) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/2020-5wtzce5g.js +4 -0
  3. package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
  4. package/dist/chunks/adapter-5tphg7xe.js +4 -0
  5. package/dist/chunks/add-new-flow-psym14sn.js +4 -0
  6. package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
  7. package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
  8. package/dist/chunks/color-area-6rbra5dy.js +4 -0
  9. package/dist/chunks/color-field-gy56c94g.js +4 -0
  10. package/dist/chunks/color-m7r1vk54.js +4 -0
  11. package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
  12. package/dist/chunks/combobox-72h32ejk.js +4 -0
  13. package/dist/chunks/components-r22xca09.js +4 -0
  14. package/dist/chunks/content-source-mmppmcyg.js +4 -0
  15. package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
  16. package/dist/chunks/dialog-c4x05vyx.js +4 -0
  17. package/dist/chunks/editor-ccd9jwsa.js +4 -0
  18. package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
  19. package/dist/chunks/extension-sections-0egb88dm.js +4 -0
  20. package/dist/chunks/file-ops-qnab36ek.js +4 -0
  21. package/dist/chunks/files-rcn56qvm.js +4 -0
  22. package/dist/chunks/format-host-yxz0kjjs.js +4 -0
  23. package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
  24. package/dist/chunks/grid-open-4z1g062t.js +4 -0
  25. package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
  26. package/dist/chunks/icons-63bjtbs7.js +4 -0
  27. package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
  28. package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
  29. package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
  30. package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
  31. package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
  32. package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
  33. package/dist/chunks/index-f0jn7nnp.js +4 -0
  34. package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
  35. package/dist/chunks/jsonMode-njkvsa02.js +13 -0
  36. package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
  37. package/dist/chunks/layers-bgyr11tr.js +4 -0
  38. package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
  39. package/dist/chunks/listbox-c421cf8c.js +4 -0
  40. package/dist/chunks/lit-html-v9gh687x.js +4 -0
  41. package/dist/chunks/media-library-sq468wts.js +4 -0
  42. package/dist/chunks/media-picker-shfe59pt.js +4 -0
  43. package/dist/chunks/menu-bdpzbfvs.js +4 -0
  44. package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
  45. package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
  46. package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
  47. package/dist/chunks/notify-kzrjr3fv.js +4 -0
  48. package/dist/chunks/number-field-y62xq0ty.js +4 -0
  49. package/dist/chunks/parse-v77xtwv7.js +4 -0
  50. package/dist/chunks/platform-7v4rtd7m.js +4 -0
  51. package/dist/chunks/popover-b89sfej7.js +4 -0
  52. package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
  53. package/dist/chunks/publish-quick-qx2455cj.js +4 -0
  54. package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
  55. package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
  56. package/dist/chunks/references-9547rg5s.js +4 -0
  57. package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
  58. package/dist/chunks/select-rzds841e.js +4 -0
  59. package/dist/chunks/source-control-kwktr9y6.js +4 -0
  60. package/dist/chunks/split-c9zfdgxf.js +4 -0
  61. package/dist/chunks/studio-03ct6yfv.js +9 -0
  62. package/dist/chunks/studio-07rcfje3.js +5 -0
  63. package/dist/chunks/studio-3e54qh39.js +7 -0
  64. package/dist/chunks/studio-3exxhz5g.js +5 -0
  65. package/dist/chunks/studio-3q40e3rj.js +5 -0
  66. package/dist/chunks/studio-3qeh9t0h.js +6 -0
  67. package/dist/chunks/studio-3qqjeep5.js +6 -0
  68. package/dist/chunks/studio-43sd2mam.js +4 -0
  69. package/dist/chunks/studio-4hp8pkyt.js +5 -0
  70. package/dist/chunks/studio-58xg6j2q.js +9 -0
  71. package/dist/chunks/studio-5g0rprdt.js +7 -0
  72. package/dist/chunks/studio-6m380wp7.js +5 -0
  73. package/dist/chunks/studio-80jyh1xh.js +4 -0
  74. package/dist/chunks/studio-83mk4bgg.js +9 -0
  75. package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
  76. package/dist/chunks/studio-8m0y2qe7.js +5 -0
  77. package/dist/chunks/studio-8tr6cfrc.js +5 -0
  78. package/dist/chunks/studio-8vcvfs7r.js +6 -0
  79. package/dist/chunks/studio-9tmebf0s.js +5 -0
  80. package/dist/chunks/studio-a2bvaptz.js +5 -0
  81. package/dist/chunks/studio-b7y5mr30.js +5 -0
  82. package/dist/chunks/studio-bavb31r0.js +5 -0
  83. package/dist/chunks/studio-bbe4c90a.js +5 -0
  84. package/dist/chunks/studio-c05wdnt3.js +5 -0
  85. package/dist/chunks/studio-ccv2svc6.js +5 -0
  86. package/dist/chunks/studio-d5grtb9e.js +16 -0
  87. package/dist/chunks/studio-df0baea9.js +5 -0
  88. package/dist/chunks/studio-dgk4dqtx.js +7 -0
  89. package/dist/chunks/studio-e1g64q43.js +5 -0
  90. package/dist/chunks/studio-ed1hp6zf.js +6 -0
  91. package/dist/chunks/studio-ed3xx40h.js +7 -0
  92. package/dist/chunks/studio-f14e1zdj.js +5 -0
  93. package/dist/chunks/studio-fbhxxc5f.js +5 -0
  94. package/dist/chunks/studio-fyh0jc96.js +5 -0
  95. package/dist/chunks/studio-gcxk20n7.js +5 -0
  96. package/dist/chunks/studio-jaaz8ce9.js +5 -0
  97. package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
  98. package/dist/chunks/studio-jsgf2q5k.js +7 -0
  99. package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
  100. package/dist/chunks/studio-k7evxqh4.js +5 -0
  101. package/dist/chunks/studio-kt3pjkwd.js +5 -0
  102. package/dist/chunks/studio-m8g16bgz.js +5 -0
  103. package/dist/chunks/studio-mn0476ag.js +5 -0
  104. package/dist/chunks/studio-mx1smyq0.js +5 -0
  105. package/dist/chunks/studio-n0c5h6mf.js +5 -0
  106. package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
  107. package/dist/chunks/studio-nqxqf8p2.js +4 -0
  108. package/dist/chunks/studio-p4nrkvqr.js +5 -0
  109. package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
  110. package/dist/chunks/studio-pgmvdv7z.js +7 -0
  111. package/dist/chunks/studio-ph84avkf.js +5 -0
  112. package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
  113. package/dist/chunks/studio-q0tccd43.js +5 -0
  114. package/dist/chunks/studio-q7rtx6zq.js +14 -0
  115. package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
  116. package/dist/chunks/studio-qmn1xc24.js +5 -0
  117. package/dist/chunks/studio-qwdqwkj0.js +5 -0
  118. package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
  119. package/dist/chunks/studio-rj9eamf8.js +5 -0
  120. package/dist/chunks/studio-rptgsk96.js +5 -0
  121. package/dist/chunks/studio-rthyg42z.js +928 -0
  122. package/dist/chunks/studio-s19tp1xr.js +5 -0
  123. package/dist/chunks/studio-s32578pn.js +5 -0
  124. package/dist/chunks/studio-svb7yyve.js +5 -0
  125. package/dist/chunks/studio-syreb644.js +5 -0
  126. package/dist/chunks/studio-tf9jryb1.js +10 -0
  127. package/dist/chunks/studio-tfkznv39.js +5 -0
  128. package/dist/chunks/studio-tft6r105.js +5 -0
  129. package/dist/chunks/studio-txf2kysx.js +5 -0
  130. package/dist/chunks/studio-v8867ddv.js +12 -0
  131. package/dist/chunks/studio-vxq7fcvv.js +5 -0
  132. package/dist/chunks/studio-w4rz9hdk.js +5 -0
  133. package/dist/chunks/studio-wbcjbhy1.js +9 -0
  134. package/dist/chunks/studio-wc649wss.js +5 -0
  135. package/dist/chunks/studio-wys23mxz.js +5 -0
  136. package/dist/chunks/studio-x1x167jh.js +5 -0
  137. package/dist/chunks/studio-x9hsze61.js +5 -0
  138. package/dist/chunks/studio-y0n7yxea.js +9 -0
  139. package/dist/chunks/studio-y3ahhdpx.js +5 -0
  140. package/dist/chunks/studio-z97c48fk.js +5 -0
  141. package/dist/chunks/studio-zat62m0c.js +5 -0
  142. package/dist/chunks/studio-zcd2e7yz.js +5 -0
  143. package/dist/chunks/studio-zz9qe3rw.js +64 -0
  144. package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
  145. package/dist/chunks/tabs-f5cw3tgp.js +4 -0
  146. package/dist/chunks/textfield-wewc8rq2.js +4 -0
  147. package/dist/chunks/toast-1gv0h53h.js +4 -0
  148. package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
  149. package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
  150. package/dist/chunks/tooltip-yypz28gq.js +4 -0
  151. package/dist/chunks/tree-9xa4hm7n.js +4 -0
  152. package/dist/chunks/tsMode-epyfz1hv.js +14 -0
  153. package/dist/chunks/workspace-dz7nxfhv.js +4 -0
  154. package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
  155. package/dist/chunks/ws-client-bv552sfx.js +4 -0
  156. package/dist/iframe-entry.js +20 -16
  157. package/dist/manifest.json +77 -63
  158. package/dist/studio.js +106 -107
  159. package/dist/workers/ts.worker.js +3 -3
  160. package/package.json +17 -16
  161. package/src/about/about-modal.ts +4 -3
  162. package/src/account/action-flow.ts +45 -38
  163. package/src/account-status.ts +7 -2
  164. package/src/browse/component-examples.ts +272 -0
  165. package/src/browse/library-commands.ts +64 -104
  166. package/src/browse/library-layouts.ts +270 -53
  167. package/src/browse/library-model.ts +194 -134
  168. package/src/browse/library-pane.ts +748 -440
  169. package/src/browse/library-preview.ts +161 -26
  170. package/src/browse/library-source.ts +308 -41
  171. package/src/browse/preview-root.ts +78 -0
  172. package/src/browse/preview-style.ts +155 -0
  173. package/src/canvas/asset-refs.ts +40 -10
  174. package/src/canvas/asset-resolve.ts +19 -23
  175. package/src/canvas/canvas-helpers.ts +7 -6
  176. package/src/canvas/canvas-live-render.ts +260 -77
  177. package/src/canvas/canvas-origin.ts +37 -12
  178. package/src/canvas/canvas-page-context.ts +112 -0
  179. package/src/canvas/canvas-patcher.ts +30 -30
  180. package/src/canvas/canvas-perf.ts +11 -5
  181. package/src/canvas/canvas-render.ts +175 -148
  182. package/src/canvas/canvas-surface.ts +5 -3
  183. package/src/canvas/canvas-utils.ts +147 -61
  184. package/src/canvas/dialog-path.ts +9 -4
  185. package/src/canvas/dialog-state.ts +1 -2
  186. package/src/canvas/diff-marks.ts +9 -16
  187. package/src/canvas/diff-toolbar.ts +8 -7
  188. package/src/canvas/edit-width-drag.ts +4 -1
  189. package/src/canvas/edit-width.ts +1 -3
  190. package/src/canvas/iframe-channel.ts +27 -13
  191. package/src/canvas/iframe-drop.ts +120 -12
  192. package/src/canvas/iframe-editable-root.ts +29 -16
  193. package/src/canvas/iframe-entry.ts +104 -75
  194. package/src/canvas/iframe-eval.ts +73 -49
  195. package/src/canvas/iframe-host.ts +269 -158
  196. package/src/canvas/iframe-inline-edit.ts +49 -30
  197. package/src/canvas/iframe-insert.ts +5 -4
  198. package/src/canvas/iframe-interaction.ts +30 -25
  199. package/src/canvas/iframe-keys.ts +11 -0
  200. package/src/canvas/iframe-overlay.ts +1 -1
  201. package/src/canvas/iframe-patch.ts +25 -21
  202. package/src/canvas/iframe-position.ts +12 -6
  203. package/src/canvas/iframe-protocol.ts +36 -21
  204. package/src/canvas/iframe-render.ts +84 -35
  205. package/src/canvas/iframe-slash.ts +24 -11
  206. package/src/canvas/iframe-subtree.ts +10 -3
  207. package/src/canvas/npm-modules.ts +22 -0
  208. package/src/canvas/path-mapping.ts +19 -12
  209. package/src/canvas/popover-path.ts +7 -3
  210. package/src/canvas/popover-state.ts +1 -2
  211. package/src/canvas/preview-navigate.ts +16 -0
  212. package/src/canvas/repeater-sources.ts +200 -0
  213. package/src/canvas/serialize-scope.ts +13 -5
  214. package/src/canvas/stage-scrollbar.ts +7 -2
  215. package/src/canvas/surface-registry.ts +27 -3
  216. package/src/collab/collab-commands.ts +7 -2
  217. package/src/collab/collab-session.ts +84 -45
  218. package/src/collab/collab-state.ts +4 -3
  219. package/src/collab/monaco-binding.ts +16 -13
  220. package/src/collab/monaco-cursors.ts +5 -2
  221. package/src/commands/app-commands.ts +16 -6
  222. package/src/commands/budget.ts +13 -11
  223. package/src/commands/command-args.ts +103 -71
  224. package/src/commands/context.ts +55 -28
  225. package/src/commands/defaults.ts +69 -45
  226. package/src/commands/keymap.ts +56 -43
  227. package/src/commands/levels.ts +14 -8
  228. package/src/commands/live-context.ts +9 -7
  229. package/src/commands/reference.ts +2 -1
  230. package/src/commands/registry.ts +22 -11
  231. package/src/commands/run-reported.ts +15 -10
  232. package/src/component-props.ts +46 -30
  233. package/src/content/collection-match.ts +11 -9
  234. package/src/content/collection-pages.ts +412 -0
  235. package/src/content/content-collections.ts +270 -0
  236. package/src/content/draft-state.ts +4 -3
  237. package/src/content/entry-commands.ts +54 -62
  238. package/src/content/entry-editor.ts +137 -32
  239. package/src/content/entry-fields.ts +25 -8
  240. package/src/content/entry-inspector.ts +225 -0
  241. package/src/content/entry-model.ts +38 -15
  242. package/src/content/entry-open.ts +80 -0
  243. package/src/content/entry-summaries.ts +440 -0
  244. package/src/content/file-record-ids.ts +80 -0
  245. package/src/content/file-records.ts +125 -0
  246. package/src/content/page-summaries.ts +129 -0
  247. package/src/content/record-entry.ts +201 -0
  248. package/src/content/writing-banner.ts +177 -0
  249. package/src/create/add-new-commands.ts +185 -0
  250. package/src/create/add-new-flow.ts +1116 -0
  251. package/src/create/add-new.ts +1014 -0
  252. package/src/create/element-name.ts +121 -0
  253. package/src/editor/canvas-context-menu.ts +1 -2
  254. package/src/editor/canvas-slash-bridge.ts +3 -6
  255. package/src/editor/content-slice.ts +16 -14
  256. package/src/editor/context-menu.ts +35 -22
  257. package/src/editor/convert-targets.ts +30 -35
  258. package/src/editor/convert-to-component.ts +78 -48
  259. package/src/editor/convert-to-repeater.ts +34 -22
  260. package/src/editor/editable-tags.ts +17 -2
  261. package/src/editor/file-drop-action.ts +29 -22
  262. package/src/editor/inline-edit-apply.ts +79 -17
  263. package/src/editor/inline-edit.ts +76 -50
  264. package/src/editor/inline-format.ts +59 -56
  265. package/src/editor/inline-link.ts +40 -15
  266. package/src/editor/insert-component.ts +91 -0
  267. package/src/editor/insert-zone-action.ts +14 -5
  268. package/src/editor/merge-tags.ts +58 -19
  269. package/src/editor/repeater-scope.ts +39 -28
  270. package/src/editor/shortcuts.ts +76 -42
  271. package/src/editor/slash-menu.ts +52 -14
  272. package/src/files/asset-versions.ts +4 -4
  273. package/src/files/components.ts +89 -20
  274. package/src/files/elements.ts +5 -6
  275. package/src/files/file-ops.ts +92 -41
  276. package/src/files/files.ts +248 -239
  277. package/src/files/fs-events.ts +18 -7
  278. package/src/files/media-meta.ts +97 -2
  279. package/src/files/media-paths.ts +3 -0
  280. package/src/files/media-types.ts +55 -0
  281. package/src/files/media-upload.ts +209 -52
  282. package/src/files/new-file-name.ts +156 -0
  283. package/src/files/serialize-document.ts +15 -5
  284. package/src/format/constraints.ts +1 -1
  285. package/src/format/convert-file.ts +27 -13
  286. package/src/format/format-choices.ts +2 -1
  287. package/src/format/format-host.ts +91 -50
  288. package/src/github/github-auth-status.ts +27 -3
  289. package/src/github/github-auth.ts +21 -11
  290. package/src/github/github-publish.ts +28 -23
  291. package/src/grid/cell-editors.ts +46 -31
  292. package/src/grid/cell-popovers.ts +5 -3
  293. package/src/grid/edit-buffer.ts +10 -9
  294. package/src/grid/grid-controller.ts +25 -23
  295. package/src/grid/grid-layout.ts +21 -5
  296. package/src/grid/grid-open.ts +3 -33
  297. package/src/grid/grid-panel.ts +65 -6
  298. package/src/grid/grid-reveal.ts +34 -0
  299. package/src/grid/grid-source.ts +9 -31
  300. package/src/grid/grid-view.ts +45 -23
  301. package/src/grid/redirects-grid.ts +14 -5
  302. package/src/grid/redirects.ts +16 -14
  303. package/src/grid/schema-columns.ts +25 -19
  304. package/src/grid/sources/connector-source.ts +47 -20
  305. package/src/grid/sources/content-source.ts +100 -31
  306. package/src/grid/sources/csv-file-source.ts +2 -2
  307. package/src/grid/tabulator-tables.d.ts +61 -34
  308. package/src/hosting/document.ts +2 -2
  309. package/src/hosting/stage.ts +7 -7
  310. package/src/i18n/i18n-commands.ts +3 -3
  311. package/src/media/media-commands.ts +181 -0
  312. package/src/media/media-library-model.ts +232 -0
  313. package/src/media/media-library.ts +1283 -0
  314. package/src/media/media-pane.ts +51 -20
  315. package/src/new-project/add-repo-modal.ts +20 -19
  316. package/src/new-project/import-tab.ts +10 -14
  317. package/src/new-project/location-fields.ts +2 -1
  318. package/src/new-project/new-project-modal.ts +12 -9
  319. package/src/packages/jxsuite-update.ts +4 -3
  320. package/src/packages/pull-package-sync.ts +26 -25
  321. package/src/page-params.ts +97 -68
  322. package/src/panels/activity-panel.ts +38 -14
  323. package/src/panels/ai-chat/attached-context.ts +13 -7
  324. package/src/panels/ai-chat/chat-markdown.ts +8 -8
  325. package/src/panels/ai-chat/chat-view.ts +80 -73
  326. package/src/panels/ai-chat/composer.ts +30 -33
  327. package/src/panels/ai-chat/sessions-view.ts +1 -2
  328. package/src/panels/ai-panel.ts +23 -20
  329. package/src/panels/block-action-bar.ts +57 -46
  330. package/src/panels/bottom-dock.ts +5 -3
  331. package/src/panels/canvas-dnd-bridge.ts +36 -26
  332. package/src/panels/chat-panel.ts +6 -6
  333. package/src/panels/collections-panel.ts +306 -0
  334. package/src/panels/component-preview.ts +35 -13
  335. package/src/panels/data-explorer.ts +63 -26
  336. package/src/panels/data-grid.ts +18 -11
  337. package/src/panels/dnd.ts +115 -138
  338. package/src/panels/editors.ts +52 -21
  339. package/src/panels/elements-panel.ts +19 -5
  340. package/src/panels/empty-state.ts +2 -2
  341. package/src/panels/events-panel.ts +84 -69
  342. package/src/panels/formula-workspace.ts +78 -54
  343. package/src/panels/frontmatter-fields.ts +33 -28
  344. package/src/panels/git-diff-open.ts +10 -6
  345. package/src/panels/head-panel.ts +488 -202
  346. package/src/panels/i18n-panel.ts +20 -12
  347. package/src/panels/imports-panel.ts +25 -47
  348. package/src/panels/jump-bar.ts +75 -31
  349. package/src/panels/layers-panel.ts +130 -101
  350. package/src/panels/left-panel.ts +25 -11
  351. package/src/panels/navigator-panels.ts +23 -11
  352. package/src/panels/pane-context.ts +140 -49
  353. package/src/panels/pane-grid.ts +55 -26
  354. package/src/panels/panel-registry.ts +36 -46
  355. package/src/panels/properties-panel.ts +182 -124
  356. package/src/panels/quick-search.ts +53 -31
  357. package/src/panels/right-panel.ts +201 -45
  358. package/src/panels/seo-modal.ts +54 -125
  359. package/src/panels/settings-menu.ts +63 -61
  360. package/src/panels/settings-pane.ts +268 -162
  361. package/src/panels/signals-panel.ts +156 -135
  362. package/src/panels/site-model.ts +367 -0
  363. package/src/panels/site-panel.ts +638 -0
  364. package/src/panels/statement-editor.ts +230 -140
  365. package/src/panels/style-panel.ts +253 -206
  366. package/src/panels/style-utils.ts +114 -51
  367. package/src/panels/stylebook-doc.ts +195 -60
  368. package/src/panels/stylebook-layers-panel.ts +48 -89
  369. package/src/panels/stylebook-panel.ts +60 -27
  370. package/src/panels/styles-panel.ts +327 -0
  371. package/src/panels/tab-drop.ts +27 -11
  372. package/src/panels/tab-strip.ts +143 -49
  373. package/src/platform-errors.ts +57 -43
  374. package/src/platform.ts +59 -31
  375. package/src/platforms/cloud.ts +373 -176
  376. package/src/platforms/default-platform.ts +14 -8
  377. package/src/platforms/devserver.ts +180 -142
  378. package/src/platforms/read-batcher.ts +16 -8
  379. package/src/project-list.ts +2 -1
  380. package/src/publish/deploy-checklist.ts +20 -9
  381. package/src/publish/pages-service.ts +66 -27
  382. package/src/publish/publish-changes.ts +491 -0
  383. package/src/publish/publish-commands.ts +88 -22
  384. package/src/publish/publish-ids.ts +49 -0
  385. package/src/publish/publish-panel.ts +10 -6
  386. package/src/publish/publish-quick.ts +148 -0
  387. package/src/publish/publish-workspace.ts +926 -0
  388. package/src/publish/source-control.ts +907 -0
  389. package/src/recent-projects.ts +15 -8
  390. package/src/resize-edges.ts +26 -36
  391. package/src/services/a11y-report.ts +26 -19
  392. package/src/services/agent-seed.ts +23 -11
  393. package/src/services/ai-ask.ts +9 -12
  394. package/src/services/ai-command-tools.ts +68 -62
  395. package/src/services/ai-import-tools.ts +80 -67
  396. package/src/services/ai-models.ts +17 -13
  397. package/src/services/ai-project-tools.ts +68 -32
  398. package/src/services/ai-session-store.ts +19 -10
  399. package/src/services/ai-system-prompt.ts +46 -20
  400. package/src/services/ai-tools.ts +71 -27
  401. package/src/services/ai-write-report.ts +20 -12
  402. package/src/services/ai-writes.ts +4 -4
  403. package/src/services/automation.ts +74 -51
  404. package/src/services/cem-export.ts +149 -58
  405. package/src/services/cf-settings.ts +4 -4
  406. package/src/services/clock.ts +6 -1
  407. package/src/services/code-services.ts +37 -31
  408. package/src/services/connection.ts +2 -2
  409. package/src/services/context-manager.ts +14 -10
  410. package/src/services/context-resolver.ts +20 -8
  411. package/src/services/data-service.ts +19 -15
  412. package/src/services/directory-picker.ts +20 -14
  413. package/src/services/document-assistant.ts +39 -19
  414. package/src/services/gated-registry.ts +10 -6
  415. package/src/services/harness/chat-reducer.ts +23 -1
  416. package/src/services/import-client.ts +91 -38
  417. package/src/services/import-seed.ts +8 -2
  418. package/src/services/jx-validate.ts +28 -31
  419. package/src/services/live-preview.ts +0 -0
  420. package/src/services/live-surfaces.ts +6 -3
  421. package/src/services/model-uri.ts +10 -2
  422. package/src/services/module-preloads.ts +12 -8
  423. package/src/services/monaco-buffer.ts +43 -24
  424. package/src/services/monaco-lazy.ts +7 -8
  425. package/src/services/monaco-setup.ts +23 -16
  426. package/src/services/notify.ts +44 -17
  427. package/src/services/popover-report.ts +25 -10
  428. package/src/services/preview-eval.ts +20 -8
  429. package/src/services/profile.ts +13 -6
  430. package/src/services/project-path.ts +13 -10
  431. package/src/services/references.ts +0 -0
  432. package/src/services/render-critic.ts +29 -9
  433. package/src/services/settings/definitions.ts +25 -14
  434. package/src/services/settings/kernel.ts +13 -4
  435. package/src/services/settings/write-queue.ts +9 -9
  436. package/src/services/token-lint.ts +12 -10
  437. package/src/services/tool-executor.ts +17 -5
  438. package/src/services/tool-outcomes.ts +44 -24
  439. package/src/services/trusted-types.ts +24 -7
  440. package/src/settings/contexts-section.ts +11 -8
  441. package/src/settings/contributed-section.ts +128 -70
  442. package/src/settings/css-vars-editor.ts +119 -32
  443. package/src/settings/defs-editor.ts +38 -35
  444. package/src/settings/developer-panels.ts +43 -0
  445. package/src/settings/extension-rows.ts +16 -8
  446. package/src/settings/extension-sections.ts +42 -14
  447. package/src/settings/extensions-section.ts +4 -1
  448. package/src/settings/general-settings.ts +101 -28
  449. package/src/settings/locales-section.ts +20 -12
  450. package/src/settings/preferences-dialog.ts +17 -7
  451. package/src/settings/preferences-keymap.ts +7 -5
  452. package/src/settings/preferences-sections.ts +11 -5
  453. package/src/settings/project-sections.ts +28 -11
  454. package/src/settings/schema-field-ui.ts +12 -1
  455. package/src/settings/section-registry.ts +116 -11
  456. package/src/settings/settings-dialog.ts +192 -0
  457. package/src/settings/settings-document.ts +186 -166
  458. package/src/shell/tree.ts +6 -5
  459. package/src/shell.ts +536 -477
  460. package/src/site-context.ts +101 -32
  461. package/src/state.ts +68 -57
  462. package/src/store.ts +54 -34
  463. package/src/studio.ts +219 -116
  464. package/src/style/live-preview.ts +1 -1
  465. package/src/style/project-styles.ts +40 -7
  466. package/src/style/stylebook-specimens.ts +89 -0
  467. package/src/style/stylebook-target.ts +26 -0
  468. package/src/style/tag-inheritance.ts +105 -0
  469. package/src/style/token-ref.ts +5 -4
  470. package/src/style/variables-focus.ts +61 -0
  471. package/src/style/variables-view.ts +235 -0
  472. package/src/surfaces/about.ts +18 -19
  473. package/src/surfaces/add-new.json +1482 -0
  474. package/src/surfaces/add-new.ts +325 -0
  475. package/src/surfaces/add-repo.ts +17 -19
  476. package/src/surfaces/ai-chat.ts +33 -38
  477. package/src/surfaces/ai-credentials-form.ts +6 -16
  478. package/src/surfaces/ai-managed-connect.ts +3 -4
  479. package/src/surfaces/ai-model-picker.ts +3 -5
  480. package/src/surfaces/block-action-bar.ts +22 -11
  481. package/src/surfaces/boot-failure.json +4 -3
  482. package/src/surfaces/boot-failure.ts +4 -5
  483. package/src/surfaces/bottom-dock.json +1 -1
  484. package/src/surfaces/bottom-dock.ts +9 -18
  485. package/src/surfaces/canvas-stage.json +30 -19
  486. package/src/surfaces/canvas-stage.ts +17 -16
  487. package/src/surfaces/cf-account-picker.ts +17 -18
  488. package/src/surfaces/collections-panel.json +615 -0
  489. package/src/surfaces/collections-panel.ts +168 -0
  490. package/src/surfaces/commandbar.json +241 -96
  491. package/src/surfaces/commandbar.ts +145 -105
  492. package/src/surfaces/convert-repeater.ts +17 -19
  493. package/src/surfaces/data-actions.ts +9 -7
  494. package/src/surfaces/dialog.ts +26 -28
  495. package/src/surfaces/diff-toolbar.ts +9 -7
  496. package/src/surfaces/empty-state.json +1 -1
  497. package/src/surfaces/empty-state.ts +7 -10
  498. package/src/surfaces/entry-editor.json +136 -0
  499. package/src/surfaces/entry-editor.ts +35 -11
  500. package/src/surfaces/entry-inspector.json +371 -0
  501. package/src/surfaces/entry-inspector.ts +143 -0
  502. package/src/surfaces/expression-editor.ts +11 -25
  503. package/src/surfaces/files-panel.ts +27 -14
  504. package/src/surfaces/formula-palette.ts +4 -5
  505. package/src/surfaces/github-auth.ts +16 -20
  506. package/src/surfaces/github-publish.ts +17 -22
  507. package/src/surfaces/grid-cell.ts +30 -31
  508. package/src/surfaces/grid-open.ts +10 -14
  509. package/src/surfaces/grid-panel.ts +13 -9
  510. package/src/surfaces/grid-replace.ts +13 -13
  511. package/src/surfaces/grid-views.ts +15 -18
  512. package/src/surfaces/inspector-dock.json +162 -14
  513. package/src/surfaces/inspector-dock.ts +59 -31
  514. package/src/surfaces/jump-bar.ts +5 -6
  515. package/src/surfaces/jxsuite-update.ts +16 -22
  516. package/src/surfaces/library-pane.json +670 -437
  517. package/src/surfaces/library-pane.ts +111 -77
  518. package/src/surfaces/logic-panel.ts +17 -30
  519. package/src/surfaces/logic-workspace.ts +13 -15
  520. package/src/surfaces/media-browser.json +62 -6
  521. package/src/surfaces/media-browser.ts +26 -11
  522. package/src/surfaces/media-field.json +1 -1
  523. package/src/surfaces/media-field.ts +4 -5
  524. package/src/surfaces/media-library.json +1586 -0
  525. package/src/surfaces/media-library.ts +282 -0
  526. package/src/surfaces/media-pane.ts +8 -7
  527. package/src/surfaces/media-pick-dialog.json +71 -0
  528. package/src/surfaces/media-pick-dialog.ts +132 -0
  529. package/src/surfaces/menu.ts +47 -23
  530. package/src/surfaces/navigator-dock.ts +11 -12
  531. package/src/surfaces/new-project.ts +27 -26
  532. package/src/surfaces/pane-context.json +144 -77
  533. package/src/surfaces/pane-context.ts +44 -25
  534. package/src/surfaces/pane-grid.ts +15 -10
  535. package/src/surfaces/panel-activity.ts +5 -6
  536. package/src/surfaces/panel-data.ts +3 -4
  537. package/src/surfaces/panel-deploy-checklist.json +12 -6
  538. package/src/surfaces/panel-deploy-checklist.ts +8 -7
  539. package/src/surfaces/panel-elements.ts +5 -7
  540. package/src/surfaces/panel-i18n.ts +5 -7
  541. package/src/surfaces/panel-imports.ts +6 -13
  542. package/src/surfaces/panel-outline.ts +25 -19
  543. package/src/surfaces/panel-page.json +72 -2
  544. package/src/surfaces/panel-page.ts +49 -25
  545. package/src/surfaces/panel-problems.ts +5 -7
  546. package/src/surfaces/panel-signals.json +1 -1
  547. package/src/surfaces/panel-signals.ts +25 -39
  548. package/src/surfaces/panel-stylebook-layers.json +71 -204
  549. package/src/surfaces/panel-stylebook-layers.ts +5 -29
  550. package/src/surfaces/preferences.json +120 -48
  551. package/src/surfaces/preferences.ts +29 -11
  552. package/src/surfaces/progress-modal.ts +15 -9
  553. package/src/surfaces/properties-panel.json +1 -1
  554. package/src/surfaces/properties-panel.ts +20 -42
  555. package/src/surfaces/publish-quick.json +428 -0
  556. package/src/surfaces/publish-quick.ts +165 -0
  557. package/src/surfaces/publish-workspace.json +2892 -0
  558. package/src/surfaces/publish-workspace.ts +391 -0
  559. package/src/surfaces/publish.ts +18 -18
  560. package/src/surfaces/push-plan.ts +7 -8
  561. package/src/surfaces/rail.json +1 -159
  562. package/src/surfaces/rail.ts +22 -79
  563. package/src/surfaces/reference-field.ts +11 -15
  564. package/src/surfaces/schema-builder.ts +16 -22
  565. package/src/surfaces/schema-form.json +10 -2
  566. package/src/surfaces/schema-form.ts +17 -25
  567. package/src/surfaces/secret-field.ts +9 -6
  568. package/src/surfaces/seo.json +1 -1
  569. package/src/surfaces/seo.ts +21 -15
  570. package/src/surfaces/settings-contexts.ts +9 -7
  571. package/src/surfaces/settings-contributed.json +5 -5
  572. package/src/surfaces/settings-contributed.ts +32 -12
  573. package/src/surfaces/settings-css-vars.json +44 -36
  574. package/src/surfaces/settings-css-vars.ts +82 -16
  575. package/src/surfaces/settings-defs.json +2 -2
  576. package/src/surfaces/settings-defs.ts +17 -21
  577. package/src/surfaces/settings-deploy.json +2 -15
  578. package/src/surfaces/settings-deploy.ts +9 -16
  579. package/src/surfaces/settings-dialog.json +51 -0
  580. package/src/surfaces/settings-dialog.ts +169 -0
  581. package/src/surfaces/settings-extensions.ts +5 -6
  582. package/src/surfaces/settings-head.ts +33 -39
  583. package/src/surfaces/settings-locales.ts +8 -20
  584. package/src/surfaces/settings-overview.json +3 -3
  585. package/src/surfaces/settings-overview.ts +14 -8
  586. package/src/surfaces/settings-packages.ts +8 -7
  587. package/src/surfaces/settings-pane.json +269 -46
  588. package/src/surfaces/settings-pane.ts +88 -36
  589. package/src/surfaces/settings-rawjson.ts +5 -6
  590. package/src/surfaces/shell.json +2 -1
  591. package/src/surfaces/shell.ts +1 -2
  592. package/src/surfaces/site-panel.json +1029 -0
  593. package/src/surfaces/site-panel.ts +233 -0
  594. package/src/surfaces/slash-menu.json +63 -21
  595. package/src/surfaces/slash-menu.ts +42 -9
  596. package/src/surfaces/statements.ts +13 -18
  597. package/src/surfaces/statusbar.ts +56 -29
  598. package/src/surfaces/style-panel.ts +18 -31
  599. package/src/surfaces/stylebook-chrome.ts +3 -5
  600. package/src/surfaces/styles-panel.json +735 -0
  601. package/src/surfaces/styles-panel.ts +195 -0
  602. package/src/surfaces/styles-variables.json +149 -0
  603. package/src/surfaces/styles-variables.ts +145 -0
  604. package/src/surfaces/tab-strip.json +4 -4
  605. package/src/surfaces/tab-strip.ts +14 -13
  606. package/src/surfaces/target-line.ts +6 -7
  607. package/src/surfaces/welcome.ts +6 -8
  608. package/src/surfaces/writing-banner.json +94 -0
  609. package/src/surfaces/writing-banner.ts +80 -0
  610. package/src/tabs/bare-repeaters.ts +101 -0
  611. package/src/tabs/patch-ops.ts +4 -3
  612. package/src/tabs/project-config.ts +32 -21
  613. package/src/tabs/selection.ts +36 -8
  614. package/src/tabs/tab.ts +99 -48
  615. package/src/tabs/transact.ts +98 -53
  616. package/src/types.ts +53 -43
  617. package/src/ui/ai-credentials-form.ts +10 -13
  618. package/src/ui/ai-model-picker.ts +3 -3
  619. package/src/ui/cf-account-picker.ts +7 -9
  620. package/src/ui/color-selector.ts +9 -5
  621. package/src/ui/dynamic-slot.ts +7 -8
  622. package/src/ui/expression-editor.ts +112 -105
  623. package/src/ui/form-controls.ts +104 -56
  624. package/src/ui/formula-catalog.ts +239 -230
  625. package/src/ui/formula-chips.ts +33 -18
  626. package/src/ui/layers.ts +57 -31
  627. package/src/ui/media-picker.ts +300 -47
  628. package/src/ui/popover-surface.ts +20 -12
  629. package/src/ui/progress-modal.ts +13 -8
  630. package/src/ui/regions.ts +14 -12
  631. package/src/ui/schema-form.ts +372 -97
  632. package/src/ui/surface.ts +71 -8
  633. package/src/ui/timing.ts +9 -0
  634. package/src/ui/value-source.ts +44 -31
  635. package/src/ui/virtual-window.ts +29 -3
  636. package/src/utils/base64.ts +6 -4
  637. package/src/utils/edit-display.ts +366 -111
  638. package/src/utils/element-selectors.ts +3 -2
  639. package/src/utils/google-fonts.ts +15 -14
  640. package/src/utils/inherited-style.ts +18 -20
  641. package/src/utils/link-target.ts +1 -1
  642. package/src/utils/local-day.ts +18 -0
  643. package/src/utils/preview-format.ts +25 -3
  644. package/src/utils/strip-events.ts +49 -22
  645. package/src/utils/studio-utils.ts +29 -14
  646. package/src/view.ts +2 -3
  647. package/src/workspace/pane-derive.ts +14 -16
  648. package/src/workspace/session.ts +81 -50
  649. package/src/workspace/tab-workspace.ts +137 -0
  650. package/src/workspace/workspace-back.ts +189 -0
  651. package/src/workspace/workspace-home.ts +133 -0
  652. package/src/workspace/workspace-ids.ts +129 -0
  653. package/src/workspace/workspace-switch.ts +372 -0
  654. package/src/workspace/workspace.ts +165 -47
  655. package/styles/shell-frame.css +30 -7
  656. package/styles/shell-frame.json +15 -3
  657. package/dist/chunks/2020-va2wwra4.js +0 -4
  658. package/dist/chunks/adapter-f93pafd7.js +0 -4
  659. package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
  660. package/dist/chunks/cf-settings-125tdm0w.js +0 -4
  661. package/dist/chunks/color-area-jqhna8zy.js +0 -4
  662. package/dist/chunks/color-field-embq5ctg.js +0 -4
  663. package/dist/chunks/color-fpezvnkt.js +0 -4
  664. package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
  665. package/dist/chunks/combobox-773hdzyj.js +0 -4
  666. package/dist/chunks/components-ax2f1fnn.js +0 -4
  667. package/dist/chunks/content-source-108aqtk1.js +0 -4
  668. package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
  669. package/dist/chunks/dialog-mtm9fq5t.js +0 -4
  670. package/dist/chunks/editor-pfgdmkb0.js +0 -4
  671. package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
  672. package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
  673. package/dist/chunks/file-ops-meej5mqf.js +0 -4
  674. package/dist/chunks/files-44vp8a2s.js +0 -4
  675. package/dist/chunks/format-host-7q1petb9.js +0 -4
  676. package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
  677. package/dist/chunks/git-panel-zngbymvd.js +0 -4
  678. package/dist/chunks/grid-view-sx9vynsp.js +0 -51
  679. package/dist/chunks/icons-p44xhjf0.js +0 -4
  680. package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
  681. package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
  682. package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
  683. package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
  684. package/dist/chunks/index-wkyfjeqz.js +0 -4
  685. package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
  686. package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
  687. package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
  688. package/dist/chunks/layers-xd92fg8d.js +0 -4
  689. package/dist/chunks/listbox-s8fkmnq8.js +0 -4
  690. package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
  691. package/dist/chunks/media-picker-0svzkdyb.js +0 -4
  692. package/dist/chunks/menu-37d07z9m.js +0 -4
  693. package/dist/chunks/menu-5c55ea3d.js +0 -4
  694. package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
  695. package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
  696. package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
  697. package/dist/chunks/notify-0xgtn8q1.js +0 -4
  698. package/dist/chunks/number-field-gw7sq8rn.js +0 -4
  699. package/dist/chunks/parse-897fvqah.js +0 -4
  700. package/dist/chunks/platform-v1qctbe6.js +0 -4
  701. package/dist/chunks/popover-8htra4er.js +0 -4
  702. package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
  703. package/dist/chunks/quick-search-a54e6t5n.js +0 -4
  704. package/dist/chunks/references-gmqp82fs.js +0 -4
  705. package/dist/chunks/right-panel-v7t9awbk.js +0 -4
  706. package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
  707. package/dist/chunks/select-n3v7gwas.js +0 -4
  708. package/dist/chunks/split-pff8f3ze.js +0 -4
  709. package/dist/chunks/studio-0bhx5hz6.js +0 -5
  710. package/dist/chunks/studio-0k1ddnyy.js +0 -6
  711. package/dist/chunks/studio-1b04pd0j.js +0 -64
  712. package/dist/chunks/studio-4dwbj6gb.js +0 -5
  713. package/dist/chunks/studio-4tanh828.js +0 -5
  714. package/dist/chunks/studio-55h4mstj.js +0 -4
  715. package/dist/chunks/studio-5tnvjkz4.js +0 -5
  716. package/dist/chunks/studio-60dqgb0c.js +0 -5
  717. package/dist/chunks/studio-61dp09qg.js +0 -9
  718. package/dist/chunks/studio-63epcrj2.js +0 -5
  719. package/dist/chunks/studio-74k29dy9.js +0 -5
  720. package/dist/chunks/studio-7vg6jcd3.js +0 -5
  721. package/dist/chunks/studio-7zx31knw.js +0 -9
  722. package/dist/chunks/studio-8bxk97km.js +0 -5
  723. package/dist/chunks/studio-933e30n4.js +0 -5
  724. package/dist/chunks/studio-98wnwhbg.js +0 -5
  725. package/dist/chunks/studio-9mccjwjh.js +0 -14
  726. package/dist/chunks/studio-a2ke1e4t.js +0 -5
  727. package/dist/chunks/studio-e3a2a6v3.js +0 -4
  728. package/dist/chunks/studio-e81q1vb9.js +0 -5
  729. package/dist/chunks/studio-epgrmqqm.js +0 -5
  730. package/dist/chunks/studio-ery42sqr.js +0 -4
  731. package/dist/chunks/studio-g1shz58g.js +0 -5
  732. package/dist/chunks/studio-gf0fz03c.js +0 -5
  733. package/dist/chunks/studio-gjtpe62q.js +0 -6
  734. package/dist/chunks/studio-gkskhg7m.js +0 -5
  735. package/dist/chunks/studio-gx4dnjzd.js +0 -5
  736. package/dist/chunks/studio-j03zga3y.js +0 -9
  737. package/dist/chunks/studio-jhpxeckz.js +0 -5
  738. package/dist/chunks/studio-k01r7ykp.js +0 -5
  739. package/dist/chunks/studio-kk7h30ne.js +0 -7
  740. package/dist/chunks/studio-kt1zqney.js +0 -5
  741. package/dist/chunks/studio-m3cwhvye.js +0 -5
  742. package/dist/chunks/studio-mcayt6hz.js +0 -5
  743. package/dist/chunks/studio-myjcghv3.js +0 -5
  744. package/dist/chunks/studio-n8bxwc3y.js +0 -4
  745. package/dist/chunks/studio-ngm8gvpb.js +0 -5
  746. package/dist/chunks/studio-nj5a01jy.js +0 -928
  747. package/dist/chunks/studio-pcgz8heb.js +0 -5
  748. package/dist/chunks/studio-qcsq0t15.js +0 -5
  749. package/dist/chunks/studio-qkstvve9.js +0 -5
  750. package/dist/chunks/studio-qv1pwd3c.js +0 -5
  751. package/dist/chunks/studio-rc6dvxjb.js +0 -7
  752. package/dist/chunks/studio-s8dmmz66.js +0 -5
  753. package/dist/chunks/studio-sp5xzbj4.js +0 -6
  754. package/dist/chunks/studio-szsjbj0g.js +0 -5
  755. package/dist/chunks/studio-t1xzawhr.js +0 -16
  756. package/dist/chunks/studio-tdcprbqb.js +0 -5
  757. package/dist/chunks/studio-vrmcjf9g.js +0 -7
  758. package/dist/chunks/studio-vyc0b4he.js +0 -10
  759. package/dist/chunks/studio-w0cgf6jg.js +0 -5
  760. package/dist/chunks/studio-w3hskzqk.js +0 -5
  761. package/dist/chunks/studio-xgrgcdyh.js +0 -9
  762. package/dist/chunks/studio-xz2yxfcb.js +0 -5
  763. package/dist/chunks/studio-y6n42tgs.js +0 -5
  764. package/dist/chunks/studio-yb560vxr.js +0 -5
  765. package/dist/chunks/studio-yn9f8vtx.js +0 -5
  766. package/dist/chunks/studio-yw05w8f0.js +0 -7
  767. package/dist/chunks/studio-z16sgavc.js +0 -5
  768. package/dist/chunks/studio-zey7zsdw.js +0 -12
  769. package/dist/chunks/studio-zyqn40w4.js +0 -5
  770. package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
  771. package/dist/chunks/tabs-jwthg40w.js +0 -4
  772. package/dist/chunks/textfield-spy3hc77.js +0 -4
  773. package/dist/chunks/toast-4d35zd64.js +0 -4
  774. package/dist/chunks/toast-host-8sjmfed3.js +0 -4
  775. package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
  776. package/dist/chunks/tree-h19v1jfz.js +0 -4
  777. package/dist/chunks/tsMode-2frah6h1.js +0 -14
  778. package/dist/chunks/workspace-zt81g1ms.js +0 -4
  779. package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
  780. package/src/panels/frontmatter-panel.ts +0 -701
  781. package/src/panels/git-panel.ts +0 -1120
  782. package/src/surfaces/doc-header.json +0 -776
  783. package/src/surfaces/doc-header.ts +0 -231
  784. package/src/surfaces/git-panel.json +0 -1880
  785. package/src/surfaces/git-panel.ts +0 -272
@@ -1,4 +1,5 @@
1
1
  /// <reference lib="dom" />
2
+ /// <reference lib="dom.iterable" />
2
3
  /**
3
4
  * Inline-format.js — Inline formatting engine for contenteditable editing
4
5
  *
@@ -22,6 +23,25 @@ const FORMAT_TAGS = new Set([
22
23
  "span",
23
24
  ]);
24
25
 
26
+ /** Whether `node` is an element. Decided by node type, so it holds for a node of any realm. */
27
+ function isElementNode(node: Node): node is Element {
28
+ return node.nodeType === Node.ELEMENT_NODE;
29
+ }
30
+
31
+ /** Whether `node` is a text node (`CDATASection` has its own node type and is excluded). */
32
+ function isTextNode(node: Node): node is Text {
33
+ return node.nodeType === Node.TEXT_NODE;
34
+ }
35
+
36
+ /** One edge-whitespace move {@link liftEdgeWhitespace} applies after its scan. */
37
+ interface EdgeWhitespaceLift {
38
+ type: "lift-leading" | "lift-trailing";
39
+ el: Element;
40
+ /** The wrapper's first (leading) or last (trailing) child, whose edge whitespace moves out. */
41
+ text: Text;
42
+ ws: string;
43
+ }
44
+
25
45
  /**
26
46
  * Check whether `tag` is currently active on both ends of the selection. Walks from anchor and
27
47
  * focus nodes up to editableRoot looking for the tag. Returns false if selection is outside
@@ -59,10 +79,7 @@ export function isTagActiveInSelection(tag: string, editableRoot: HTMLElement |
59
79
  const hasTag = (node: Node | null) => {
60
80
  let current = node;
61
81
  while (current && current !== editableRoot) {
62
- if (
63
- current.nodeType === Node.ELEMENT_NODE &&
64
- (current as Element).tagName.toLowerCase() === tag
65
- ) {
82
+ if (isElementNode(current) && current.tagName.toLowerCase() === tag) {
66
83
  return true;
67
84
  }
68
85
  current = current.parentNode;
@@ -121,20 +138,11 @@ export function toggleInlineFormat(tag: string, editableRoot: HTMLElement | null
121
138
  */
122
139
  function findIntersectingElements(tag: string, range: Range, root: HTMLElement) {
123
140
  const matches: Element[] = [];
124
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
125
- /**
126
- * @param {Node} node
127
- * @returns {number}
128
- */
129
- acceptNode(node: Node) {
130
- if ((node as Element).tagName.toLowerCase() === tag && range.intersectsNode(node)) {
131
- return NodeFilter.FILTER_ACCEPT;
132
- }
133
- return NodeFilter.FILTER_SKIP;
134
- },
135
- });
136
- while (walker.nextNode()) {
137
- matches.push(walker.currentNode as Element);
141
+ // Every descendant element, in document order: the same set a SHOW_ELEMENT tree walk visits.
142
+ for (const el of root.querySelectorAll("*")) {
143
+ if (el.tagName.toLowerCase() === tag && range.intersectsNode(el)) {
144
+ matches.push(el);
145
+ }
138
146
  }
139
147
  return matches;
140
148
  }
@@ -343,21 +351,19 @@ export function normalizeInlineContent(root: HTMLElement | null) {
343
351
  */
344
352
  function mergeAdjacentSiblings(root: HTMLElement) {
345
353
  let changed = false;
346
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
347
354
  const toMerge: [Element, Element][] = [];
348
355
 
349
356
  // Collect pairs first to avoid mutation during walk
350
- while (walker.nextNode()) {
351
- const el = walker.currentNode as Element;
357
+ for (const el of root.querySelectorAll("*")) {
352
358
  const next = el.nextSibling;
353
359
  if (
354
360
  next &&
355
- next.nodeType === Node.ELEMENT_NODE &&
356
- (next as Element).tagName === el.tagName &&
361
+ isElementNode(next) &&
362
+ next.tagName === el.tagName &&
357
363
  FORMAT_TAGS.has(el.tagName.toLowerCase()) &&
358
- attributesMatch(el, next as Element)
364
+ attributesMatch(el, next)
359
365
  ) {
360
- toMerge.push([el, next as Element]);
366
+ toMerge.push([el, next]);
361
367
  }
362
368
  }
363
369
 
@@ -383,27 +389,31 @@ function mergeAdjacentSiblings(root: HTMLElement) {
383
389
  */
384
390
  function collapseRedundantNesting(root: HTMLElement) {
385
391
  let changed = false;
386
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
387
392
  const toCollapse: Element[] = [];
388
393
 
389
- while (walker.nextNode()) {
390
- const el = walker.currentNode as Element;
394
+ for (const el of root.querySelectorAll("*")) {
391
395
  if (!FORMAT_TAGS.has(el.tagName.toLowerCase())) {
392
396
  continue;
393
397
  }
394
398
  // Check if only child is an element with the same tag
399
+ const only = el.firstChild;
395
400
  if (
396
401
  el.childNodes.length === 1 &&
397
- el.firstChild !== null &&
398
- el.firstChild.nodeType === Node.ELEMENT_NODE &&
399
- (el.firstChild as Element).tagName === el.tagName
402
+ only !== null &&
403
+ isElementNode(only) &&
404
+ only.tagName === el.tagName
400
405
  ) {
401
406
  toCollapse.push(el);
402
407
  }
403
408
  }
404
409
 
405
410
  for (const el of toCollapse) {
406
- const inner = el.firstChild as Element;
411
+ const inner = el.firstChild;
412
+ if (inner === null) {
413
+ /* Three or more nested identical wrappers: collapsing the outer pair moved this wrapper's only
414
+ child out, leaving it empty. That has always failed here, and is kept rather than changed. */
415
+ throw new TypeError("collapseRedundantNesting: an earlier collapse emptied this wrapper");
416
+ }
407
417
  // Replace outer with inner's children
408
418
  while (inner.firstChild) {
409
419
  inner.before(inner.firstChild);
@@ -422,11 +432,9 @@ function collapseRedundantNesting(root: HTMLElement) {
422
432
  */
423
433
  function removeEmptyInlines(root: HTMLElement) {
424
434
  let changed = false;
425
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
426
435
  const toRemove: Element[] = [];
427
436
 
428
- while (walker.nextNode()) {
429
- const el = walker.currentNode as Element;
437
+ for (const el of root.querySelectorAll("*")) {
430
438
  if (!FORMAT_TAGS.has(el.tagName.toLowerCase())) {
431
439
  continue;
432
440
  }
@@ -451,12 +459,9 @@ function removeEmptyInlines(root: HTMLElement) {
451
459
  */
452
460
  function liftEdgeWhitespace(root: HTMLElement) {
453
461
  let changed = false;
454
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
455
- /** @type {{ type: string; el: Element; ws: string }[]} */
456
- const ops = [];
462
+ const ops: EdgeWhitespaceLift[] = [];
457
463
 
458
- while (walker.nextNode()) {
459
- const el = walker.currentNode as Element;
464
+ for (const el of root.querySelectorAll("*")) {
460
465
  if (!FORMAT_TAGS.has(el.tagName.toLowerCase())) {
461
466
  continue;
462
467
  }
@@ -465,36 +470,36 @@ function liftEdgeWhitespace(root: HTMLElement) {
465
470
  }
466
471
 
467
472
  const first = el.firstChild;
468
- if (first && first.nodeType === Node.TEXT_NODE) {
469
- const text = first.textContent ?? "";
473
+ if (first && isTextNode(first)) {
474
+ const text = first.textContent;
470
475
  const m = text.match(/^(\s+)/);
471
476
  if (m && text.length > m[1]!.length) {
472
- ops.push({ el, type: "lift-leading", ws: m[1]! });
477
+ ops.push({ el, text: first, type: "lift-leading", ws: m[1]! });
473
478
  }
474
479
  }
475
480
 
476
481
  const last = el.lastChild;
477
- if (last && last.nodeType === Node.TEXT_NODE && last !== first) {
478
- const text = last.textContent ?? "";
482
+ if (last && isTextNode(last) && last !== first) {
483
+ const text = last.textContent;
479
484
  const m = text.match(/(\s+)$/);
480
485
  if (m && text.length > m[1]!.length) {
481
- ops.push({ el, type: "lift-trailing", ws: m[1]! });
486
+ ops.push({ el, text: last, type: "lift-trailing", ws: m[1]! });
482
487
  }
483
488
  }
484
489
  }
485
490
 
491
+ /* Each recorded text node is still its wrapper's edge child when its move runs: a move only edits
492
+ a text node's data and inserts a sibling OUTSIDE its own wrapper, and a wrapper whose edge child
493
+ is an element (the only place a nested move could insert) never recorded a move on that edge. */
486
494
  for (const op of ops) {
487
495
  if (op.type === "lift-leading") {
488
- const firstChild = op.el.firstChild as Text;
489
- firstChild.textContent = (firstChild.textContent ?? "").slice(op.ws.length);
496
+ op.text.textContent = op.text.textContent.slice(op.ws.length);
490
497
  op.el.parentNode?.insertBefore(document.createTextNode(op.ws), op.el);
491
- changed = true;
492
- } else if (op.type === "lift-trailing") {
493
- const lastChild = op.el.lastChild as Text;
494
- lastChild.textContent = (lastChild.textContent ?? "").slice(0, -op.ws.length);
498
+ } else {
499
+ op.text.textContent = op.text.textContent.slice(0, -op.ws.length);
495
500
  op.el.parentNode?.insertBefore(document.createTextNode(op.ws), op.el.nextSibling);
496
- changed = true;
497
501
  }
502
+ changed = true;
498
503
  }
499
504
  return changed;
500
505
  }
@@ -508,11 +513,9 @@ function liftEdgeWhitespace(root: HTMLElement) {
508
513
  */
509
514
  function unwrapBareSpans(root: HTMLElement) {
510
515
  let changed = false;
511
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
512
516
  const toUnwrap: Element[] = [];
513
517
 
514
- while (walker.nextNode()) {
515
- const el = walker.currentNode as Element;
518
+ for (const el of root.querySelectorAll("*")) {
516
519
  if (el.tagName.toLowerCase() !== "span") {
517
520
  continue;
518
521
  }
@@ -8,32 +8,57 @@
8
8
  * it here (Phase 4b-2).
9
9
  *
10
10
  * `document.execCommand` is uncoverable under happy-dom (no implementation), so it is wrapped in a
11
- * one-line shim {@link exec} that the branch logic calls; tests stub `document.execCommand` and
12
- * assert at the stub level (documented as stub-level, not behavioral).
11
+ * one-line shim {@link execEditingCommand} that the branch logic calls; tests stub
12
+ * `document.execCommand` and assert at the stub level (documented as stub-level, not behavioral).
13
13
  */
14
14
 
15
15
  import { normalizeInlineContent } from "./inline-format";
16
16
 
17
- /** The one uncoverable call, isolated so the surrounding branch logic stays unit-testable. */
18
- const exec = (cmd: string, val?: string): boolean => document.execCommand(cmd, false, val);
17
+ /**
18
+ * The one uncoverable call, isolated so the surrounding branch logic stays unit-testable, and the
19
+ * one place Studio reaches `document.execCommand`. It is deprecated, and NOT kept for the native
20
+ * undo stack: Studio owns history (`edit.undo` is forwarded out of the frame and a `historyUndo`
21
+ * `beforeinput` is rejected, studio.md §8.2.1). It is kept because it is the only script entry into
22
+ * the browser's editing engine, which a Range rewrite would not reproduce: `insertText` rebalances
23
+ * whitespace into `&nbsp;` runs (and back) around the caret, and `createLink` splits the anchor at
24
+ * inline-formatting boundaries it only partly covers.
25
+ */
26
+ export const execEditingCommand = (cmd: string, val?: string): boolean =>
27
+ // oxlint-disable-next-line typescript/no-deprecated -- no successor API exists: execCommand is the only script entry into the browser's editing engine (whitespace rebalancing, anchor splitting), see the doc comment above
28
+ document.execCommand(cmd, false, val);
29
+
30
+ /** The link the selection sits in, as the format toolbar's Link field shows it. */
31
+ export interface LinkState {
32
+ /** Whether the selection anchor is inside an `<a>`. */
33
+ active: boolean;
34
+ /** The author-entered URL of that `<a>`, or null when there is none. */
35
+ href: string | null;
36
+ }
37
+
38
+ /**
39
+ * Whether `node` is an `<a>` element. Decided by node type and name rather than `instanceof`, so it
40
+ * holds for nodes of another realm; for an element, `nodeName` is its tag name.
41
+ */
42
+ function isAnchorNode(node: Node): node is HTMLAnchorElement | SVGAElement {
43
+ return node.nodeType === Node.ELEMENT_NODE && node.nodeName.toLowerCase() === "a";
44
+ }
19
45
 
20
46
  /**
21
47
  * Read the link state of the current selection relative to `root`: walk the selection's anchor node
22
48
  * up to `root` looking for an `<a>`. Returns the author-entered `href` attribute (NOT the resolved
23
49
  * `.href` property), so relative/templated URLs round-trip unchanged.
24
50
  */
25
- export function linkStateForSelection(root: HTMLElement): { active: boolean; href: string | null } {
51
+ export function linkStateForSelection(root: HTMLElement): LinkState {
26
52
  const sel = window.getSelection();
27
53
  if (!sel || !sel.rangeCount) {
28
54
  return { active: false, href: null };
29
55
  }
30
56
  let node: Node | null = sel.anchorNode;
31
57
  while (node && node !== root) {
32
- if (node.nodeType === Node.ELEMENT_NODE && (node as Element).tagName.toLowerCase() === "a") {
58
+ if (isAnchorNode(node)) {
33
59
  // Design/edit renders anchors de-linked, with the URL on `data-jx-href` — so the toolbar's
34
60
  // Link field must read that first or it shows an empty URL for every existing link.
35
- const el = node as HTMLElement;
36
- return { active: true, href: el.dataset.jxHref ?? el.getAttribute("href") };
61
+ return { active: true, href: node.dataset.jxHref ?? node.getAttribute("href") };
37
62
  }
38
63
  node = node.parentNode;
39
64
  }
@@ -44,17 +69,17 @@ export function linkStateForSelection(root: HTMLElement): { active: boolean; hre
44
69
  * Find the `<a>` that contains the selection anchor (up to `root`), if any.
45
70
  *
46
71
  * @param {HTMLElement} root
47
- * @returns {HTMLAnchorElement | null}
72
+ * @returns {HTMLAnchorElement | SVGAElement | null}
48
73
  */
49
- function anchorInSelection(root: HTMLElement): HTMLAnchorElement | null {
74
+ function anchorInSelection(root: HTMLElement): HTMLAnchorElement | SVGAElement | null {
50
75
  const sel = window.getSelection();
51
76
  if (!sel || !sel.rangeCount) {
52
77
  return null;
53
78
  }
54
79
  let node: Node | null = sel.anchorNode;
55
80
  while (node && node !== root) {
56
- if (node.nodeType === Node.ELEMENT_NODE && (node as Element).tagName.toLowerCase() === "a") {
57
- return node as HTMLAnchorElement;
81
+ if (isAnchorNode(node)) {
82
+ return node;
58
83
  }
59
84
  node = node.parentNode;
60
85
  }
@@ -80,13 +105,13 @@ export function applyLink(root: HTMLElement, href: string | null): void {
80
105
  existing.replaceWith(frag);
81
106
  }
82
107
  } else if (href) {
83
- exec("createLink", href);
108
+ execEditingCommand("createLink", href);
84
109
  }
85
110
  normalizeInlineContent(root);
86
111
  }
87
112
 
88
- /** Insert a `${token}` template expression at the caret inside `root` (joins the native undo stack). */
113
+ /** Insert a `${token}` template expression at the caret inside `root`, through the editing engine. */
89
114
  export function insertTemplateToken(root: HTMLElement, token: string): void {
90
115
  root.focus();
91
- exec("insertText", `\${${token}}`);
116
+ execEditingCommand("insertText", `\${${token}}`);
92
117
  }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Inserting a component has one meaning everywhere (`specs/studio.md` §5.7, §9.1.3).
3
+ *
4
+ * A component instance is only a usable element in a document that imports it: the canvas drop did
5
+ * that, and the Insert panel's click, the slash menu and the canvas `+` did not, so a component
6
+ * clicked in rendered as an element the page could not resolve. This module is the one rule the
7
+ * four doors share — the instance comes from `buildComponentInstance`, and the import from the one
8
+ * `$elements` service, `files/elements.ts`'s `enableElement`.
9
+ *
10
+ * @docs studio/design/components
11
+ */
12
+
13
+ import { isString } from "@jxsuite/schema/guards";
14
+ import { buildComponentInstance, componentRegistry } from "../files/components";
15
+ import { enableElement } from "../files/elements";
16
+ import { mutateUpdateProperty } from "../tabs/transact";
17
+ import type { JxNodeValue } from "../tabs/transact";
18
+ import type { ElementsEntry } from "../files/elements";
19
+ import type { JxMutableNode } from "@jxsuite/schema/types";
20
+ import type { Tab } from "../tabs/tab";
21
+ import type { SlashCommand } from "./inline-edit";
22
+
23
+ /** The slash menu's group heading for the project's components. */
24
+ export const COMPONENTS_GROUP = "Components";
25
+
26
+ /**
27
+ * Import the component a node is an instance of into `tab`'s document, when it is one and is not
28
+ * imported yet. A node whose tag has no hyphen is an HTML element and is left alone, and a
29
+ * component the registry cannot name (an npm entry with no package, a local one with no path)
30
+ * changes nothing, so a document that had no `$elements` is not handed an empty one.
31
+ *
32
+ * A computed tag (`{ $expression }`) names no registered component, so it is left alone too.
33
+ *
34
+ * This is a MUTATION: call it inside the transaction that inserts the instance, so the instance and
35
+ * its import are one undo step. As a transaction of its own after the insert, the first ⌘Z took
36
+ * back only the import and left a document using a component it no longer imported, which saves as
37
+ * an instance the page cannot resolve.
38
+ *
39
+ * @param tab The document the node was inserted into, inside a `transactDoc`.
40
+ * @param tagName The inserted node's tag.
41
+ */
42
+ export function mutateImportComponent(tab: Tab, tagName: JxMutableNode["tagName"]): void {
43
+ const after = elementsImporting(tab, tagName);
44
+ if (after) {
45
+ /* Through the recorded mutator, not a bare assignment: a transaction that records ops is
46
+ undone by replaying their inverses, so an unrecorded write beside the insert would survive
47
+ the ⌘Z that took the instance back, and never reach a co-editor.
48
+ SAFETY: `$elements` entries are JSON — module specifiers, `{ $ref }` imports and inline
49
+ element definitions — which is what a node key holds. */
50
+ mutateUpdateProperty(tab, [], "$elements", after as JxNodeValue);
51
+ }
52
+ }
53
+
54
+ /** The document's `$elements` with the component imported, or null when nothing would change. */
55
+ function elementsImporting(tab: Tab, tagName: JxMutableNode["tagName"]): ElementsEntry[] | null {
56
+ if (!isString(tagName) || !tagName.includes("-")) {
57
+ return null;
58
+ }
59
+ const comp = componentRegistry.find((entry) => entry.tagName === tagName);
60
+ if (!comp) {
61
+ return null;
62
+ }
63
+ /* SAFETY: `$elements` holds module specifiers and `{ $ref }` imports; the document type and
64
+ files/elements.ts spell an inline entry as JxMutableNode and JxElement respectively, two editor
65
+ views of the same JSON object that enableElement only compares by `$ref`. */
66
+ const before = (tab.doc.document.$elements ?? []) as ElementsEntry[];
67
+ const after = enableElement(before, comp, tab.documentPath ?? null);
68
+ return after.length === before.length ? null : after;
69
+ }
70
+
71
+ /** A fresh instance of a registered component, or null for a tag the registry does not know. */
72
+ export function componentInstance(tagName: string): JxMutableNode | null {
73
+ const comp = componentRegistry.find((entry) => entry.tagName === tagName);
74
+ return comp ? buildComponentInstance(comp) : null;
75
+ }
76
+
77
+ /**
78
+ * Every registered component as a slash-menu offer, under the Components heading: the project's
79
+ * own, described by their definition file, and the ones installed packages provide, described by
80
+ * their package. A package component needs no prior enabling, because inserting one imports its
81
+ * package ({@link mutateImportComponent}), exactly as the canvas drop does.
82
+ */
83
+ export function componentSlashCommands(): SlashCommand[] {
84
+ return componentRegistry.map((comp) => ({
85
+ component: true,
86
+ description: (comp.source === "npm" ? comp.package : comp.path) ?? "",
87
+ group: COMPONENTS_GROUP,
88
+ label: `<${comp.tagName}>`,
89
+ tag: comp.tagName,
90
+ }));
91
+ }
@@ -7,11 +7,13 @@
7
7
  * name via `setInsertZoneClickHandler(runInsertZoneAction)` in studio.ts.
8
8
  *
9
9
  * The cross-origin insertion "+" (drawn by the host from posted zones) runs the parent-realm
10
- * slash-menu → mutateInsertNode flow on click. The host captured the zone (parentPath + index); the
11
- * new node is selected at its inserted path. Salvaged from the orphaned insertion-helper.ts.
10
+ * slash-menu → mutateInsertNode flow on click. The menu offers the HTML elements and, under a
11
+ * Components heading, the project's components. The host captured the zone (parentPath + index);
12
+ * the new node is selected at its inserted path. Salvaged from the orphaned insertion-helper.ts.
12
13
  */
13
14
 
14
15
  import { showSlashMenu } from "./slash-menu";
16
+ import { componentInstance, mutateImportComponent } from "./insert-component";
15
17
  import { defaultDef } from "../panels/shared";
16
18
  import { mutateInsertNode, transactDoc } from "../tabs/transact";
17
19
  import { activeTab } from "../workspace/workspace";
@@ -21,12 +23,19 @@ import type { JxPath } from "../state";
21
23
  export function runInsertZoneAction(btn: HTMLElement, zone: InsertZone): void {
22
24
  showSlashMenu(btn, "", {
23
25
  onSelect: (cmd) => {
24
- const def = defaultDef(cmd.tag);
25
- const insertPath = zone.insertParentPath as JxPath;
26
+ /* A pick from the Components group inserts an instance and imports the component, as a drop
27
+ of the same component does (§5.7); every other pick inserts the element's default. */
28
+ const instance = cmd.component === true ? componentInstance(cmd.tag) : null;
29
+ const def = instance ?? defaultDef(cmd.tag);
30
+ const insertPath: JxPath = zone.insertParentPath;
26
31
  const idx = zone.index;
27
32
  const newPath = [...insertPath, "children", idx];
28
- transactDoc(activeTab.value, (t) => {
33
+ const tab = activeTab.value;
34
+ transactDoc(tab, (t) => {
29
35
  mutateInsertNode(t, insertPath, idx, def);
36
+ if (instance) {
37
+ mutateImportComponent(t, instance.tagName);
38
+ }
30
39
  t.session.selection = [newPath];
31
40
  });
32
41
  },
@@ -9,8 +9,10 @@
9
9
  * Pure and DOM-free: callers pass the data in, this returns plain descriptors.
10
10
  */
11
11
 
12
+ import { isNonNullObject, isString } from "@jxsuite/schema/guards";
12
13
  import { defCategory } from "../panels/signals-panel";
13
14
  import { dataTypeLabel, unwrapSignal } from "../panels/data-explorer";
15
+ import type { JsonPrimitive, JxStateDefinition } from "@jxsuite/schema/types";
14
16
 
15
17
  export interface MergeTag {
16
18
  /** Insertion token placed between `${` and `}`, e.g. `state.user.name`, `item.title`, `index`. */
@@ -23,20 +25,50 @@ export interface MergeTag {
23
25
  category: string;
24
26
  }
25
27
 
28
+ /**
29
+ * A value in a live render scope, as far as the merge-tag walk reads it: document data, a handler,
30
+ * a pending (`undefined`) entry, or an object — a plain record, a fetched payload, a Vue ref —
31
+ * whose own keys hold further scope values.
32
+ */
33
+ export type ScopeValue =
34
+ | JsonPrimitive
35
+ | undefined
36
+ | bigint
37
+ | symbol
38
+ | ((...args: never[]) => void)
39
+ | ScopeValue[]
40
+ | ScopeRecord;
41
+
42
+ /** A render scope, or any object inside one, read key by key. */
43
+ export interface ScopeRecord {
44
+ readonly [key: string]: ScopeValue;
45
+ }
46
+
26
47
  /** Levels of nesting walked beneath each root name. */
27
48
  const DEPTH_CAP = 3;
28
49
  /** Maximum object keys enumerated per level (mirrors the data-explorer tree cap). */
29
50
  const BREADTH_CAP = 30;
30
51
 
52
+ /** Whether a scope value is an object read by key: non-null, not an array, not a function. */
53
+ function isScopeRecord(value: ScopeValue): value is ScopeRecord {
54
+ return isNonNullObject(value) && !Array.isArray(value);
55
+ }
56
+
57
+ /** The value behind a Vue ref, or the value itself. */
58
+ function unwrapScopeValue(value: ScopeValue): ScopeValue {
59
+ /* SAFETY: unwrapSignal returns its argument unchanged, or a ref's `.value`; a ref is a scope record,
60
+ so its `.value` member is itself a scope value. */
61
+ return unwrapSignal(value) as ScopeValue;
62
+ }
63
+
31
64
  /** Type label plus a short value preview for primitives. */
32
- function previewHint(value: unknown): string {
33
- const v = unwrapSignal(value);
65
+ function previewHint(value: ScopeValue): string {
66
+ const v = unwrapScopeValue(value);
34
67
  const typeLabel = dataTypeLabel(v);
35
- if (v === null || v === undefined || typeof v === "object") {
68
+ if (v === null || v === undefined || isNonNullObject(v)) {
36
69
  return typeLabel; // Null / pending / Array(n) / {n}
37
70
  }
38
- const text =
39
- typeof v === "string" ? (v.length > 24 ? `"${v.slice(0, 24)}…"` : `"${v}"`) : String(v);
71
+ const text = isString(v) ? (v.length > 24 ? `"${v.slice(0, 24)}…"` : `"${v}"`) : String(v);
40
72
  return `${typeLabel} · ${text}`;
41
73
  }
42
74
 
@@ -44,25 +76,25 @@ function previewHint(value: unknown): string {
44
76
  * Walk a resolved value, appending nested-path tags to `out`. Arrays contribute a `.length` tag and
45
77
  * stop (index access is context-dependent); plain objects recurse up to the depth/breadth caps.
46
78
  */
47
- function walk(value: unknown, prefix: string, category: string, depth: number, out: MergeTag[]) {
79
+ function walk(value: ScopeValue, prefix: string, category: string, depth: number, out: MergeTag[]) {
48
80
  if (depth >= DEPTH_CAP) {
49
81
  return;
50
82
  }
51
- const v = unwrapSignal(value);
52
- if (v === null || v === undefined || typeof v !== "object") {
53
- return;
54
- }
83
+ const v = unwrapScopeValue(value);
55
84
  if (Array.isArray(v)) {
56
85
  const token = `${prefix}.length`;
57
86
  out.push({ category, hint: `number · ${v.length}`, label: token, token });
58
87
  return;
59
88
  }
89
+ if (!isScopeRecord(v)) {
90
+ return;
91
+ }
60
92
  const keys = Object.keys(v).slice(0, BREADTH_CAP);
61
93
  for (const key of keys) {
62
94
  if (key.startsWith("$")) {
63
95
  continue; // Internal keys ($children, $ref, reactive plumbing) are not author-facing
64
96
  }
65
- const childVal = (v as Record<string, unknown>)[key];
97
+ const childVal = v[key];
66
98
  const childPrefix = `${prefix}.${key}`;
67
99
  out.push({ category, hint: previewHint(childVal), label: childPrefix, token: childPrefix });
68
100
  walk(childVal, childPrefix, category, depth + 1, out);
@@ -80,9 +112,9 @@ function walk(value: unknown, prefix: string, category: string, depth: number, o
80
112
  * carries a `$map` (repeater) context, `item` / `item.*` / `index` tags are appended.
81
113
  */
82
114
  export function buildMergeTags(
83
- state: Record<string, unknown> | null | undefined,
84
- scope: Record<string, unknown> | null | undefined,
85
- localScope: Record<string, unknown> | null = null,
115
+ state: Readonly<Record<string, JxStateDefinition>> | null | undefined,
116
+ scope: ScopeRecord | null | undefined,
117
+ localScope: ScopeRecord | null = null,
86
118
  ): MergeTag[] {
87
119
  const out: MergeTag[] = [];
88
120
  const defs = state ?? {};
@@ -103,13 +135,20 @@ export function buildMergeTags(
103
135
  }
104
136
 
105
137
  if (localScope) {
106
- const map = unwrapSignal(localScope.$map) as { item?: unknown; index?: unknown } | undefined;
107
- if (map && typeof map === "object") {
108
- out.push({ category: "repeater", hint: previewHint(map.item), label: "item", token: "item" });
109
- walk(map.item, "item", "repeater", 0, out);
138
+ const map = unwrapScopeValue(localScope.$map);
139
+ if (isNonNullObject(map)) {
140
+ // An array `$map` has no `item` / `index` members, so it reads as an empty row.
141
+ const row = isScopeRecord(map) ? map : undefined;
142
+ out.push({
143
+ category: "repeater",
144
+ hint: previewHint(row?.item),
145
+ label: "item",
146
+ token: "item",
147
+ });
148
+ walk(row?.item, "item", "repeater", 0, out);
110
149
  out.push({
111
150
  category: "repeater",
112
- hint: previewHint(map.index),
151
+ hint: previewHint(row?.index),
113
152
  label: "index",
114
153
  token: "index",
115
154
  });