@jxsuite/studio 2.0.1 → 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-799jpvhm.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-799jpvhm.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-8jxwts2p.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-gs6kqdt1.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-gs6kqdt1.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-esrewxap.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-v7jkjqng.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-jm0z592w.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 +21080 -32585
  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 +7 -0
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +221 -245
  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 -53
  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 +30 -1
  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 +7 -1
  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-qr3drkkw.js +0 -531
  363. package/dist/chunks/extension-sections-qr3drkkw.js.map +0 -12
  364. package/dist/chunks/files-j8a1t06k.js +0 -50
  365. package/dist/chunks/files-j8a1t06k.js.map +0 -9
  366. package/dist/chunks/git-panel-xtq5z81x.js +0 -28
  367. package/dist/chunks/git-panel-xtq5z81x.js.map +0 -9
  368. package/dist/chunks/layers-panel-ancn2wpq.js +0 -26
  369. package/dist/chunks/layers-panel-ancn2wpq.js.map +0 -9
  370. package/dist/chunks/settings-modal-17ttr96g.js +0 -29
  371. package/dist/chunks/settings-modal-17ttr96g.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-0xgs7xrs.js +0 -429
  381. package/dist/chunks/studio-0xgs7xrs.js.map +0 -13
  382. package/dist/chunks/studio-4d8hzcz5.js +0 -3427
  383. package/dist/chunks/studio-4d8hzcz5.js.map +0 -26
  384. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  385. package/dist/chunks/studio-9smfzqhc.js +0 -19
  386. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  387. package/dist/chunks/studio-jm0z592w.js.map +0 -115
  388. package/dist/chunks/studio-m2t4mdg5.js +0 -1854
  389. package/dist/chunks/studio-m2t4mdg5.js.map +0 -18
  390. package/dist/chunks/studio-n4p11dfy.js +0 -853
  391. package/dist/chunks/studio-n4p11dfy.js.map +0 -12
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-sjh1wt1a.js +0 -3744
  394. package/dist/chunks/studio-sjh1wt1a.js.map +0 -22
  395. package/dist/chunks/studio-v7jkjqng.js.map +0 -46
  396. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  397. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  398. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  399. package/dist/chunks/studio-yfcstdzy.js +0 -399
  400. package/dist/chunks/studio-yfcstdzy.js.map +0 -12
  401. package/dist/chunks/studio-zp7jncs8.js +0 -469
  402. package/dist/chunks/studio-zp7jncs8.js.map +0 -14
  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-8jxwts2p.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-esrewxap.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,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/panels/stylebook-doc.ts", "../src/style/project-styles.ts", "../src/panels/stylebook-panel.ts", "../src/commands/defaults.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Stylebook specimen-document generator — pure functions (no DOM) that turn the static element\n * catalog (data/stylebook-meta.json) plus the project's component registry into a plain JxDocument\n * the iframe canvas renders like any page. Each breakpoint panel renders the SAME generated doc in\n * a width-sized iframe, so `@media` blocks evaluate for real — this replaces the legacy parent-side\n * inline-style flatten (`buildStylebookElement`/`refreshStylebookStyles`).\n *\n * Two runtime facts shape {@link transposeStylebookStyle}:\n *\n * 1. The runtime's `applyStyle` emits `@media.selector` nesting but DROPS `selector.@media`\n * (`emitNested` skips `@` keys) — the legacy flatten honored both orders, so tag rules' embedded\n * `@name` blocks are HOISTED into the corresponding top-level `@name` block here.\n * 2. Tag-keyed rules on the generated root would restyle the card chrome (`div` rules hit chrome\n * divs), so every tag rule `T` is re-keyed to `` `& .element-card-preview ${T}` `` — applyStyle\n * resolves `&` to the root's `[data-jx=uid]` scope, confining the cascade to specimens.\n */\n\nimport { serializeJxPath } from \"../canvas/path-mapping\";\nimport type { StylebookEntry } from \"./stylebook-panel\";\nimport type { ComponentEntry } from \"../files/components\";\nimport type { JxPath } from \"../state\";\nimport type { JxMutableNode, JxStyle } from \"@jxsuite/schema/types\";\n\nexport interface StylebookDocResult {\n /** The specimen document (plain JSON — safe to post over the bridge). */\n doc: JxMutableNode;\n /** SerializeJxPath(path) → tag or compound (\"ul li\") for hit decoding. Chrome paths absent. */\n pathToTag: Map<string, string>;\n /** Tag/compound → the FIRST matching card's document path (selection-overlay measurement). */\n tagToCardPath: Map<string, JxPath>;\n}\n\n/** Selector-key classifier — a bare tag path like \"p\" or \"table th\" (mirrors style-panel's rule). */\nfunction isTagPath(key: string): boolean {\n return (\n !key.startsWith(\":\") &&\n !key.startsWith(\".\") &&\n !key.startsWith(\"&\") &&\n !key.startsWith(\"[\") &&\n !key.startsWith(\"@\") &&\n !key.startsWith(\"--\")\n );\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\n/** The specimen-scoping selector prefix (see module doc, runtime fact 2). */\nconst SPECIMEN_SCOPE = \"& .element-card-preview\";\n\n/** Deep-merge `add` into `base` (objects merge, scalars overwrite; add wins). */\nfunction mergeRules(\n base: Record<string, unknown> | undefined,\n add: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = { ...base };\n for (const [k, v] of Object.entries(add)) {\n out[k] = isPlainObject(v) && isPlainObject(out[k]) ? mergeRules(out[k], v) : v;\n }\n return out;\n}\n\n/** Drop nested `@` keys from a rule object (already-hoisted media can't nest deeper). */\nfunction stripAtKeys(rule: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(rule)) {\n if (isPlainObject(v) && k.startsWith(\"@\")) {\n continue;\n }\n out[k] = isPlainObject(v) ? stripAtKeys(v) : v;\n }\n return out;\n}\n\n/**\n * Transform the merged effective document style into the generated root's style block: flat scalars\n * and `--` custom props stay at the top (inheritance into specimens), tag rules are re-keyed under\n * {@link SPECIMEN_SCOPE}, and `selector.@media` nesting is hoisted into top-level `@name` blocks\n * (both per the module doc). Shared by the doc generator and the live `styleUpdate` fast path so an\n * edit round-trips through the exact same transform.\n */\nexport function transposeStylebookStyle(effectiveStyle: JxStyle): JxStyle {\n const style = effectiveStyle as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n const mediaOut: Record<string, Record<string, unknown>> = {};\n\n /** Re-key + hoist one tag rule subtree; returns the cleaned (media-free) rule. */\n const processTagRule = (\n rule: Record<string, unknown>,\n tagPath: string,\n ): Record<string, unknown> => {\n const cleaned: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(rule)) {\n if (!isPlainObject(v)) {\n cleaned[k] = v;\n continue;\n }\n if (k.startsWith(\"@\")) {\n if (k === \"@--\") {\n continue; // Base canvas width marker, not a real query.\n }\n mediaOut[k] ??= {};\n const bucket = mediaOut[k];\n const sel = `${SPECIMEN_SCOPE} ${tagPath}`;\n bucket[sel] = mergeRules(\n bucket[sel] as Record<string, unknown> | undefined,\n stripAtKeys(v),\n );\n continue;\n }\n if (isTagPath(k)) {\n cleaned[k] = processTagRule(v, `${tagPath} ${k}`);\n continue;\n }\n cleaned[k] = v; // Pseudo/class/& sub-rules ride along under the re-keyed parent.\n }\n return cleaned;\n };\n\n for (const [k, v] of Object.entries(style)) {\n if (!isPlainObject(v)) {\n out[k] = v; // Flat scalars + -- custom props.\n continue;\n }\n if (k.startsWith(\"@\")) {\n if (k === \"@--\") {\n continue;\n }\n // Media block: re-key tag rules inside; non-tag keys (scalars/pseudo) apply to the root.\n mediaOut[k] ??= {};\n const bucket = mediaOut[k];\n for (const [mk, mv] of Object.entries(v)) {\n if (isPlainObject(mv) && isTagPath(mk)) {\n const sel = `${SPECIMEN_SCOPE} ${mk}`;\n bucket[sel] = mergeRules(bucket[sel] as Record<string, unknown> | undefined, mv);\n } else {\n bucket[mk] = mv;\n }\n }\n continue;\n }\n if (isTagPath(k)) {\n out[`${SPECIMEN_SCOPE} ${k}`] = processTagRule(v, k);\n continue;\n }\n out[k] = v;\n }\n\n for (const [mk, mv] of Object.entries(mediaOut)) {\n out[mk] = isPlainObject(out[mk]) ? mergeRules(out[mk] as Record<string, unknown>, mv) : mv;\n }\n return out as JxStyle;\n}\n\n/** Resolve a nested tag path (\"table th\") in a style object; null when absent. */\nfunction resolveNestedStyle(\n style: Record<string, unknown>,\n tagPath: string,\n): Record<string, unknown> | null {\n const parts = tagPath.split(\" \");\n let obj: unknown = style;\n for (const part of parts) {\n if (!isPlainObject(obj)) {\n return null;\n }\n obj = obj[part];\n }\n return isPlainObject(obj) ? obj : null;\n}\n\n/** Whether the effective style customizes `tagPath` (directly or under any `@media` block). */\nexport function hasTagStyle(rootStyle: JxStyle, tagPath: string): boolean {\n const style = rootStyle as Record<string, unknown>;\n const direct = resolveNestedStyle(style, tagPath);\n if (direct && Object.keys(direct).length > 0) {\n return true;\n }\n for (const [key, val] of Object.entries(style)) {\n if (!key.startsWith(\"@\") || !isPlainObject(val)) {\n continue;\n }\n const nested = resolveNestedStyle(val, tagPath);\n if (nested && Object.keys(nested).length > 0) {\n return true;\n }\n }\n return false;\n}\n\n/** Options for {@link buildStylebookDoc}. */\nexport interface BuildStylebookDocOpts {\n meta: { $sections: { label: string; elements: StylebookEntry[] }[] };\n components: ComponentEntry[];\n /** Merged document+project style (getEffectiveStyle output) — transposed here. */\n effectiveStyle: JxStyle;\n /** Merged $media map (getEffectiveMedia output) — becomes the doc's $media. */\n effectiveMedia: Record<string, string>;\n filter: string;\n customizedOnly: boolean;\n projectRoot: string | null;\n}\n\n/**\n * Build the specimen document + path↔tag maps. Deterministic: paths are recorded as the tree is\n * assembled, so the parent can decode `hit` paths and measure selection cards without reading the\n * iframe DOM.\n */\nexport function buildStylebookDoc(opts: BuildStylebookDocOpts): StylebookDocResult {\n const pathToTag = new Map<string, string>();\n const tagToCardPath = new Map<string, JxPath>();\n const filter = opts.filter.toLowerCase();\n\n /** Register a specimen subtree's paths: root → tag; descendants → compound (legacy semantics). */\n const registerSpecimenPaths = (entry: StylebookEntry, path: JxPath, rootTag: string): void => {\n const compound = entry.tag === rootTag ? rootTag : `${rootTag} ${entry.tag}`;\n pathToTag.set(serializeJxPath(path), compound);\n const kids = entry.children ?? [];\n for (const [i, child] of kids.entries()) {\n registerSpecimenPaths(child, [...path, \"children\", i], rootTag);\n }\n };\n\n const specimenNode = (entry: StylebookEntry): JxMutableNode => {\n const attributes: Record<string, string> = { ...entry.attributes };\n if (entry.style) {\n attributes.style = entry.style; // Inline CSS text — legacy `el.style.cssText` parity.\n }\n return {\n tagName: entry.tag,\n ...(entry.text ? { textContent: entry.text } : {}),\n ...(Object.keys(attributes).length > 0 ? { attributes } : {}),\n ...(entry.children ? { children: entry.children.map(specimenNode) } : {}),\n } as JxMutableNode;\n };\n\n /** A card wrapping one specimen; registers card/preview/specimen paths under `tag`. */\n const cardNode = (\n tag: string,\n label: string,\n specimen: JxMutableNode,\n cardPath: JxPath,\n entryForPaths: StylebookEntry | null,\n ): JxMutableNode => {\n pathToTag.set(serializeJxPath(cardPath), tag);\n pathToTag.set(serializeJxPath([...cardPath, \"children\", 0]), tag);\n const specimenPath = [...cardPath, \"children\", 0, \"children\", 0];\n if (entryForPaths) {\n registerSpecimenPaths(entryForPaths, specimenPath, tag);\n } else {\n pathToTag.set(serializeJxPath(specimenPath), tag);\n }\n if (!tagToCardPath.has(tag)) {\n tagToCardPath.set(tag, cardPath);\n }\n return {\n attributes: { class: \"element-card\" },\n children: [\n { attributes: { class: \"element-card-preview\" }, children: [specimen], tagName: \"div\" },\n { attributes: { class: \"element-card-label\" }, tagName: \"div\", textContent: label },\n ],\n tagName: \"div\",\n } as JxMutableNode;\n };\n\n const sections: JxMutableNode[] = [];\n const sectionNode = (label: string, cards: JxMutableNode[]): JxMutableNode =>\n ({\n attributes: { class: \"sb-section\" },\n children: [\n { attributes: { class: \"sb-label\" }, tagName: \"div\", textContent: label },\n { attributes: { class: \"sb-body\" }, children: cards, tagName: \"div\" },\n ],\n tagName: \"div\",\n }) as JxMutableNode;\n\n // Paths below mirror the assembled tree: root.children[si] = section; section.children[1] =\n // Sb-body; body.children[ci] = card. Sections are appended only when non-empty, so indices are\n // Computed from the OUTPUT arrays, not the input catalog.\n const sectionBodyPath = (): JxPath => [\"children\", sections.length, \"children\", 1];\n\n for (const section of opts.meta.$sections) {\n let entries = section.elements;\n if (filter) {\n entries = entries.filter(\n (e) => e.tag.includes(filter) || section.label.toLowerCase().includes(filter),\n );\n }\n if (opts.customizedOnly) {\n entries = entries.filter((e) => hasTagStyle(opts.effectiveStyle, e.tag));\n }\n if (entries.length === 0) {\n continue;\n }\n const bodyPath = sectionBodyPath();\n const cards = entries.map((entry, ci) =>\n cardNode(\n entry.tag,\n `<${entry.tag}>`,\n specimenNode(entry),\n [...bodyPath, \"children\", ci],\n entry,\n ),\n );\n sections.push(sectionNode(section.label, cards));\n }\n\n // Custom components from the registry — live custom elements registered via $elements.\n const $elements: (string | { $ref: string })[] = [];\n {\n let comps = opts.components;\n if (filter) {\n comps = comps.filter((c) => c.tagName.toLowerCase().includes(filter));\n }\n if (opts.customizedOnly) {\n comps = comps.filter((c) => hasTagStyle(opts.effectiveStyle, c.tagName));\n }\n if (comps.length > 0) {\n const bodyPath = sectionBodyPath();\n const cards = comps.map((comp, ci) => {\n const cardPath = [...bodyPath, \"children\", ci];\n const renderable = comp.source !== \"npm\" && comp.path?.endsWith(\".json\");\n if (renderable) {\n // Root-relative $ref: registerElements resolves it against docBase (the canvas origin).\n // Collapse leading slashes — an absolute projectRoot (\"/home/…\") would otherwise produce\n // A protocol-relative \"//home/…\" that URL-resolves to a foreign host.\n $elements.push({\n $ref: `/${opts.projectRoot ? `${opts.projectRoot}/` : \"\"}${comp.path}`.replace(\n /^\\/+/,\n \"/\",\n ),\n });\n const attributes: Record<string, string> = {};\n for (const p of comp.props ?? []) {\n if (p.default !== undefined && p.default !== \"false\" && p.default !== \"''\") {\n attributes[p.name] = String(p.default).replaceAll(/^'|'$/g, \"\");\n }\n }\n const specimen = {\n tagName: comp.tagName,\n ...(Object.keys(attributes).length > 0 ? { attributes } : {}),\n } as JxMutableNode;\n return cardNode(comp.tagName, `<${comp.tagName}>`, specimen, cardPath, null);\n }\n // Npm/format-class components can't be $ref-registered — placeholder box (legacy parity).\n const fallback = {\n attributes: { class: \"sb-fallback\" },\n tagName: \"div\",\n textContent: `<${comp.tagName}>`,\n } as JxMutableNode;\n return cardNode(comp.tagName, `<${comp.tagName}>`, fallback, cardPath, null);\n });\n sections.push(sectionNode(\"Components\", cards));\n }\n }\n\n if (sections.length === 0) {\n sections.push({\n attributes: { class: \"sb-empty\" },\n tagName: \"div\",\n textContent: opts.customizedOnly ? \"No customized elements\" : \"No matching elements\",\n } as JxMutableNode);\n }\n\n const doc = {\n ...($elements.length > 0 ? { $elements } : {}),\n $media: opts.effectiveMedia,\n attributes: { class: \"sb-root\" },\n children: sections,\n style: transposeStylebookStyle(opts.effectiveStyle),\n tagName: \"div\",\n } as JxMutableNode;\n\n return { doc, pathToTag, tagToCardPath };\n}\n",
