@jxsuite/studio 2.0.0 → 2.1.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 (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-0hzentwq.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-0hzentwq.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-2c188n41.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-97qcgvdn.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-hhj92gcr.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-ygzav7z5.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-n9zmpxjg.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +23711 -35185
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +34 -9
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +270 -262
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -120
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +75 -2
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +113 -0
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qct0gt8f.js +0 -531
  363. package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
  364. package/dist/chunks/files-02zn5y24.js +0 -50
  365. package/dist/chunks/files-02zn5y24.js.map +0 -9
  366. package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
  367. package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
  368. package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
  369. package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
  370. package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
  371. package/dist/chunks/settings-modal-gj0hrah4.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  381. package/dist/chunks/studio-568nx4t5.js +0 -469
  382. package/dist/chunks/studio-568nx4t5.js.map +0 -14
  383. package/dist/chunks/studio-9smfzqhc.js +0 -19
  384. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  385. package/dist/chunks/studio-asvf0j9e.js +0 -429
  386. package/dist/chunks/studio-asvf0j9e.js.map +0 -13
  387. package/dist/chunks/studio-d77qm3pk.js +0 -3427
  388. package/dist/chunks/studio-d77qm3pk.js.map +0 -26
  389. package/dist/chunks/studio-j6gqyjf4.js +0 -1854
  390. package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
  391. package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-rq0vxb19.js +0 -3744
  394. package/dist/chunks/studio-rq0vxb19.js.map +0 -22
  395. package/dist/chunks/studio-wd6ewdvd.js +0 -853
  396. package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
  397. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  398. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  399. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  400. package/dist/chunks/studio-ygzav7z5.js.map +0 -46
  401. package/dist/chunks/studio-zmy7241e.js +0 -399
  402. package/dist/chunks/studio-zmy7241e.js.map +0 -12
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-2c188n41.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-hhj92gcr.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -0,0 +1,67 @@
1
+ // src/settings/section-registry.ts
2
+ var DEFAULT_SETTINGS_SECTION = "overview";
3
+ var sections = new Map;
4
+ var listeners = new Set;
5
+ function announce() {
6
+ for (const listener of listeners) {
7
+ listener();
8
+ }
9
+ }
10
+ function notifySettingsDocument() {
11
+ announce();
12
+ }
13
+ function onSettingsDocumentChanged(listener) {
14
+ listeners.add(listener);
15
+ return () => {
16
+ listeners.delete(listener);
17
+ };
18
+ }
19
+ function registerSettingsSection(section) {
20
+ sections.set(section.key, section);
21
+ announce();
22
+ }
23
+ function unregisterSettingsSection(key) {
24
+ if (sections.delete(key)) {
25
+ announce();
26
+ }
27
+ }
28
+ function sortedSettingsSections() {
29
+ return [...sections.values()].toSorted((a, b) => a.order - b.order);
30
+ }
31
+ function settingsSectionKeys() {
32
+ return sortedSettingsSections().map((section) => section.key);
33
+ }
34
+ function settingsSection(key) {
35
+ return sections.get(key);
36
+ }
37
+ var _requested = null;
38
+ var _displayed = DEFAULT_SETTINGS_SECTION;
39
+ function settingsDocumentSection() {
40
+ if (_requested !== null && sections.has(_requested)) {
41
+ _displayed = _requested;
42
+ _requested = null;
43
+ return _displayed;
44
+ }
45
+ if (sections.has(_displayed)) {
46
+ return _displayed;
47
+ }
48
+ return settingsSectionKeys()[0] ?? _displayed;
49
+ }
50
+ function setSettingsSection(key) {
51
+ if (sections.has(key)) {
52
+ _displayed = key;
53
+ _requested = null;
54
+ } else {
55
+ _requested = key;
56
+ }
57
+ announce();
58
+ }
59
+ function resetSettingsDocumentState() {
60
+ _requested = null;
61
+ _displayed = DEFAULT_SETTINGS_SECTION;
62
+ }
63
+
64
+ export { DEFAULT_SETTINGS_SECTION, notifySettingsDocument, onSettingsDocumentChanged, registerSettingsSection, unregisterSettingsSection, sortedSettingsSections, settingsSectionKeys, settingsSection, settingsDocumentSection, setSettingsSection, resetSettingsDocumentState };
65
+
66
+ //# debugId=19468228E71CB42E64756E2164756E21
67
+ //# sourceMappingURL=studio-7afd21nw.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/settings/section-registry.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * The Project Settings section registry, and which of its sections the document is showing.\n *\n * `registerSettingsSection` is a **preserved public contract** (specs/extensions.md §9.1): an\n * extension's `project` class declares a `$studio.settings` block and `settings/extension-sections`\n * turns it into one of these records. P6 moved Project Settings out of a modal and into a document\n * in the pane; the registry did not move with it, because a section is a contribution to\n * CONFIGURATION, not to a dialog. Splitting it out is what lets the host be replaced without the\n * contribution point being touched.\n *\n * **This module holds no renderer and imports nothing.** That is load-bearing rather than tidy:\n * `panels/settings-pane.ts` is reached from `canvas/canvas-render.ts`, so anything this module\n * imports becomes part of the canvas's import graph. The section RENDERERS are registered by\n * `settings/settings-document.ts`, which the app loads when it registers its commands.\n *\n * **What is requested and what is displayed are two variables, and unregistering touches neither.**\n * The modal had one, and its `unregisterSettingsSection` reset it to `\"general\"` — which is half of\n * the deep-link race P6 exists to close. The contribution sync unregisters stale keys before it\n * registers fresh ones, so a section merely being REFRESHED took the caller's requested section\n * down with it, silently, after the awaited readiness promise had already resolved. Here a request\n * outlives its section going away and is satisfied the moment the key comes back.\n */\n\n/** A Project Settings section: an inner-nav entry plus a renderer for the content area. */\nexport interface SettingsSection {\n key: string;\n label: string;\n /** Nav icon name (reserved for future nav treatments). */\n icon?: string | undefined;\n /** Sort position — lower orders render higher in the inner nav. */\n order: number;\n render: (container: HTMLElement) => void;\n}\n\n/** Where a settings document lands when nobody named a section. */\nexport const DEFAULT_SETTINGS_SECTION = \"overview\";\n\nconst sections = new Map<string, SettingsSection>();\n\nconst listeners = new Set<() => void>();\n\n/**\n * Tell every subscriber something changed.\n *\n * A `Set` tolerates deletion during its own iteration, so a listener that unsubscribes itself (the\n * pane host, on unmount) is safe without copying.\n */\nfunction announce(): void {\n for (const listener of listeners) {\n listener();\n }\n}\n\n/**\n * Redraw the settings document — for a change this module cannot see, such as a command selecting\n * an entry inside the section that is already on screen.\n */\nexport function notifySettingsDocument(): void {\n announce();\n}\n\n/**\n * Subscribe to everything that changes what the settings document draws: the section set (an\n * extension registering or going away) and the chosen section. Returns the unsubscribe.\n *\n * @param {() => void} listener\n * @returns {() => void}\n */\nexport function onSettingsDocumentChanged(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n// ─── Registration ─────────────────────────────────────────────────────────────\n\n/**\n * Register (or replace) a settings section.\n *\n * @param {SettingsSection} section\n */\nexport function registerSettingsSection(section: SettingsSection): void {\n sections.set(section.key, section);\n announce();\n}\n\n/**\n * Remove a registered section — used when a descriptor-contributed section's extension is disabled\n * (see ./extension-sections). Built-ins are never unregistered.\n *\n * @param {string} key\n */\nexport function unregisterSettingsSection(key: string): void {\n if (sections.delete(key)) {\n announce();\n }\n}\n\n/** Registered sections sorted by order (registration order breaks ties). */\nexport function sortedSettingsSections(): SettingsSection[] {\n return [...sections.values()].toSorted((a, b) => a.order - b.order);\n}\n\n/** Every registered section key, built-ins and contributions alike, in display order. */\nexport function settingsSectionKeys(): string[] {\n return sortedSettingsSections().map((section) => section.key);\n}\n\n/**\n * One section by key, or `undefined`.\n *\n * @param {string} key\n * @returns {SettingsSection | undefined}\n */\nexport function settingsSection(key: string): SettingsSection | undefined {\n return sections.get(key);\n}\n\n// ─── Which section is on screen ───────────────────────────────────────────────\n\n/** The section the last caller ASKED for, kept until it is satisfied. */\nlet _requested: string | null = null;\n\n/** The section the document is drawing. Only a nav click and a satisfied request move it. */\nlet _displayed = DEFAULT_SETTINGS_SECTION;\n\n/**\n * The section key the document should render right now.\n *\n * A pending request wins as soon as its section exists. Otherwise the displayed one, and — when\n * that has been unregistered too — the first section there is, so the content area is never blank\n * because of bookkeeping.\n *\n * @returns {string}\n */\nexport function settingsDocumentSection(): string {\n if (_requested !== null && sections.has(_requested)) {\n _displayed = _requested;\n _requested = null;\n return _displayed;\n }\n if (sections.has(_displayed)) {\n return _displayed;\n }\n return settingsSectionKeys()[0] ?? _displayed;\n}\n\n/**\n * Show a section. A nav click satisfies itself immediately; a deep link to a section that has not\n * registered yet is remembered until it does.\n *\n * @param {string} key\n */\nexport function setSettingsSection(key: string): void {\n if (sections.has(key)) {\n _displayed = key;\n _requested = null;\n } else {\n _requested = key;\n }\n announce();\n}\n\n/** Forget the chosen section — the project-close and test hook. */\nexport function resetSettingsDocumentState(): void {\n _requested = null;\n _displayed = DEFAULT_SETTINGS_SECTION;\n}\n"
6
+ ],
7
+ "mappings": ";AAmCO,IAAM,2BAA2B;AAExC,IAAM,WAAW,IAAI;AAErB,IAAM,YAAY,IAAI;AAQtB,SAAS,QAAQ,GAAS;AAAA,EACxB,WAAW,YAAY,WAAW;AAAA,IAChC,SAAS;AAAA,EACX;AAAA;AAOK,SAAS,sBAAsB,GAAS;AAAA,EAC7C,SAAS;AAAA;AAUJ,SAAS,yBAAyB,CAAC,UAAkC;AAAA,EAC1E,UAAU,IAAI,QAAQ;AAAA,EACtB,OAAO,MAAM;AAAA,IACX,UAAU,OAAO,QAAQ;AAAA;AAAA;AAWtB,SAAS,uBAAuB,CAAC,SAAgC;AAAA,EACtE,SAAS,IAAI,QAAQ,KAAK,OAAO;AAAA,EACjC,SAAS;AAAA;AASJ,SAAS,yBAAyB,CAAC,KAAmB;AAAA,EAC3D,IAAI,SAAS,OAAO,GAAG,GAAG;AAAA,IACxB,SAAS;AAAA,EACX;AAAA;AAIK,SAAS,sBAAsB,GAAsB;AAAA,EAC1D,OAAO,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAAA;AAI7D,SAAS,mBAAmB,GAAa;AAAA,EAC9C,OAAO,uBAAuB,EAAE,IAAI,CAAC,YAAY,QAAQ,GAAG;AAAA;AASvD,SAAS,eAAe,CAAC,KAA0C;AAAA,EACxE,OAAO,SAAS,IAAI,GAAG;AAAA;AAMzB,IAAI,aAA4B;AAGhC,IAAI,aAAa;AAWV,SAAS,uBAAuB,GAAW;AAAA,EAChD,IAAI,eAAe,QAAQ,SAAS,IAAI,UAAU,GAAG;AAAA,IACnD,aAAa;AAAA,IACb,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AAAA,EACA,IAAI,SAAS,IAAI,UAAU,GAAG;AAAA,IAC5B,OAAO;AAAA,EACT;AAAA,EACA,OAAO,oBAAoB,EAAE,MAAM;AAAA;AAS9B,SAAS,kBAAkB,CAAC,KAAmB;AAAA,EACpD,IAAI,SAAS,IAAI,GAAG,GAAG;AAAA,IACrB,aAAa;AAAA,IACb,aAAa;AAAA,EACf,EAAO;AAAA,IACL,aAAa;AAAA;AAAA,EAEf,SAAS;AAAA;AAIJ,SAAS,0BAA0B,GAAS;AAAA,EACjD,aAAa;AAAA,EACb,aAAa;AAAA;",
8
+ "debugId": "19468228E71CB42E64756E2164756E21",
9
+ "names": []
10
+ }
@@ -91,5 +91,5 @@ function decodeFrame(data) {
91
91
 
92
92
  export { FRAME_DOC_SYNC, FRAME_AWARENESS, FRAME_DOC_CLOSE, FRAME_CONTROL, EnvelopeError, encodeFrame, decodeFrame };
93
93
 
94
- //# debugId=DAAAC2821D4C97A164756E2164756E21
95
- //# sourceMappingURL=studio-xze4zrs1.js.map
94
+ //# debugId=9834DA0DD0D8392964756E2164756E21
95
+ //# sourceMappingURL=studio-7bmdvzne.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../collab/src/envelope.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * The binary wire envelope every Jx collab provider speaks: the Cloudflare platform DO, the\n * devserver endpoint in the server package, and the browser client. One WebSocket per project\n * carries every open document, multiplexed by path:\n *\n * frame := varUint frameType, body\n * 0 DOC_SYNC := varString path, varUint docEpoch, varUint8Array y-protocols sync body\n * 1 AWARENESS := varUint8Array y-protocols awareness update (project-scoped)\n * 2 DOC_CLOSE := varString path (client → server unsubscribe)\n * 3 CONTROL := varString json (see ControlMessage)\n *\n * `docEpoch` is the server-owned lifetime counter of a document's Y history. Out-of-band content\n * replacement (git discard/pull/rename, non-collab writes) bumps it; frames carrying a stale epoch\n * are dropped and answered with a `doc-reset` control message, upon which the client destroys its\n * Y.Doc and re-opens. The invariant \"Y history is never deleted or replaced without an epoch bump\"\n * is what prevents divergent-history duplicate-content merges.\n *\n * The layout above is what the `jx.collab.v1` WebSocket subprotocol names. A change that would make\n * a peer mis-parse a frame is a new token, not a silent edit here — see `negotiate.ts` for the bump\n * rule and for why the capability probe, not the socket, is where the two sides agree.\n */\n\nimport * as decoding from \"lib0/decoding\";\nimport * as encoding from \"lib0/encoding\";\n\nexport { COLLAB_SUBPROTOCOL } from \"./negotiate.ts\";\n\nexport const FRAME_DOC_SYNC = 0;\nexport const FRAME_AWARENESS = 1;\nexport const FRAME_DOC_CLOSE = 2;\nexport const FRAME_CONTROL = 3;\n\nexport type CollabPermission = \"admin\" | \"write\" | \"read\";\n\n/** JSON payloads of CONTROL frames. */\nexport type ControlMessage =\n /** Server → client on accept: the socket's identity and effective permission. */\n | {\n type: \"hello\";\n login: string;\n name?: string;\n avatarUrl?: string;\n color: string;\n permission: CollabPermission;\n }\n /** Client → server: subscribe to a document (the client's Y.Doc must start EMPTY). */\n | { type: \"open\"; path: string }\n /** Server → client: the room is ready at this epoch; sync follows. */\n | { type: \"opened\"; path: string; epoch: number }\n /** Server → client: the doc's history was replaced; destroy the local Y.Doc and re-open. */\n | { type: \"doc-reset\"; path: string; epoch: number }\n /** Client → server: persist this doc to durable storage now (Cmd+S). */\n | { type: \"flush\"; path: string }\n /** Server → client: the flush landed. */\n | { type: \"flush-ack\"; path: string }\n /**\n * Server → client: the room's unsaved-since-last-persist state changed (drives the Save\n * affordance). Room-level and authoritative: any peer's edit dirties the room for everyone; a\n * persist clears it for everyone. Sent to a newly-subscribing connection during the open\n * handshake so it learns the current state.\n */\n | { type: \"doc-dirty\"; path: string; dirty: boolean }\n /**\n * Server → client: a request was refused (codes: read-only, content-not-loaded, too-large,\n * rate-limited, binary-file, unknown-frame).\n */\n | { type: \"error\"; path?: string; code: string; message: string };\n\nexport type CollabFrame =\n | { type: \"doc-sync\"; path: string; epoch: number; body: Uint8Array }\n | { type: \"awareness\"; body: Uint8Array }\n | { type: \"doc-close\"; path: string }\n | { type: \"control\"; message: ControlMessage };\n\nexport class EnvelopeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"EnvelopeError\";\n }\n}\n\nexport function encodeFrame(frame: CollabFrame): Uint8Array {\n const encoder = encoding.createEncoder();\n switch (frame.type) {\n case \"doc-sync\": {\n encoding.writeVarUint(encoder, FRAME_DOC_SYNC);\n encoding.writeVarString(encoder, frame.path);\n encoding.writeVarUint(encoder, frame.epoch);\n encoding.writeVarUint8Array(encoder, frame.body);\n break;\n }\n case \"awareness\": {\n encoding.writeVarUint(encoder, FRAME_AWARENESS);\n encoding.writeVarUint8Array(encoder, frame.body);\n break;\n }\n case \"doc-close\": {\n encoding.writeVarUint(encoder, FRAME_DOC_CLOSE);\n encoding.writeVarString(encoder, frame.path);\n break;\n }\n case \"control\": {\n encoding.writeVarUint(encoder, FRAME_CONTROL);\n encoding.writeVarString(encoder, JSON.stringify(frame.message));\n break;\n }\n default: {\n throw new EnvelopeError(`unknown-frame:${(frame as CollabFrame).type}`);\n }\n }\n return encoding.toUint8Array(encoder);\n}\n\nexport function decodeFrame(data: Uint8Array): CollabFrame {\n try {\n const decoder = decoding.createDecoder(data);\n const frameType = decoding.readVarUint(decoder);\n switch (frameType) {\n case FRAME_DOC_SYNC: {\n const path = decoding.readVarString(decoder);\n const epoch = decoding.readVarUint(decoder);\n const body = decoding.readVarUint8Array(decoder);\n return { body, epoch, path, type: \"doc-sync\" };\n }\n case FRAME_AWARENESS: {\n return { body: decoding.readVarUint8Array(decoder), type: \"awareness\" };\n }\n case FRAME_DOC_CLOSE: {\n return { path: decoding.readVarString(decoder), type: \"doc-close\" };\n }\n case FRAME_CONTROL: {\n const message = JSON.parse(decoding.readVarString(decoder)) as ControlMessage;\n if (typeof message !== \"object\" || typeof message.type !== \"string\") {\n throw new EnvelopeError(\"malformed-control\");\n }\n return { message, type: \"control\" };\n }\n default: {\n throw new EnvelopeError(`unknown-frame-type:${frameType}`);\n }\n }\n } catch (error) {\n if (error instanceof EnvelopeError) {\n throw error;\n }\n throw new EnvelopeError(\n `malformed-frame: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;;;;;;AA2BO,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AAAA;AA4CtB,MAAM,sBAAsB,MAAM;AAAA,EACvC,WAAW,CAAC,SAAiB;AAAA,IAC3B,MAAM,OAAO;AAAA,IACb,KAAK,OAAO;AAAA;AAEhB;AAEO,SAAS,WAAW,CAAC,OAAgC;AAAA,EAC1D,MAAM,UAAmB,cAAc;AAAA,EACvC,QAAQ,MAAM;AAAA,SACP,YAAY;AAAA,MACN,aAAa,SAAS,cAAc;AAAA,MACpC,eAAe,SAAS,MAAM,IAAI;AAAA,MAClC,aAAa,SAAS,MAAM,KAAK;AAAA,MACjC,mBAAmB,SAAS,MAAM,IAAI;AAAA,MAC/C;AAAA,IACF;AAAA,SACK,aAAa;AAAA,MACP,aAAa,SAAS,eAAe;AAAA,MACrC,mBAAmB,SAAS,MAAM,IAAI;AAAA,MAC/C;AAAA,IACF;AAAA,SACK,aAAa;AAAA,MACP,aAAa,SAAS,eAAe;AAAA,MACrC,eAAe,SAAS,MAAM,IAAI;AAAA,MAC3C;AAAA,IACF;AAAA,SACK,WAAW;AAAA,MACL,aAAa,SAAS,aAAa;AAAA,MACnC,eAAe,SAAS,KAAK,UAAU,MAAM,OAAO,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,aACS;AAAA,MACP,MAAM,IAAI,cAAc,iBAAkB,MAAsB,MAAM;AAAA,IACxE;AAAA;AAAA,EAEF,OAAgB,aAAa,OAAO;AAAA;AAG/B,SAAS,WAAW,CAAC,MAA+B;AAAA,EACzD,IAAI;AAAA,IACF,MAAM,UAAmB,cAAc,IAAI;AAAA,IAC3C,MAAM,YAAqB,YAAY,OAAO;AAAA,IAC9C,QAAQ;AAAA,WACD,gBAAgB;AAAA,QACnB,MAAM,OAAgB,cAAc,OAAO;AAAA,QAC3C,MAAM,QAAiB,YAAY,OAAO;AAAA,QAC1C,MAAM,OAAgB,kBAAkB,OAAO;AAAA,QAC/C,OAAO,EAAE,MAAM,OAAO,MAAM,MAAM,WAAW;AAAA,MAC/C;AAAA,WACK,iBAAiB;AAAA,QACpB,OAAO,EAAE,MAAe,kBAAkB,OAAO,GAAG,MAAM,YAAY;AAAA,MACxE;AAAA,WACK,iBAAiB;AAAA,QACpB,OAAO,EAAE,MAAe,cAAc,OAAO,GAAG,MAAM,YAAY;AAAA,MACpE;AAAA,WACK,eAAe;AAAA,QAClB,MAAM,UAAU,KAAK,MAAe,cAAc,OAAO,CAAC;AAAA,QAC1D,IAAI,OAAO,YAAY,YAAY,OAAO,QAAQ,SAAS,UAAU;AAAA,UACnE,MAAM,IAAI,cAAc,mBAAmB;AAAA,QAC7C;AAAA,QACA,OAAO,EAAE,SAAS,MAAM,UAAU;AAAA,MACpC;AAAA,eACS;AAAA,QACP,MAAM,IAAI,cAAc,sBAAsB,WAAW;AAAA,MAC3D;AAAA;AAAA,IAEF,OAAO,OAAO;AAAA,IACd,IAAI,iBAAiB,eAAe;AAAA,MAClC,MAAM;AAAA,IACR;AAAA,IACA,MAAM,IAAI,cACR,oBAAoB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAC3E;AAAA;AAAA;",
8
+ "debugId": "9834DA0DD0D8392964756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,128 @@
1
+ // src/panels/panel-scheduler.ts
2
+ function isTextInput(el) {
3
+ if (!el) {
4
+ return false;
5
+ }
6
+ const tag = el.tagName.toLowerCase();
7
+ if (tag === "input" || tag === "textarea") {
8
+ return true;
9
+ }
10
+ if (tag === "sp-textfield" || tag === "sp-number-field" || tag === "sp-search") {
11
+ return true;
12
+ }
13
+ if (el.shadowRoot?.activeElement) {
14
+ return isTextInput(el.shadowRoot.activeElement);
15
+ }
16
+ return false;
17
+ }
18
+ var boundSchedulers = new Set;
19
+ function describeRoot(root) {
20
+ if (root.id) {
21
+ return `#${root.id}`;
22
+ }
23
+ const first = root.className.split(/\s+/).find(Boolean);
24
+ return first ? `.${first}` : root.tagName.toLowerCase();
25
+ }
26
+ function pendingSchedulers() {
27
+ const blockers = [];
28
+ for (const entry of boundSchedulers) {
29
+ if (entry.hasFrame()) {
30
+ blockers.push(`${describeRoot(entry.root)} has a frame queued`);
31
+ } else if (entry.isDeferring()) {
32
+ blockers.push(`${describeRoot(entry.root)} is withholding a render (a field has focus)`);
33
+ }
34
+ }
35
+ return blockers;
36
+ }
37
+ function createPanelScheduler(opts) {
38
+ const { root, render, blockWhile } = opts;
39
+ let editing = false;
40
+ let scheduled = false;
41
+ let pending = false;
42
+ let rendering = false;
43
+ let rafId = 0;
44
+ const blocked = () => editing || (blockWhile ? blockWhile() : false);
45
+ function markStale(stale) {
46
+ if (stale) {
47
+ root.dataset.jxStale = "";
48
+ } else {
49
+ delete root.dataset.jxStale;
50
+ }
51
+ }
52
+ function flush() {
53
+ scheduled = false;
54
+ rafId = 0;
55
+ if (rendering) {
56
+ return;
57
+ }
58
+ if (blocked()) {
59
+ pending = true;
60
+ markStale(true);
61
+ return;
62
+ }
63
+ pending = false;
64
+ markStale(false);
65
+ rendering = true;
66
+ try {
67
+ render();
68
+ } finally {
69
+ rendering = false;
70
+ }
71
+ }
72
+ function schedule() {
73
+ if (scheduled) {
74
+ return;
75
+ }
76
+ scheduled = true;
77
+ rafId = requestAnimationFrame(flush);
78
+ }
79
+ function onFocusIn(e) {
80
+ editing = isTextInput(e.target);
81
+ }
82
+ function onFocusOut() {
83
+ editing = false;
84
+ if (pending) {
85
+ schedule();
86
+ }
87
+ }
88
+ const tracked = {
89
+ hasFrame: () => scheduled,
90
+ isDeferring: () => pending,
91
+ root
92
+ };
93
+ boundSchedulers.add(tracked);
94
+ return {
95
+ bindFocus() {
96
+ root.addEventListener("focusin", onFocusIn);
97
+ root.addEventListener("focusout", onFocusOut);
98
+ },
99
+ flushNow() {
100
+ if (rafId) {
101
+ cancelAnimationFrame(rafId);
102
+ }
103
+ rafId = 0;
104
+ scheduled = false;
105
+ flush();
106
+ },
107
+ isEditing: () => blocked(),
108
+ schedule,
109
+ unbind() {
110
+ boundSchedulers.delete(tracked);
111
+ root.removeEventListener("focusin", onFocusIn);
112
+ root.removeEventListener("focusout", onFocusOut);
113
+ if (rafId) {
114
+ cancelAnimationFrame(rafId);
115
+ }
116
+ scheduled = false;
117
+ pending = false;
118
+ editing = false;
119
+ markStale(false);
120
+ rendering = false;
121
+ }
122
+ };
123
+ }
124
+
125
+ export { pendingSchedulers, createPanelScheduler };
126
+
127
+ //# debugId=590200A08A20676A64756E2164756E21
128
+ //# sourceMappingURL=studio-8jpzqk5s.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/panels/panel-scheduler.ts"],
4
+ "sourcesContent": [
5
+ "/// <reference lib=\"dom\" />\n/**\n * Panel-scheduler.ts — Shared focus-aware render scheduler for Studio panels.\n *\n * Generalizes the guard that previously lived only in the right panel: render requests are\n * coalesced via requestAnimationFrame and DEFERRED while a text input inside the panel root is\n * focused, then flushed on focusout. Routing every render path (reactive effect, renderOnly(...),\n * explicit calls) through one scheduler means a focused field is never rebuilt mid-edit — which is\n * what previously truncated or dropped characters in the document/head sidebar.\n */\n\n/**\n * Is the element (or its shadow-DOM active descendant) a text-entry control whose value would be\n * clobbered by a re-render? Covers native inputs and the Spectrum web components used in panels.\n *\n * @param {Element | null} el\n * @returns {boolean}\n */\nexport function isTextInput(el: Element | null): boolean {\n if (!el) {\n return false;\n }\n const tag = el.tagName.toLowerCase();\n if (tag === \"input\" || tag === \"textarea\") {\n return true;\n }\n if (tag === \"sp-textfield\" || tag === \"sp-number-field\" || tag === \"sp-search\") {\n return true;\n }\n if (el.shadowRoot?.activeElement) {\n return isTextInput(el.shadowRoot.activeElement);\n }\n return false;\n}\n\n/**\n * Every bound scheduler, so \"is any panel still owing a repaint?\" has one answer.\n *\n * Condition 2 of the `probe.idle()` predicate (`services/idle.ts`, spec §13.5). Each scheduler\n * already knew whether it had a frame queued or a render withheld; nothing could ask all of them at\n * once. P4.4 makes the withheld case visible to the author too — a panel silently showing stale\n * state is a bug whichever consumer notices it first.\n */\nconst boundSchedulers = new Set<TrackedScheduler>();\n\ninterface TrackedScheduler {\n /** The panel root, for the human-readable blocker string. */\n root: HTMLElement;\n /** A coalescing frame is queued and will paint. */\n hasFrame: () => boolean;\n /** A render was requested and is being WITHHELD because a field in the panel has focus. */\n isDeferring: () => boolean;\n}\n\n/** `#right-panel`, `.frontmatter-panel`, `div` — the most specific handle the root offers. */\nfunction describeRoot(root: HTMLElement): string {\n if (root.id) {\n return `#${root.id}`;\n }\n const first = root.className.split(/\\s+/).find(Boolean);\n return first ? `.${first}` : root.tagName.toLowerCase();\n}\n\n/**\n * One line per panel that still owes a repaint — empty when every panel's DOM matches its state.\n *\n * A withheld render is reported separately from a queued one because they end differently: a queued\n * frame lands on its own, a withheld one waits for a focusout that may never come. A predicate that\n * conflated them would either hang or lie.\n */\nexport function pendingSchedulers(): string[] {\n const blockers: string[] = [];\n for (const entry of boundSchedulers) {\n if (entry.hasFrame()) {\n blockers.push(`${describeRoot(entry.root)} has a frame queued`);\n } else if (entry.isDeferring()) {\n blockers.push(`${describeRoot(entry.root)} is withholding a render (a field has focus)`);\n }\n }\n return blockers;\n}\n\nexport interface PanelScheduler {\n /** Request a render. Coalesced; deferred while a text input in the panel is focused. */\n schedule: () => void;\n /** True when a render would currently be deferred (text input focused or blockWhile()). */\n isEditing: () => boolean;\n /** Attach focusin/focusout listeners to the panel root. */\n bindFocus: () => void;\n /** Detach listeners and cancel any pending frame. */\n unbind: () => void;\n /** Render immediately, bypassing the rAF coalescing (still respects the focus guard). */\n flushNow: () => void;\n}\n\n/**\n * Create a focus-aware render scheduler bound to a panel root.\n *\n * @param {{\n * root: HTMLElement;\n * render: () => void;\n * blockWhile?: () => boolean;\n * }} opts\n * - `render` does the actual DOM paint; `blockWhile` is an extra defer predicate (e.g. a color\n * popover being open).\n * @returns {PanelScheduler}\n */\nexport function createPanelScheduler(opts: {\n root: HTMLElement;\n render: () => void;\n blockWhile?: () => boolean;\n}): PanelScheduler {\n const { root, render, blockWhile } = opts;\n let editing = false;\n let scheduled = false;\n let pending = false;\n let rendering = false;\n let rafId = 0;\n\n const blocked = () => editing || (blockWhile ? blockWhile() : false);\n\n /**\n * Publish the withheld render to the person looking at the panel.\n *\n * A deferred render is the panel deciding, correctly, that finishing your sentence matters more\n * than being current — but until P4 it made that trade in silence, so a panel showing state from\n * before your last edit was indistinguishable from a panel that had stopped working. The\n * attribute is the whole mechanism: `styles/overlays.css` hangs the hint off it, so every panel\n * that already routes through this scheduler inherits it without a line of its own.\n */\n function markStale(stale: boolean) {\n if (stale) {\n root.dataset.jxStale = \"\";\n } else {\n delete root.dataset.jxStale;\n }\n }\n\n function flush() {\n scheduled = false;\n rafId = 0;\n if (rendering) {\n return;\n }\n // Defer while a field is focused — flushed later by focusout (or the next schedule()).\n if (blocked()) {\n pending = true;\n markStale(true);\n return;\n }\n pending = false;\n markStale(false);\n rendering = true;\n try {\n render();\n } finally {\n rendering = false;\n }\n }\n\n function schedule() {\n if (scheduled) {\n return;\n }\n scheduled = true;\n rafId = requestAnimationFrame(flush);\n }\n\n function onFocusIn(e: FocusEvent) {\n editing = isTextInput(e.target as Element);\n }\n\n function onFocusOut() {\n // Clear the editing flag and schedule a flush. If focus is merely moving to another field in\n // The same panel, the synchronous focusin that follows re-sets `editing` before the rAF runs,\n // So the deferred render keeps waiting (no mid-edit clobber).\n editing = false;\n if (pending) {\n schedule();\n }\n }\n\n const tracked: TrackedScheduler = {\n hasFrame: () => scheduled,\n isDeferring: () => pending,\n root,\n };\n boundSchedulers.add(tracked);\n\n return {\n bindFocus() {\n root.addEventListener(\"focusin\", onFocusIn);\n root.addEventListener(\"focusout\", onFocusOut);\n },\n flushNow() {\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n rafId = 0;\n scheduled = false;\n flush();\n },\n isEditing: () => blocked(),\n schedule,\n unbind() {\n boundSchedulers.delete(tracked);\n root.removeEventListener(\"focusin\", onFocusIn);\n root.removeEventListener(\"focusout\", onFocusOut);\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n scheduled = false;\n pending = false;\n editing = false;\n markStale(false);\n rendering = false;\n },\n };\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "590200A08A20676A64756E2164756E21",
9
+ "names": []
10
+ }