6
+ "/**\n * Project Styles — the model behind the project's design tokens and element defaults.\n *\n * ## The name and the wire value are different things\n *\n * The surface a user reaches is called **Project Styles** (plan §9.4). The canvas view it opens is\n * the string `\"stylebook\"`, a member of `CANVAS_MODES` in\n * {@link file://../canvas/iframe-protocol.ts} and therefore half of a `ParentToIframe` union: the\n * studio bundle and `dist/iframe-entry.js` agree on it, and changing it means rebuilding both in\n * lockstep. So it is not a name and may never be renamed to follow one.\n * {@link PROJECT_STYLES_TITLE} is the name; {@link PROJECT_STYLES_VIEW} is the wire value; a\n * surface that needs one must not reach for the other.\n *\n * ## One vocabulary for the `@` blocks\n *\n * A token's value can differ per rendering context, and on disk every such override lives in the\n * same place — a `@<name>` block beside the token, keyed by a `$media` entry name. Breakpoints and\n * colour schemes are two _kinds_ of that one thing, and this module models them as one\n * {@link TokenContext} list so a surface cannot grow a second override path for the second kind (a\n * per-scheme writer and a per-media writer that disagreed about pruning an emptied block is exactly\n * what this replaces). Contexts are **defined** in Project Settings › Contexts and only selected or\n * overridden here — §2 principle 5.\n *\n * On-disk format is unchanged by anything in this module: it reads and writes the same\n * `style[\"--token\"]` and `style[\"@--ctx\"][\"--token\"]` shapes the compiler already consumes.\n */\n\nimport { parseMediaEntries, schemeOfQuery } from \"../utils/canvas-media\";\nimport { varDisplayName } from \"../utils/studio-utils\";\n\nimport type { JxStyle } from \"@jxsuite/schema/types\";\nimport type { CanvasMode } from \"../canvas/iframe-protocol\";\n\n/** What the surface is called, everywhere a reader sees it. One definition site. */\nexport const PROJECT_STYLES_TITLE = \"Project Styles\";\n\n/**\n * The canvas view Project Styles opens — a WIRE value, not a name. See the module doc: it is a\n * `CANVAS_MODES` member shared with the iframe bundle, and it stays `\"stylebook\"`.\n */\nexport const PROJECT_STYLES_VIEW: CanvasMode = \"stylebook\";\n\n// ─── Token groups ────────────────────────────────────────────────────────────\n\n/** The four buckets the token editor lists, in display order. */\nexport type TokenGroupId = \"color\" | \"font\" | \"size\" | \"other\";\n\nexport interface TokenGroup {\n id: TokenGroupId;\n /** The group heading. */\n title: string;\n /** The prefix a token added in this group is named under. */\n prefix: string;\n}\n\n/**\n * The groups, in order. `other` is rendered only when something lands in it — a bucket named\n * \"Other\" over an empty list teaches nothing (§2 principle 6).\n *\n * A group is a name and a prefix and nothing else. The example values an add row hints with are a\n * property of the FORM, not of the model, and they live beside the form that shows them.\n */\nexport const TOKEN_GROUPS: readonly TokenGroup[] = [\n { id: \"color\", prefix: \"--color-\", title: \"Colors\" },\n { id: \"font\", prefix: \"--font-\", title: \"Fonts\" },\n { id: \"size\", prefix: \"--size-\", title: \"Sizes & Spacing\" },\n { id: \"other\", prefix: \"--\", title: \"Other\" },\n];\n\n/**\n * Which group a custom property belongs to, by prefix.\n *\n * @param {string} name\n * @returns {TokenGroupId}\n */\nexport function groupIdOfToken(name: string): TokenGroupId {\n if (name.startsWith(\"--color\")) {\n return \"color\";\n }\n if (name.startsWith(\"--font\")) {\n return \"font\";\n }\n if (name.startsWith(\"--size\") || name.startsWith(\"--spacing\") || name.startsWith(\"--radius\")) {\n return \"size\";\n }\n return \"other\";\n}\n\n/**\n * The label a reader sees for a token: the friendly name it was added under, recovered from the\n * variable name. `--color-primary-blue` → \"Primary Blue\".\n *\n * The `other` group keeps its raw name deliberately — a token there has no prefix to strip, so \"Z\n * Index Modal\" would be a guess at a name its author never typed.\n *\n * @param {string} name\n * @returns {string}\n */\nexport function tokenLabel(name: string): string {\n const group = groupIdOfToken(name);\n if (group === \"other\") {\n return name;\n }\n /*\n * `varDisplayName` falls back to stripping a bare `--` when the prefix does not match, which is\n * what turns `--spacing-lg` (group `size`, prefix `--size-`) into \"Spacing Lg\". The predecessor\n * chained three prefixes with `||` and never reached the second, because the first always\n * returns a truthy string.\n */\n const { prefix } = TOKEN_GROUPS.find((g) => g.id === group)!;\n return varDisplayName(name, prefix);\n}\n\n// ─── Tokens ──────────────────────────────────────────────────────────────────\n\n/** One design token declared at the top level of a style block. */\nexport interface ProjectToken {\n /** The custom property, e.g. `--color-primary`. */\n name: string;\n group: TokenGroupId;\n /** What a reader sees — {@link tokenLabel}. */\n label: string;\n value: string | number;\n}\n\n/**\n * Every design token in a style block, in declaration order.\n *\n * Non-custom properties (`color: blue`) and object values are not tokens and are skipped — an\n * object under a `--` key is malformed, and every `@ctx` block is an object by construction.\n *\n * @param {JxStyle | null | undefined} style\n * @returns {ProjectToken[]}\n */\nexport function listTokens(style: JxStyle | null | undefined): ProjectToken[] {\n if (!style) {\n return [];\n }\n const out: ProjectToken[] = [];\n for (const [name, value] of Object.entries(style)) {\n if (!name.startsWith(\"--\")) {\n continue;\n }\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n continue;\n }\n out.push({ group: groupIdOfToken(name), label: tokenLabel(name), name, value });\n }\n return out;\n}\n\n/**\n * Group tokens for display: every group in {@link TOKEN_GROUPS} order, each with its members.\n *\n * @param {JxStyle | null | undefined} style\n * @returns {{ group: TokenGroup; tokens: ProjectToken[] }[]}\n */\nexport function groupTokens(\n style: JxStyle | null | undefined,\n): { group: TokenGroup; tokens: ProjectToken[] }[] {\n const tokens = listTokens(style);\n return TOKEN_GROUPS.map((group) => ({\n group,\n tokens: tokens.filter((t) => t.group === group.id),\n }));\n}\n\n// ─── Rendering contexts ──────────────────────────────────────────────────────\n\n/**\n * What a context IS, for a reader. `size` is a breakpoint, `scheme` is a colour scheme, `feature`\n * is any other feature query. The distinction decides only how the row is labelled and whether it\n * is offered unprompted — the on-disk block is the same shape for all three.\n */\nexport type TokenContextKind = \"size\" | \"scheme\" | \"feature\";\n\n/** A declared `$media` entry, seen as a place a token can carry a different value. */\nexport interface TokenContext {\n /** The `$media` entry name, e.g. `--sm` or `--dark`. */\n name: string;\n /** The style key its overrides live under, e.g. `@--sm`. */\n key: string;\n /** What the reader sees: \"Dark\" for a scheme, the raw `@--sm` for anything else. */\n label: string;\n kind: TokenContextKind;\n /** Present only when `kind` is `\"scheme\"`. */\n scheme?: \"light\" | \"dark\";\n}\n\n/**\n * The contexts a token can be overridden in, derived from `$media`.\n *\n * Schemes come first because they are the pair a colour token is always asked about; breakpoints\n * follow in the order {@link parseMediaEntries} sorts them (the same order the canvas shows its\n * panels in), then any other feature query. `--` is the base canvas width, not a context.\n *\n * @param {Record<string, string> | null | undefined} media\n * @returns {TokenContext[]}\n */\nexport function listTokenContexts(\n media: Record<string, string> | null | undefined,\n): TokenContext[] {\n if (!media) {\n return [];\n }\n const { featureQueries, sizeBreakpoints } = parseMediaEntries(media);\n const schemes: TokenContext[] = [];\n const features: TokenContext[] = [];\n for (const { name, query } of featureQueries) {\n const scheme = schemeOfQuery(query);\n if (scheme) {\n schemes.push({\n key: `@${name}`,\n kind: \"scheme\",\n label: scheme === \"dark\" ? \"Dark\" : \"Light\",\n name,\n scheme,\n });\n } else {\n features.push({ key: `@${name}`, kind: \"feature\", label: `@${name}`, name });\n }\n }\n const sizes: TokenContext[] = sizeBreakpoints.map(({ name }) => ({\n key: `@${name}`,\n kind: \"size\",\n label: `@${name}`,\n name,\n }));\n return [...schemes, ...sizes, ...features];\n}\n\n// ─── Overrides ───────────────────────────────────────────────────────────────\n\n/** A token's value in one context, alongside the context it came from. */\nexport interface TokenOverride {\n context: TokenContext;\n value: string | number;\n}\n\n/**\n * The block a context's overrides live in, or undefined when the context carries none.\n *\n * @param {JxStyle} style\n * @param {TokenContext} context\n */\nfunction overrideBlock(style: JxStyle, context: TokenContext): Record<string, unknown> | undefined {\n const block = style[context.key];\n return block && typeof block === \"object\" ? (block as Record<string, unknown>) : undefined;\n}\n\n/**\n * A token's value in one context, or undefined when it inherits the base value.\n *\n * @param {JxStyle} style\n * @param {TokenContext} context\n * @param {string} token\n * @returns {string | number | undefined}\n */\nexport function readTokenOverride(\n style: JxStyle,\n context: TokenContext,\n token: string,\n): string | number | undefined {\n const value = overrideBlock(style, context)?.[token];\n return typeof value === \"string\" || typeof value === \"number\" ? value : undefined;\n}\n\n/**\n * Write or clear a token's override in one context, IN PLACE.\n *\n * An empty value clears it, and an emptied block is removed rather than left as `\"@--dark\": {}` — a\n * block that exists but says nothing is a diff on every save and a rule the compiler emits for no\n * reason. The block is recreated on demand, so a caller holding a stale render still writes to the\n * right place.\n *\n * @param {JxStyle} style\n * @param {TokenContext} context\n * @param {string} token\n * @param {string} value — empty clears\n */\nexport function writeTokenOverride(\n style: JxStyle,\n context: TokenContext,\n token: string,\n value: string,\n): void {\n if (value) {\n const block = (style[context.key] ??= {}) as Record<string, unknown>;\n block[token] = value;\n return;\n }\n const block = overrideBlock(style, context);\n if (!block) {\n return;\n }\n delete block[token];\n if (Object.keys(block).length === 0) {\n delete style[context.key];\n }\n}\n\n/**\n * Every context in which a token already carries an override, in {@link listTokenContexts} order.\n *\n * @param {JxStyle} style\n * @param {readonly TokenContext[]} contexts\n * @param {string} token\n * @returns {TokenOverride[]}\n */\nexport function tokenOverrides(\n style: JxStyle,\n contexts: readonly TokenContext[],\n token: string,\n): TokenOverride[] {\n const out: TokenOverride[] = [];\n for (const context of contexts) {\n const value = readTokenOverride(style, context, token);\n if (value !== undefined) {\n out.push({ context, value });\n }\n }\n return out;\n}\n\n/**\n * The contexts a token can still be given an override in — the add affordance's menu.\n *\n * The predecessor had none: an override row appeared only for a token that already carried an\n * `@media` block, so the only way to create the first one was to hand-edit `project.json`. This is\n * the list of contexts that are declared and not yet used, minus the ones already shown unprompted\n * (`alreadyShown`), so the menu never offers a row the reader is already looking at.\n *\n * @param {JxStyle} style\n * @param {readonly TokenContext[]} contexts\n * @param {string} token\n * @param {readonly TokenContext[]} [alreadyShown]\n * @returns {TokenContext[]}\n */\nexport function addableContexts(\n style: JxStyle,\n contexts: readonly TokenContext[],\n token: string,\n alreadyShown: readonly TokenContext[] = [],\n): TokenContext[] {\n const shown = new Set(alreadyShown.map((c) => c.name));\n return contexts.filter(\n (context) => !shown.has(context.name) && readTokenOverride(style, context, token) === undefined,\n );\n}\n",
7
+ "/// <reference lib=\"dom\" />\n/**\n * The **Project Styles** canvas — the element catalogue with its per-file style defaults, rendered\n * through the IFRAME canvas pipeline: a specimen document is generated parent-side\n * ({@link file://./stylebook-doc.ts}) and mounted per breakpoint panel via `mountStylebookCanvas`,\n * so each panel is a real width-sized viewport and `@media` blocks evaluate for real (no JS\n * flatten). Hits decode to tags in the host and route back here through the injected stylebook-hit\n * handler (`setStylebookHitHandler` in studio.ts).\n *\n * Every identifier here still says `stylebook`, and that is deliberate: `\"stylebook\"` is the\n * `CANVAS_MODES` wire value this module mounts against, shared with `dist/iframe-entry.js`. The\n * user-facing name is {@link PROJECT_STYLES_TITLE} and nothing a reader sees may be spelled from\n * the wire value — see {@link file://../style/project-styles.ts}.\n */\n\nimport { html, render as litRender } from \"lit-html\";\nimport { ref } from \"lit-html/directives/ref.js\";\nimport { classMap } from \"lit-html/directives/class-map.js\";\nimport { live } from \"lit-html/directives/live.js\";\n\nimport { projectState, updateSession } from \"../store\";\nimport type { CanvasSurface } from \"../canvas/canvas-surface\";\nimport { tabOfPane } from \"../canvas/canvas-surface\";\nimport { activeTab } from \"../workspace/workspace\";\nimport { shell } from \"../shell\";\nimport { componentRegistry } from \"../files/components\";\nimport { getEffectiveMedia, getEffectiveStyle } from \"../site-context\";\nimport { parseMediaEntries } from \"../utils/canvas-media\";\nimport { mediaDisplayName } from \"./shared\";\nimport { buildStylebookDoc } from \"./stylebook-doc\";\nimport { PROJECT_STYLES_TITLE } from \"../style/project-styles\";\nimport { mountStylebookCanvas, panToStylebookTag } from \"../canvas/iframe-host\";\nimport stylebookMeta from \"../../data/stylebook-meta.json\";\nimport type { TemplateResult } from \"lit-html\";\nimport type { CanvasPanel } from \"../types\";\n\nexport interface StylebookEntry {\n tag: string;\n text?: string;\n attributes?: Record<string, string>;\n style?: string;\n children?: StylebookEntry[];\n}\n\ninterface StylebookCtx {\n canvasPanelTemplate: (\n mediaName: string | null,\n label: string | null,\n fullWidth: boolean,\n width?: number | null,\n ) => { tpl: TemplateResult; panel: CanvasPanel };\n applyTransform: (surface: CanvasSurface) => void;\n observeCenterUntilStable: (surface: CanvasSurface) => void;\n updateActivePanelHeaders: (surface: CanvasSurface) => void;\n}\n\nexport { default as stylebookMeta } from \"../../data/stylebook-meta.json\";\n\n/**\n * Render the stylebook mode into the canvas: chrome bar + one iframe panel per breakpoint, all\n * mounting the SAME generated specimen document.\n *\n * @param {StylebookCtx} ctx\n */\nexport function renderStylebookMode(surface: CanvasSurface, ctx: StylebookCtx) {\n const canvasWrap = surface.wrap;\n /* THIS stage's tab. It was `activeTab.value` — the focused pane's — so a Stylebook drawn in the\n unfocused pane took its `$media` breakpoints from whatever document the keyboard was in, and\n rebuilt its specimen columns at the other document's widths. Found by the fourth rule in\n `scripts/check-pane-singletons.ts`, which is the whole reason that rule is per-FUNCTION: this\n module is not a singleton and its other focus read is legitimate. */\n const tab = tabOfPane(surface.paneId);\n const filter = shell.stylebook.filter.toLowerCase();\n const { customizedOnly } = shell.stylebook;\n\n const effectiveMedia = getEffectiveMedia(tab?.doc.document?.$media);\n const { sizeBreakpoints, baseWidth } = parseMediaEntries(effectiveMedia);\n const hasMedia = sizeBreakpoints.length > 0;\n\n const onFilterInput = (e: Event) => {\n shell.stylebook.filter = (e.target as HTMLInputElement).value;\n };\n\n const onCustomizedToggle = () => {\n shell.stylebook.customizedOnly = !shell.stylebook.customizedOnly;\n };\n\n const chromeBarTpl = html`\n <div\n class=\"sb-chrome\"\n style=\"position:absolute;top:0;left:0;right:0;z-index:15;background:var(--bg-panel);border-bottom:1px solid var(--border)\"\n >\n <div\n style=\"display:flex;align-items:center;padding:4px 8px;gap:4px\"\n role=\"toolbar\"\n aria-label=${PROJECT_STYLES_TITLE}\n >\n <input\n class=\"field-input\"\n style=\"flex:1;max-width:200px\"\n placeholder=\"Filter…\"\n aria-label=\"Filter the ${PROJECT_STYLES_TITLE} catalogue\"\n .value=${live(shell.stylebook.filter)}\n @input=${onFilterInput}\n />\n <button\n class=${classMap({\n active: shell.stylebook.customizedOnly,\n \"tb-toggle\": true,\n })}\n aria-pressed=${String(shell.stylebook.customizedOnly)}\n title=\"Show only the elements this file has already styled\"\n @click=${onCustomizedToggle}\n >\n Customized\n </button>\n </div>\n </div>\n `;\n\n (canvasWrap as HTMLElement).style.overflow = \"hidden\";\n\n /** @type {{ name: string; displayName: string; width: number }[]} */\n const allPanelDefs = [];\n if (hasMedia) {\n allPanelDefs.push({\n displayName: mediaDisplayName(\"--\"),\n name: \"base\",\n width: baseWidth,\n });\n for (const bp of sizeBreakpoints) {\n allPanelDefs.push({\n displayName: mediaDisplayName(bp.name),\n name: bp.name,\n width: bp.width,\n });\n }\n }\n\n /** @type {{ tpl: import(\"lit-html\").TemplateResult; panel: CanvasPanel }[]} */\n let panelEntries;\n if (!hasMedia) {\n const hasBaseWidth = effectiveMedia && effectiveMedia[\"--\"];\n const label = hasBaseWidth ? `${mediaDisplayName(\"--\")} (${baseWidth}px)` : null;\n const entry = ctx.canvasPanelTemplate(\n hasBaseWidth ? \"base\" : null,\n label,\n !hasBaseWidth,\n hasBaseWidth ? baseWidth : undefined,\n );\n panelEntries = [{ panel: entry.panel, tpl: entry.tpl }];\n } else {\n panelEntries = allPanelDefs.map((def) => {\n const label = `${def.displayName} (${def.width}px)`;\n const { tpl, panel } = ctx.canvasPanelTemplate(def.name, label, false, def.width);\n return { panel, tpl };\n });\n }\n\n litRender(\n html`\n ${chromeBarTpl}\n <div\n class=\"panzoom-wrap\"\n style=\"transform-origin:0 0;padding-top:40px\"\n ${ref((el) => {\n if (el) {\n surface.panzoomWrap = el as HTMLDivElement;\n }\n })}\n >\n ${panelEntries.map((e) => e.tpl)}\n </div>\n `,\n /** @type {HTMLElement} */ canvasWrap,\n );\n\n // ONE generated doc shared by every panel — per-panel @media differentiation comes from each\n // Iframe's real viewport width, not from a per-panel style flatten.\n const generated = buildStylebookDoc({\n components: componentRegistry,\n customizedOnly: Boolean(customizedOnly),\n effectiveMedia: effectiveMedia ?? {},\n effectiveStyle: getEffectiveStyle(tab?.doc.document?.style),\n filter,\n meta: stylebookMeta as { $sections: { label: string; elements: StylebookEntry[] }[] },\n projectRoot: projectState?.projectRoot ?? null,\n });\n\n const { panels } = surface;\n for (const { panel } of panelEntries) {\n panels.push(panel);\n mountStylebookCanvas(\n surface.renderGeneration,\n generated,\n panel.canvas as HTMLElement,\n panel._width,\n );\n }\n if (hasMedia) {\n ctx.updateActivePanelHeaders(surface);\n }\n\n ctx.applyTransform(surface);\n ctx.observeCenterUntilStable(surface);\n}\n\n/**\n * Select a tag in the stylebook — shared by the canvas hit handler (via studio's\n * setStylebookHitHandler wiring), the stylebook layers panel, and the style panel. The host's\n * selection watcher tracks `shell.stylebook.selection` and measures the selected tag's card, so no\n * direct overlay drawing happens here.\n *\n * @param {string} tag\n * @param {string | null} [media]\n */\nexport function selectStylebookTag(tag: string, media?: string | null, { panCanvas = false } = {}) {\n shell.stylebook.selection = tag;\n updateSession(activeTab.value, {\n // The ROOT path, not an empty selection: stylebook mode has always parked the selection on the\n // Document element while the Style tab edits a TAG, and widening the field to a list changed\n // Which literal spells that — `[[]]` is one selected path, the root — not what it means.\n selection: [[]],\n ui: {\n activeSelector: tag,\n rightTab: \"style\",\n ...(media !== undefined ? { activeMedia: media } : {}),\n },\n });\n\n if (tag && panCanvas) {\n panToStylebookTag(tag);\n }\n}\n\n/** Re-exported for legacy consumers (the preview now lives in component-preview.ts). */\nexport { renderComponentPreview } from \"./component-preview\";\n",
8
+ "/**\n * Defaults.ts — the first real command records.\n *\n * These are not examples. Each one is a capability Studio already has, written out in the form\n * every surface will read it from, with the implementation taken by injection ({@link CommandDeps})\n * so this module imports no state and can be loaded by a CI check in a bare Bun process. Next wave\n * the bootstrap passes the real functions; nothing about the records changes.\n *\n * The one value import is `isSpliceablePath` — a four-token predicate over a path array, from the\n * module that also enforces it inside the mutators. An enablement predicate and the mutator it\n * guards disagreeing about which paths are editable is exactly how a Delete comes to be offered on\n * a selection it corrupts, so the two read the same function rather than the same sentence.\n *\n * Two of them exist to settle arguments the current code has with itself:\n *\n * - `document.close` is ⌘W. Today `editor/shortcuts.ts:192` refuses to close the last tab while\n * `panels/tab-strip.ts:182`'s × closes it happily. Here the chord and the × button are the same\n * record, so they cannot disagree again.\n * - `selection.duplicate` is \"duplicate node\", implemented four times today. Its `requires` string is\n * what the block action bar's tooltip, the palette's grey subtitle and the agent's refusal all\n * print — one sentence, three consumers.\n *\n * The primary Command Bar cluster is capped at five by `scripts/check-chrome-budget.ts`; four are\n * spent here (Save, Undo, Redo, Open in Browser) exactly as plan §3.2 region ① specifies.\n */\n\nimport { isSpliceablePath } from \"../tabs/selection\";\n\nimport type { AnyCommand } from \"./registry\";\nimport type { CommandContext } from \"./context\";\n\n/**\n * Which dock {@link CommandDeps.toggleDock} addresses.\n *\n * The Command Bar draws three toggles, but only two come through this verb: the Bottom dock's is\n * `shell.ts`'s `view.toggleBottomDock`, which writes `shell.docks.bottom` directly now that the\n * dock is on the shell record. `\"bottom\"` survives in the union only because\n * `editor/shortcuts.ts`'s `toggleShellDock` still carries the branch that used to route ⌘J to the\n * Assistant — HANDOFF: that branch is now unreachable, and it goes with this member.\n */\nexport type DockId = \"navigator\" | \"inspector\" | \"bottom\";\n\n/**\n * Palette modes, echoed as a removable chip in the input (plan §5.4).\n *\n * The value space is the palette's namespace, declared once here so a new mode is a new member\n * rather than a new widget: P4's Problems and P7's content search slot in beside these.\n */\nexport type PaletteMode = \"picker\" | \"files\" | \"commands\" | \"nodes\" | \"projects\";\n\n/**\n * One panel, as the ⌘1–8 direct keys address it.\n *\n * Structurally the part of `panels/panel-registry.ts`'s `PanelRecord` a chord needs, declared here\n * rather than imported so this module keeps its one load-bearing property: it imports no state and\n * no DOM, which is what lets the three CI checks load the command set in a bare Bun process. The\n * ROSTER arrives by injection ({@link CommandDeps.panelRoster}) from the panel registry, so there\n * is still exactly one place a panel is named.\n */\nexport interface RailPanel {\n /** The panel's registry id — what `deps.focusPanel` is handed. */\n id: string;\n /** The panel's human name, which is also the command's title after \"Show \". */\n title: string;\n /** `false` for a panel with no rail button — reachable by name, not by number. */\n rail?: boolean;\n /** The panel's own visibility predicate, composed into the command's. */\n when?: (ctx: CommandContext) => boolean;\n}\n\n/** How many rail panels get a ⌘N. §3.2 ② spends exactly this many slots, four per level group. */\nexport const RAIL_CHORD_LIMIT = 8;\n\n/**\n * The Inspector's four tabs, in the order §3.2 ⑨ names them — which is the order ⌘⇧1–4 follow.\n *\n * `\"assistant\"` is a different dock (it is the Inspector's second instance until P3.6 folds the\n * column in), so it is not one of `shell.ts`'s `INSPECTOR_TAB_IDS`; the chord still belongs in the\n * same run of four, because a user counting tabs does not know that.\n */\nexport interface InspectorTab {\n /** The stored `session.ui.rightTab` value, or `\"assistant\"` for the assistant dock. */\n id: string;\n title: string;\n}\n\nexport const INSPECTOR_TABS: readonly InspectorTab[] = [\n { id: \"properties\", title: \"Content\" },\n { id: \"style\", title: \"Style\" },\n { id: \"events\", title: \"Logic\" },\n { id: \"assistant\", title: \"Assistant\" },\n];\n\n/**\n * Everything the default command set needs from the rest of Studio.\n *\n * One flat interface of verbs, not a bag of modules: a command's `run` is allowed to know that\n * \"save the document\" exists, and nothing else.\n */\nexport interface CommandDeps {\n saveDocument: () => void | Promise<void>;\n undo: () => void;\n redo: () => void;\n openInBrowser: () => void | Promise<void>;\n closeDocument: () => void;\n duplicateSelection: () => void;\n deleteSelection: () => void;\n selectParent: () => void;\n toggleDock: (dock: DockId) => void;\n toggleZen: () => void;\n openPalette: (mode: PaletteMode) => void;\n openProject: () => void | Promise<void>;\n /**\n * The rail's panels in rail order, then the rail-less ones — the roster ⌘1–8 is generated from.\n *\n * Every entry is a Navigator panel: the rail is the Navigator's, and a Bottom-dock tab is\n * addressed by `view.setBottomTab` instead — one door per surface. `panels/navigator-panels.ts`'s\n * `panelFocusRoster()` builds it.\n *\n * Injected rather than declared here so the panel registry stays the one place a panel is named,\n * levelled and gated. An empty roster (the no-op deps) simply yields no `panel.focus.*` records.\n */\n panelRoster: readonly RailPanel[];\n /**\n * Toggle-FOCUS a panel (plan §5.3): reveal it and take focus, or — when it already has focus —\n * collapse the dock hosting it and hand focus back to the pane. Deliberately not toggle-visible:\n * ⌘1 pressed from the canvas must land you in Files, not close it.\n */\n focusPanel: (panelId: string) => void;\n /** Show an Inspector tab and focus the dock. `\"assistant\"` addresses the assistant dock. */\n focusInspectorTab: (tabId: string) => void;\n /** F6 / ⇧F6 — move focus to the next (or previous) shell region. */\n cycleRegion: (direction: 1 | -1) => void;\n}\n\n/** A dependency set whose verbs do nothing — what the CI checks load the records with. */\nexport function noopCommandDeps(): CommandDeps {\n return {\n saveDocument: () => {},\n undo: () => {},\n redo: () => {},\n openInBrowser: () => {},\n closeDocument: () => {},\n duplicateSelection: () => {},\n deleteSelection: () => {},\n selectParent: () => {},\n toggleDock: () => {},\n toggleZen: () => {},\n openPalette: () => {},\n openProject: () => {},\n panelRoster: [],\n focusPanel: () => {},\n focusInspectorTab: () => {},\n cycleRegion: () => {},\n };\n}\n\n/** A document is open and editable — the precondition most document-level verbs share. */\nconst documentOpen = (ctx: CommandContext) => ctx.document.open;\n\n/**\n * At least one node is selected, **on a canvas**.\n *\n * The editor-kind conjunct is not belt-and-braces. `keyScope` gates `handleKeyEvent` and nothing\n * else, so a record reachable from the palette, the element menu, `__jxAutomation` or the assistant\n * is reachable regardless of scope — and the Outline renders whatever\n * `activeTab.value.doc.document` is, which with Project Settings open is the project CONFIGURATION\n * object drawn as a layer tree. Clicking a row there writes `session.selection`, so Delete and\n * Duplicate would transact against `project.json` and splice element nodes into the file that\n * defines the project.\n */\nconst hasSelection = (ctx: CommandContext) =>\n ctx.selection.count > 0 && ctx.editor.kind === \"canvas\";\n\n/**\n * Every selected path names a position a structural verb can act on.\n *\n * Two halves, because two surfaces answer this question with different halves of the context. A\n * menu opened over ONE node reports its verdict as `selection.isRoot` and carries no path list\n * (`editor/context-menu.ts` builds a synthetic context from its target); the running app carries\n * the real `selection.paths` and sets `isRoot` only for the document element. `isRoot` alone would\n * leave a ctrl-clicked repeater template enabled — and Delete on a selection that includes one used\n * to splice into a children ARRAY and throw, leaving the earlier removals applied and unrecorded.\n *\n * It is `every`, not `some`, deliberately: a batch that silently skips two of the five nodes the\n * user selected is a worse answer than a Delete that says why it is unavailable. Offering a verb\n * that cannot perform what the selection asks for is the defect, not the refusal.\n */\nconst structurallyEditable = (ctx: CommandContext) =>\n !ctx.selection.isRoot && ctx.selection.paths.every((path) => isSpliceablePath(path));\n\n/**\n * The default command set.\n *\n * Order is the order surfaces iterate in, so it is the order these read in the palette and in the\n * Command Bar — grouped by category rather than alphabetised.\n */\nexport function defaultCommands(deps: CommandDeps): AnyCommand[] {\n const commands: AnyCommand[] = [\n // ── File / Document ──\n {\n id: \"file.save\",\n title: \"Save\",\n category: \"File\",\n level: \"document\",\n icon: \"save\",\n keybinding: \"mod+s\",\n menus: [\"commandbar/primary\", \"statusbar/document\", \"palette\"],\n group: \"1_file\",\n undo: \"none\",\n when: documentOpen,\n requires: \"an open document\",\n run: () => deps.saveDocument(),\n },\n {\n id: \"document.close\",\n title: \"Close Document\",\n category: \"Document\",\n level: \"document\",\n keybinding: \"mod+w\",\n menus: [\"context/tab\", \"palette\"],\n group: \"1_file\",\n when: documentOpen,\n requires: \"an open document\",\n run: () => deps.closeDocument(),\n },\n {\n id: \"view.openInBrowser\",\n title: \"Open in Browser\",\n category: \"View\",\n level: \"document\",\n icon: \"browser\",\n keybinding: \"mod+shift+o\",\n menus: [\"commandbar/primary\", \"statusbar/document\", \"palette\"],\n group: \"2_output\",\n when: (ctx) => ctx.project.isSite,\n enablement: documentOpen,\n requires: \"a built page to open\",\n run: () => deps.openInBrowser(),\n },\n\n // ── Edit ──\n {\n id: \"edit.undo\",\n title: \"Undo\",\n category: \"Edit\",\n level: \"document\",\n icon: \"undo\",\n keybinding: \"mod+z\",\n menus: [\"commandbar/primary\", \"palette\"],\n group: \"1_history\",\n when: documentOpen,\n enablement: (ctx) => ctx.document.canUndo,\n requires: \"a change to undo\",\n run: () => deps.undo(),\n },\n {\n id: \"edit.redo\",\n title: \"Redo\",\n category: \"Edit\",\n level: \"document\",\n icon: \"redo\",\n keybinding: [\"mod+shift+z\", \"mod+y\"],\n menus: [\"commandbar/primary\", \"palette\"],\n group: \"1_history\",\n when: documentOpen,\n enablement: (ctx) => ctx.document.canRedo,\n requires: \"a change to redo\",\n run: () => deps.redo(),\n },\n\n // ── Selection ──\n // KeyScope \"canvas\", not \"global\": these chords must not fire while a text caret owns the\n // Keyboard. ⌘D inside a paragraph duplicates the word, not the paragraph's element.\n {\n id: \"selection.duplicate\",\n title: \"Duplicate\",\n category: \"Selection\",\n level: \"selection\",\n keyScope: \"canvas\",\n keybinding: \"mod+d\",\n menus: [\"blockbar\", \"context/element\", \"context/layer\", \"outline/row\", \"palette\"],\n group: \"3_structure\",\n undo: \"document\",\n when: hasSelection,\n // Same gate as `selection.delete`: duplicating needs a sibling position to insert into. The\n // Document root, a repeater template and a `$switch` case have none, and `mutateDuplicateNode`\n // Would splice at a non-numeric index there — a live button that silently corrupts the\n // Document. Both surfaces that render this record had to hand-guard it before the record\n // Said so.\n enablement: structurallyEditable,\n requires: \"an element that has a sibling position\",\n aiTool: {\n name: \"duplicate_node\",\n description: \"Duplicate the currently selected element, inserting the copy after it.\",\n },\n run: () => deps.duplicateSelection(),\n },\n {\n id: \"selection.repeat\",\n title: \"Repeat...\",\n category: \"Selection\",\n level: \"selection\",\n keyScope: \"canvas\",\n menus: [\"context/element\", \"palette\"],\n group: \"3_structure\",\n undo: \"document\",\n when: hasSelection,\n // Two ways to mean nothing: an element with no sibling position (`mutateInsertNode`'s\n // Coordinate is the same splice index Duplicate needs), and an element that IS the repeater\n // Already — its content is the single `map` template, not a child list.\n enablement: (ctx) => structurallyEditable(ctx) && !ctx.selection.isRepeater,\n requires: \"an element with a sibling position that is not already a repeater\",\n aiTool: {\n name: \"repeat_node\",\n description:\n \"Turn the selected element into a repeater template, rendering it once per item of a \" +\n \"data collection the author picks in the dialog this opens.\",\n },\n /*\n * The one record here whose implementation is not injected, and the reason is a property of\n * the implementation rather than of this record: `convertToRepeater()` is self-contained —\n * it reads the active tab, opens its own dialog and commits its own transaction — so there\n * is no bootstrap state for a `CommandDeps` verb to carry, and injecting it would only mean\n * the bootstrap re-exporting a function that needs nothing from the bootstrap.\n *\n * Imported at CALL time, which is what keeps this module's one load-bearing property intact:\n * it still imports no state at module scope, so `scripts/check-command-levels.ts` and its two\n * sibling checks still load the command set in a bare Bun process with no DOM.\n *\n * Deliberately NOT awaited, exactly as `selection.convertToComponent` is not: the promise\n * resolves when a HUMAN answers the dialog, and a command whose promise waits on a person is\n * a command nothing automated can call — `run()` means \"start this flow\".\n */\n run: () => {\n void import(\"../editor/convert-to-repeater\").then(({ convertToRepeater }) =>\n convertToRepeater(),\n );\n },\n },\n {\n id: \"selection.delete\",\n title: \"Delete\",\n category: \"Selection\",\n level: \"selection\",\n keyScope: \"canvas\",\n keybinding: [\"delete\", \"backspace\"],\n menus: [\"blockbar\", \"context/element\", \"context/layer\", \"outline/row\", \"palette\"],\n group: \"9_danger\",\n destructive: true,\n undo: \"document\",\n when: hasSelection,\n // The document root is the document; deleting it is not an edit, it is an empty file. The\n // Outline's other unspliceable rows — a repeater's map template, a `$switch` case — are\n // Refused by the same gate, and refusing the whole batch is why a mixed selection can no\n // Longer half-apply.\n enablement: structurallyEditable,\n requires: \"an element selection that is not the document root\",\n aiTool: {\n name: \"delete_node\",\n description: \"Delete the currently selected element from the document.\",\n },\n run: () => deps.deleteSelection(),\n },\n {\n id: \"selection.selectParent\",\n title: \"Select Parent\",\n category: \"Selection\",\n level: \"selection\",\n keyScope: \"canvas\",\n // Two spellings of ONE action, in the record rather than in a second `keymap.add` call beside\n // The registration — which is what `editor/shortcuts.ts` had to do while this file was another\n // Workstream's, and is exactly the second definition site the registry exists to prevent.\n keybinding: [\"escape\", \"arrowleft\"],\n menus: [\"palette\"],\n group: \"2_navigate\",\n when: hasSelection,\n requires: \"an element selection\",\n run: () => deps.selectParent(),\n },\n\n // ── View ──\n {\n id: \"view.toggleNavigator\",\n title: \"Toggle Navigator Dock\",\n category: \"View\",\n level: \"application\",\n keybinding: \"mod+b\",\n menus: [\"commandbar/overflow\", \"palette\"],\n group: \"4_docks\",\n run: () => deps.toggleDock(\"navigator\"),\n },\n {\n id: \"view.toggleInspector\",\n title: \"Toggle Inspector Dock\",\n category: \"View\",\n level: \"application\",\n keybinding: \"mod+alt+b\",\n menus: [\"commandbar/overflow\", \"palette\"],\n group: \"4_docks\",\n run: () => deps.toggleDock(\"inspector\"),\n },\n // `view.toggleBottomDock` (⌘J) is NOT here. It moved to `shell.ts`, beside `view.setBottomDock`\n // And the `shell.docks.bottom` record both of them write: the Bottom dock is a dock now, so its\n // Verbs are declared where the other two docks' are, and the toggle no longer needs a `deps`\n // Hop through a dock id this module cannot resolve.\n {\n id: \"view.zen\",\n title: \"Zen Mode\",\n category: \"View\",\n level: \"application\",\n keybinding: \"mod+.\",\n menus: [\"commandbar/overflow\", \"palette\"],\n group: \"4_docks\",\n run: () => deps.toggleZen(),\n },\n\n // ── Palette ──\n {\n id: \"palette.open\",\n title: \"Open Command Center\",\n category: \"View\",\n level: \"application\",\n keybinding: \"mod+k\",\n menus: [\"palette\"],\n group: \"5_palette\",\n run: () => deps.openPalette(\"picker\"),\n },\n {\n id: \"palette.openFiles\",\n title: \"Go to File…\",\n category: \"File\",\n level: \"application\",\n keybinding: \"mod+p\",\n menus: [\"palette\"],\n group: \"5_palette\",\n run: () => deps.openPalette(\"files\"),\n },\n {\n id: \"palette.openCommands\",\n title: \"Run Command…\",\n category: \"View\",\n level: \"application\",\n keybinding: \"mod+shift+p\",\n menus: [\"palette\"],\n group: \"5_palette\",\n run: () => deps.openPalette(\"commands\"),\n },\n\n {\n id: \"palette.openNodes\",\n title: \"Go to Symbol in Document…\",\n category: \"Selection\",\n level: \"document\",\n menus: [\"palette\"],\n group: \"5_palette\",\n when: documentOpen,\n requires: \"an open document\",\n run: () => deps.openPalette(\"nodes\"),\n },\n\n // ── Project ──\n {\n id: \"project.open\",\n title: \"Open Project…\",\n category: \"Project\",\n level: \"project\",\n keybinding: \"mod+o\",\n menus: [\"commandbar/overflow\", \"statusbar/project\", \"palette\"],\n group: \"1_file\",\n run: () => deps.openProject(),\n },\n {\n // The no-project palette stops being a hidden domain swap on `!projectState` and becomes a\n // NAMED mode that works either way (plan §5.4) — same trigger, same chrome, stated feature.\n id: \"project.openRecent\",\n title: \"Open Recent…\",\n category: \"Project\",\n level: \"project\",\n menus: [\"commandbar/overflow\", \"statusbar/project\", \"palette\"],\n group: \"1_file\",\n run: () => deps.openPalette(\"projects\"),\n },\n\n // ── Direct keys (plan §5.3) ──\n ...panelFocusCommands(deps),\n ...inspectorFocusCommands(deps),\n {\n id: \"view.cycleRegion\",\n title: \"Focus Next Region\",\n category: \"View\",\n level: \"application\",\n keybinding: \"f6\",\n menus: [\"palette\"],\n group: \"4_docks\",\n run: () => deps.cycleRegion(1),\n },\n {\n id: \"view.cycleRegionBack\",\n title: \"Focus Previous Region\",\n category: \"View\",\n level: \"application\",\n keybinding: \"shift+f6\",\n menus: [\"palette\"],\n group: \"4_docks\",\n run: () => deps.cycleRegion(-1),\n },\n ];\n return commands;\n}\n\n/**\n * ⌘1–8 — one record per panel, generated from {@link CommandDeps.panelRoster}.\n *\n * Generated rather than written out eight times for the reason the whole registry exists: the rail,\n * the chord, the palette row and the generated shortcut sheet are then four renderings of one list.\n * Only the first eight get a chord; a ninth panel keeps its name and its palette row, which is the\n * cost §2 principle 9 puts on chrome.\n */\nexport function panelFocusCommands(deps: CommandDeps): AnyCommand[] {\n let chordsSpent = 0;\n return deps.panelRoster.map((panel) => {\n const command: AnyCommand = {\n id: `panel.focus.${panel.id}`,\n title: `Show ${panel.title}`,\n category: \"View\",\n // Application, like `view.setActivity`: revealing a panel arranges the workspace. What the\n // PANEL acts on is the panel record's own level, and that is `registerPanel()`'s field.\n level: \"application\",\n menus: [\"palette\"],\n group: \"4_docks\",\n requires: \"an open project\",\n // The panel's OWN `when` composes in, so a declared-but-unbuilt surface (Search, Problems)\n // Has no palette row and no live chord — the record exists, the affordance does not.\n when: (ctx: CommandContext) => ctx.project.open && (panel.when?.(ctx) ?? true),\n run: () => deps.focusPanel(panel.id),\n };\n if (panel.rail !== false && chordsSpent < RAIL_CHORD_LIMIT) {\n chordsSpent += 1;\n command.keybinding = `mod+${chordsSpent}`;\n }\n return command;\n });\n}\n\n/** ⌘⇧1–4 — one record per Inspector tab, generated from {@link INSPECTOR_TABS}. */\nexport function inspectorFocusCommands(deps: CommandDeps): AnyCommand[] {\n return INSPECTOR_TABS.map((tab, index) => {\n const command: AnyCommand = {\n id: `inspector.focus.${tab.id}`,\n title: `Show ${tab.title}`,\n category: \"View\",\n // DOCUMENT-level, like `view.setRightTab`, which writes the same field. These carried no\n // `when`, no `enablement` and no `requires` at all, so with nothing open ⌘⇧2 reported success,\n // Opening the right dock and moving focus there while silently NOT switching the tab —\n // The delegate `focusInspectorTab` goes through `runIfPresent`, which checks `isEnabled` and skips.\n // One gesture, three outcomes across the family: a loud refusal, a full write, and a\n // Half-applied success with no message. The Inspector's tabs are per-document session state\n // (`session.ui.rightTab`), so the document is the honest precondition.\n level: \"document\",\n keybinding: `mod+shift+${index + 1}`,\n menus: [\"palette\"],\n group: \"4_docks\",\n requires: \"an open document\",\n when: (ctx: CommandContext) => ctx.document.open,\n run: () => deps.focusInspectorTab(tab.id),\n };\n return command;\n });\n}\n\n/**\n * The default set with no-op implementations — the shape the CI checks validate.\n *\n * `scripts/check-command-levels.ts` and `scripts/check-chrome-budget.ts` both call this by name; a\n * fixture module passed with `--source` exports the same function.\n */\nexport function defaultCommandSet(): AnyCommand[] {\n return defaultCommands(noopCommandDeps());\n}\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "B0A56BD62EB8ABB664756E2164756E21",
12
+ "names": []
13
+ }
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  decodeFrame,
9
9
  encodeFrame
10
- } from "./studio-xze4zrs1.js";
10
+ } from "./studio-7bmdvzne.js";
11
11
  import {
12
12
  Doc,
13
13
  applyUpdate,
@@ -22,6 +22,7 @@ import {
22
22
  writeVarUint,
23
23
  writeVarUint8Array
24
24
  } from "./studio-xgm355mm.js";
25
+ import"./studio-dg7zyt5x.js";
25
26
  import"./studio-md4gps17.js";
26
27
 
27
28
  // ../../node_modules/y-protocols/sync.js
@@ -231,7 +232,8 @@ function createWsCollabConnection(options) {
231
232
  return;
232
233
  }
233
234
  setStatus("connecting");
234
- const ws = new WebSocketCtor(options.url);
235
+ const offer = options.protocols;
236
+ const ws = offer === undefined || offer.length === 0 ? new WebSocketCtor(options.url) : new WebSocketCtor(options.url, offer);
235
237
  socket = ws;
236
238
  ws.binaryType = "arraybuffer";
237
239
  ws.onopen = () => {
@@ -414,5 +416,5 @@ export {
414
416
  createWsCollabConnection
415
417
  };
416
418
 
417
- //# debugId=A5C0E576FD4383EF64756E2164756E21
418
- //# sourceMappingURL=ws-client-q7hkz3j9.js.map
419
+ //# debugId=1A24E7FF808B62FF64756E2164756E21
420
+ //# sourceMappingURL=ws-client-654ts66j.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../node_modules/y-protocols/sync.js", "../../collab/src/ws-client.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * @module sync-protocol\n */\n\nimport * as encoding from 'lib0/encoding'\nimport * as decoding from 'lib0/decoding'\nimport * as Y from 'yjs'\n\n/**\n * @typedef {Map<number, number>} StateMap\n */\n\n/**\n * Core Yjs defines two message types:\n * • YjsSyncStep1: Includes the State Set of the sending client. When received, the client should reply with YjsSyncStep2.\n * • YjsSyncStep2: Includes all missing structs and the complete delete set. When received, the client is assured that it\n * received all information from the remote client.\n *\n * In a peer-to-peer network, you may want to introduce a SyncDone message type. Both parties should initiate the connection\n * with SyncStep1. When a client received SyncStep2, it should reply with SyncDone. When the local client received both\n * SyncStep2 and SyncDone, it is assured that it is synced to the remote client.\n *\n * In a client-server model, you want to handle this differently: The client should initiate the connection with SyncStep1.\n * When the server receives SyncStep1, it should reply with SyncStep2 immediately followed by SyncStep1. The client replies\n * with SyncStep2 when it receives SyncStep1. Optionally the server may send a SyncDone after it received SyncStep2, so the\n * client knows that the sync is finished. There are two reasons for this more elaborated sync model: 1. This protocol can\n * easily be implemented on top of http and websockets. 2. The server should only reply to requests, and not initiate them.\n * Therefore it is necessary that the client initiates the sync.\n *\n * Construction of a message:\n * [messageType : varUint, message definition..]\n *\n * Note: A message does not include information about the room name. This must to be handled by the upper layer protocol!\n *\n * stringify[messageType] stringifies a message definition (messageType is already read from the bufffer)\n */\n\nexport const messageYjsSyncStep1 = 0\nexport const messageYjsSyncStep2 = 1\nexport const messageYjsUpdate = 2\n\n/**\n * Create a sync step 1 message based on the state of the current shared document.\n *\n * @param {encoding.Encoder} encoder\n * @param {Y.Doc} doc\n */\nexport const writeSyncStep1 = (encoder, doc) => {\n encoding.writeVarUint(encoder, messageYjsSyncStep1)\n const sv = Y.encodeStateVector(doc)\n encoding.writeVarUint8Array(encoder, sv)\n}\n\n/**\n * @param {encoding.Encoder} encoder\n * @param {Y.Doc} doc\n * @param {Uint8Array} [encodedStateVector]\n */\nexport const writeSyncStep2 = (encoder, doc, encodedStateVector) => {\n encoding.writeVarUint(encoder, messageYjsSyncStep2)\n encoding.writeVarUint8Array(encoder, Y.encodeStateAsUpdate(doc, encodedStateVector))\n}\n\n/**\n * Read SyncStep1 message and reply with SyncStep2.\n *\n * @param {decoding.Decoder} decoder The reply to the received message\n * @param {encoding.Encoder} encoder The received message\n * @param {Y.Doc} doc\n */\nexport const readSyncStep1 = (decoder, encoder, doc) =>\n writeSyncStep2(encoder, doc, decoding.readVarUint8Array(decoder))\n\n/**\n * Read and apply Structs and then DeleteStore to a y instance.\n *\n * @param {decoding.Decoder} decoder\n * @param {Y.Doc} doc\n * @param {any} transactionOrigin\n * @param {(error:Error)=>any} [errorHandler]\n */\nexport const readSyncStep2 = (decoder, doc, transactionOrigin, errorHandler) => {\n try {\n Y.applyUpdate(doc, decoding.readVarUint8Array(decoder), transactionOrigin)\n } catch (error) {\n if (errorHandler != null) errorHandler(/** @type {Error} */ (error))\n // This catches errors that are thrown by event handlers\n console.error('Caught error while handling a Yjs update', error)\n }\n}\n\n/**\n * @param {encoding.Encoder} encoder\n * @param {Uint8Array} update\n */\nexport const writeUpdate = (encoder, update) => {\n encoding.writeVarUint(encoder, messageYjsUpdate)\n encoding.writeVarUint8Array(encoder, update)\n}\n\n/**\n * Read and apply Structs and then DeleteStore to a y instance.\n *\n * @param {decoding.Decoder} decoder\n * @param {Y.Doc} doc\n * @param {any} transactionOrigin\n * @param {(error:Error)=>any} [errorHandler]\n */\nexport const readUpdate = readSyncStep2\n\n/**\n * @param {decoding.Decoder} decoder A message received from another client\n * @param {encoding.Encoder} encoder The reply message. Does not need to be sent if empty.\n * @param {Y.Doc} doc\n * @param {any} transactionOrigin\n * @param {(error:Error)=>any} [errorHandler] Optional error handler that catches errors when reading Yjs messages.\n */\nexport const readSyncMessage = (decoder, encoder, doc, transactionOrigin, errorHandler) => {\n const messageType = decoding.readVarUint(decoder)\n switch (messageType) {\n case messageYjsSyncStep1:\n readSyncStep1(decoder, encoder, doc)\n break\n case messageYjsSyncStep2:\n readSyncStep2(decoder, doc, transactionOrigin, errorHandler)\n break\n case messageYjsUpdate:\n readUpdate(decoder, doc, transactionOrigin, errorHandler)\n break\n default:\n throw new Error('Unknown message type')\n }\n return messageType\n}\n",
6
+ "/**\n * The browser half of the wire envelope: one WebSocket per project, multiplexing every open\n * document. `createWsCollabConnection` owns the socket (exponential-backoff reconnect, re-open of\n * live docs on reconnect), the shared project-level Awareness, and per-doc sync state;\n * `openDoc(path)` hands out {@link CollabHandle}s for `StudioPlatform.collab`.\n */\n\nimport * as Y from \"yjs\";\nimport * as decoding from \"lib0/decoding\";\nimport * as encoding from \"lib0/encoding\";\nimport {\n applyAwarenessUpdate,\n Awareness,\n encodeAwarenessUpdate,\n removeAwarenessStates,\n} from \"y-protocols/awareness\";\nimport * as syncProtocol from \"y-protocols/sync\";\nimport { decodeFrame, encodeFrame } from \"./envelope.ts\";\nimport type { CollabFrame, ControlMessage } from \"./envelope.ts\";\nimport type { CollabHandle, CollabIdentity, CollabStatus } from \"./provider.ts\";\n\n/** The subset of the WebSocket API the connection uses (injectable for tests). */\nexport interface WsLike {\n binaryType: string;\n readyState: number;\n send: (data: Uint8Array) => void;\n close: () => void;\n onopen: (() => void) | null;\n onclose: (() => void) | null;\n onerror: (() => void) | null;\n onmessage: ((event: { data: unknown }) => void) | null;\n}\n\nexport interface WsCollabConnectionOptions {\n /** The ws(s):// endpoint for this project's collab socket. */\n url: string;\n /**\n * Subprotocols to offer (`Sec-WebSocket-Protocol`), normally `negotiateCollab`'s `offer`.\n *\n * Left empty or undefined deliberately when the server advertised none: RFC 6455 §4.1 makes a\n * client that offers a subprotocol and receives no echo fail the connection, so an unconditional\n * offer would break collab against every server built before negotiation shipped. The caller\n * decides, from the capability probe, and `negotiate.ts` holds the reasoning.\n */\n protocols?: string[];\n /** WebSocket constructor override (tests, non-browser runtimes). */\n webSocketImpl?: new (url: string, protocols?: string[]) => WsLike;\n /**\n * Called when the server refuses a doc with content-not-loaded: hydrate the file over HTTP (which\n * caches it server-side) so the retry can seed. One retry per open.\n */\n hydratePath?: (path: string) => Promise<void>;\n /** Give up on an openDoc after this long (falls back to solo editing). */\n openTimeoutMs?: number;\n /** Initial reconnect backoff (doubles to 30s). */\n reconnectDelayMs?: number;\n}\n\nexport interface WsCollabConnection {\n openDoc: (path: string) => Promise<CollabHandle | null>;\n status: () => CollabStatus;\n destroy: () => void;\n}\n\nconst WS_OPEN = 1;\n\ninterface DocEntry {\n doc: Y.Doc;\n epoch: number;\n opened: boolean;\n synced: boolean;\n hydrated: boolean;\n resolveOpen: ((ok: boolean) => void) | null;\n resolveSynced: () => void;\n whenSynced: Promise<void>;\n resetCbs: Set<() => void>;\n pendingFlush: Set<() => void>;\n handleDestroyed: boolean;\n /** Latest room-level dirty state from the server (survives reconnect on the same entry). */\n dirty: boolean;\n dirtyCbs: Set<(dirty: boolean) => void>;\n}\n\nexport function createWsCollabConnection(options: WsCollabConnectionOptions): WsCollabConnection {\n const WebSocketCtor =\n options.webSocketImpl ??\n (globalThis.WebSocket as unknown as new (url: string, protocols?: string[]) => WsLike);\n const openTimeoutMs = options.openTimeoutMs ?? 10_000;\n const docs = new Map<string, DocEntry>();\n const statusCbs = new Set<(status: CollabStatus) => void>();\n const awarenessDoc = new Y.Doc();\n const awareness = new Awareness(awarenessDoc);\n /* Clear the constructor's implicit {} state: it sits at clock 0, which applyAwarenessUpdate on\n the receiving side can never apply (currClock 0 < clock 0 is false) — publishing it would\n poison the server's controlled-id tracking. Real state arrives via setLocalState (clock ≥ 2). */\n awareness.setLocalState(null);\n\n let socket: WsLike | null = null;\n let identity: CollabIdentity | null = null;\n let status: CollabStatus = \"connecting\";\n let destroyed = false;\n let retryMs = options.reconnectDelayMs ?? 1000;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n\n const setStatus = (next: CollabStatus) => {\n if (status === next) {\n return;\n }\n status = next;\n for (const cb of statusCbs) {\n cb(next);\n }\n };\n\n const sendFrame = (frame: CollabFrame) => {\n if (socket && socket.readyState === WS_OPEN) {\n try {\n socket.send(encodeFrame(frame));\n } catch {\n // The close handler owns recovery.\n }\n }\n };\n\n const sendOpen = (path: string) => {\n sendFrame({ message: { path, type: \"open\" }, type: \"control\" });\n };\n\n // Local awareness changes always go to the wire (queued sends drop; awareness self-heals on\n // Reconnect via the full-state re-publish below).\n awareness.on(\n \"update\",\n (changes: { added: number[]; updated: number[]; removed: number[] }, origin: unknown) => {\n if (origin === \"remote\") {\n return;\n }\n const changed = [...changes.added, ...changes.updated, ...changes.removed];\n sendFrame({ body: encodeAwarenessUpdate(awareness, changed), type: \"awareness\" });\n },\n );\n\n const handleControl = (message: ControlMessage) => {\n switch (message.type) {\n case \"hello\": {\n identity = {\n color: message.color,\n login: message.login,\n permission: message.permission,\n ...(message.name === undefined ? {} : { name: message.name }),\n ...(message.avatarUrl === undefined ? {} : { avatarUrl: message.avatarUrl }),\n };\n return;\n }\n case \"opened\": {\n const entry = docs.get(message.path);\n if (!entry) {\n return;\n }\n if (entry.opened && entry.epoch !== message.epoch) {\n // The doc's history moved while we were away: this handle is dead.\n fireReset(message.path, entry);\n return;\n }\n entry.epoch = message.epoch;\n entry.opened = true;\n entry.resolveOpen?.(true);\n entry.resolveOpen = null;\n // Client-initiated step1 (mirrors y-websocket): fetch the server's state.\n const body = encoding.createEncoder();\n syncProtocol.writeSyncStep1(body, entry.doc);\n sendFrame({\n body: encoding.toUint8Array(body),\n epoch: entry.epoch,\n path: message.path,\n type: \"doc-sync\",\n });\n return;\n }\n case \"doc-reset\": {\n const entry = docs.get(message.path);\n if (entry) {\n fireReset(message.path, entry);\n }\n return;\n }\n case \"flush-ack\": {\n const entry = docs.get(message.path);\n if (entry) {\n for (const resolve of entry.pendingFlush) {\n resolve();\n }\n entry.pendingFlush.clear();\n }\n return;\n }\n case \"doc-dirty\": {\n const entry = docs.get(message.path);\n if (entry) {\n entry.dirty = message.dirty;\n for (const cb of entry.dirtyCbs) {\n cb(message.dirty);\n }\n }\n return;\n }\n case \"error\": {\n if (!message.path) {\n return;\n }\n const entry = docs.get(message.path);\n if (!entry) {\n return;\n }\n if (message.code === \"content-not-loaded\" && options.hydratePath && !entry.hydrated) {\n entry.hydrated = true;\n void options.hydratePath(message.path).then(\n () => sendOpen(message.path!),\n () => {\n entry.resolveOpen?.(false);\n entry.resolveOpen = null;\n },\n );\n return;\n }\n if (!entry.opened) {\n // Fatal refusal (binary-file, too-large, unresolved hydration): fall back to solo.\n entry.resolveOpen?.(false);\n entry.resolveOpen = null;\n }\n break;\n }\n default: {\n break;\n }\n }\n };\n\n const handleDocSync = (path: string, epoch: number, body: Uint8Array) => {\n const entry = docs.get(path);\n if (!entry || !entry.opened || entry.epoch !== epoch) {\n return;\n }\n const decoder = decoding.createDecoder(body);\n const reply = encoding.createEncoder();\n const messageType = syncProtocol.readSyncMessage(decoder, reply, entry.doc, \"remote\");\n if (encoding.length(reply) > 0) {\n sendFrame({ body: encoding.toUint8Array(reply), epoch, path, type: \"doc-sync\" });\n }\n if (messageType === syncProtocol.messageYjsSyncStep2 && !entry.synced) {\n entry.synced = true;\n entry.resolveSynced();\n }\n };\n\n const fireReset = (path: string, entry: DocEntry) => {\n docs.delete(path);\n entry.resolveOpen?.(false);\n entry.resolveOpen = null;\n for (const cb of entry.resetCbs) {\n cb();\n }\n entry.doc.destroy();\n };\n\n const connect = () => {\n if (destroyed) {\n return;\n }\n setStatus(\"connecting\");\n /* Re-offered on every reconnect: a socket that comes back after the server was restarted must\n negotiate again, and the offer is a property of this client's envelope, not of one socket. */\n const offer = options.protocols;\n const ws =\n offer === undefined || offer.length === 0\n ? new WebSocketCtor(options.url)\n : new WebSocketCtor(options.url, offer);\n socket = ws;\n ws.binaryType = \"arraybuffer\";\n /* Each connect() builds a FRESH socket; single-assignment handlers are the point (and keep\n the injectable WsLike test surface minimal). */\n // oxlint-disable-next-line unicorn/prefer-add-event-listener\n ws.onopen = () => {\n retryMs = options.reconnectDelayMs ?? 1000;\n setStatus(\"connected\");\n // Re-open every live doc and re-publish our awareness state.\n for (const path of docs.keys()) {\n sendOpen(path);\n }\n const local = awareness.getLocalState();\n if (local !== null) {\n sendFrame({\n body: encodeAwarenessUpdate(awareness, [awareness.clientID]),\n type: \"awareness\",\n });\n }\n };\n // oxlint-disable-next-line unicorn/prefer-add-event-listener\n ws.onmessage = (event) => {\n const raw = event.data;\n const data =\n raw instanceof ArrayBuffer ? new Uint8Array(raw) : raw instanceof Uint8Array ? raw : null;\n if (!data) {\n return;\n }\n let frame: CollabFrame;\n try {\n frame = decodeFrame(data);\n } catch {\n return;\n }\n switch (frame.type) {\n case \"control\": {\n handleControl(frame.message);\n return;\n }\n case \"doc-sync\": {\n handleDocSync(frame.path, frame.epoch, frame.body);\n return;\n }\n case \"awareness\": {\n applyAwarenessUpdate(awareness, frame.body, \"remote\");\n break;\n }\n default: {\n break;\n }\n }\n };\n // oxlint-disable-next-line unicorn/prefer-add-event-listener\n ws.onclose = () => {\n if (destroyed) {\n return;\n }\n setStatus(\"offline\");\n for (const entry of docs.values()) {\n entry.opened = false;\n }\n retryTimer = setTimeout(connect, retryMs);\n retryMs = Math.min(retryMs * 2, 30_000);\n };\n // oxlint-disable-next-line unicorn/prefer-add-event-listener\n ws.onerror = () => {\n // The close handler follows and owns retry.\n };\n };\n connect();\n\n return {\n destroy() {\n if (destroyed) {\n return;\n }\n destroyed = true;\n if (retryTimer) {\n clearTimeout(retryTimer);\n }\n removeAwarenessStates(awareness, [awareness.clientID], \"destroy\");\n awareness.destroy();\n awarenessDoc.destroy();\n for (const [path, entry] of docs) {\n entry.resolveOpen?.(false);\n entry.doc.destroy();\n docs.delete(path);\n }\n socket?.close();\n },\n\n async openDoc(path: string): Promise<CollabHandle | null> {\n if (destroyed) {\n return null;\n }\n const existing = docs.get(path);\n if (existing && !existing.handleDestroyed) {\n return null;\n }\n let resolveSynced: () => void = () => {};\n const whenSynced = new Promise<void>((resolve) => {\n resolveSynced = resolve;\n });\n const entry: DocEntry = {\n dirty: false,\n dirtyCbs: new Set(),\n doc: new Y.Doc(),\n epoch: 0,\n handleDestroyed: false,\n hydrated: false,\n opened: false,\n pendingFlush: new Set(),\n resetCbs: new Set(),\n resolveOpen: null,\n resolveSynced,\n synced: false,\n whenSynced,\n };\n docs.set(path, entry);\n\n // Local doc updates go to the wire (unless they came FROM the wire).\n entry.doc.on(\"update\", (update: Uint8Array, origin: unknown) => {\n if (origin === \"remote\" || !entry.opened) {\n return;\n }\n const body = encoding.createEncoder();\n syncProtocol.writeUpdate(body, update);\n sendFrame({\n body: encoding.toUint8Array(body),\n epoch: entry.epoch,\n path,\n type: \"doc-sync\",\n });\n });\n\n const openedOk = await new Promise<boolean>((resolve) => {\n entry.resolveOpen = resolve;\n const timer = setTimeout(() => {\n entry.resolveOpen = null;\n resolve(false);\n }, openTimeoutMs);\n entry.resolveOpen = (ok) => {\n clearTimeout(timer);\n resolve(ok);\n };\n sendOpen(path);\n });\n if (!openedOk) {\n if (docs.get(path) === entry) {\n docs.delete(path);\n }\n entry.doc.destroy();\n return null;\n }\n\n const handle: CollabHandle = {\n awareness,\n destroy: () => {\n if (entry.handleDestroyed) {\n return;\n }\n entry.handleDestroyed = true;\n if (docs.get(path) === entry) {\n docs.delete(path);\n sendFrame({ path, type: \"doc-close\" });\n }\n entry.doc.destroy();\n },\n doc: entry.doc,\n flush: () =>\n new Promise<void>((resolve) => {\n entry.pendingFlush.add(resolve);\n sendFrame({ message: { path, type: \"flush\" }, type: \"control\" });\n }),\n identity: () => identity,\n onDirty: (cb) => {\n entry.dirtyCbs.add(cb);\n // Deliver current state synchronously: the server's open-handshake `doc-dirty` may have\n // Already landed before the caller subscribes, and it must not miss the initial value.\n cb(entry.dirty);\n return () => entry.dirtyCbs.delete(cb);\n },\n onReset: (cb) => {\n entry.resetCbs.add(cb);\n return () => entry.resetCbs.delete(cb);\n },\n onStatus: (cb) => {\n statusCbs.add(cb);\n return () => statusCbs.delete(cb);\n },\n whenSynced: entry.whenSynced,\n };\n return handle;\n },\n\n status: () => status,\n };\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "1A24E7FF808B62FF64756E2164756E21",
10
+ "names": []
11
+ }