@marimo-team/islands 0.25.3-dev29 → 0.25.3-dev291

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 (844) hide show
  1. package/dist/{ConnectedDataExplorerComponent-7EaP9VWb.js → ConnectedDataExplorerComponent-CErm132k.js} +116 -113
  2. package/dist/{ErrorBoundary-ysC54Xwn.js → ErrorBoundary-Df7sOY5r.js} +76 -82
  3. package/dist/_baseSet-BfI5FjBM.js +328 -0
  4. package/dist/{abnfDiagram-VCTEODGH-z_OSynK8.js → abnfDiagram-VCTEODGH-d-Qn2fwb.js} +2 -2
  5. package/dist/any-language-editor-6k6F12Z3.js +75 -0
  6. package/dist/{architectureDiagram-5GKGNRK7-Cs8J8BZr.js → architectureDiagram-5GKGNRK7-DxragHYv.js} +1 -1
  7. package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
  8. package/dist/assertNever-B-YzWzbL.js +507 -0
  9. package/dist/assets/__vite-browser-external-BKBpimif.js +1 -0
  10. package/dist/assets/worker-CgoMtD-_.js +113 -0
  11. package/dist/{blockDiagram-I7D4REHJ-Cg25UrxT.js → blockDiagram-I7D4REHJ-Dkhe6_PP.js} +1 -1
  12. package/dist/{button-CvjkwdSk.js → button-DZuNnIZO.js} +56 -48
  13. package/dist/{capabilities-CQ5IjhzL.js → capabilities-D9FskwsK.js} +2 -2
  14. package/dist/{chat-ui-0udY4hpv.js → chat-ui-CoAmcc-W.js} +2100 -1810
  15. package/dist/{check-BMKBBrdc.js → check-XFzZeH-y.js} +1 -1
  16. package/dist/{chunk-IMKFNOWR-aoSFasqF.js → chunk-IMKFNOWR-C0x0feFg.js} +1 -1
  17. package/dist/{chunk-SHT3W25Y-CMaybO3O.js → chunk-SHT3W25Y-D0ZdASqB.js} +1 -1
  18. package/dist/{chunk-SVP7TREG-BNBrTAw1.js → chunk-SVP7TREG-BHjL96zx.js} +1 -1
  19. package/dist/{chunk-TICWLB2K-DXNxvUJn.js → chunk-TICWLB2K-CzcrwGfp.js} +1 -1
  20. package/dist/{classDiagram-ZZMXUADV-DXdCCDOg.js → classDiagram-ZZMXUADV-BTqFAZTP.js} +2 -2
  21. package/dist/{classDiagram-v2-VYDZK3BY-DyZqrtLP.js → classDiagram-v2-VYDZK3BY-EPXb0Elt.js} +2 -2
  22. package/dist/{code-visibility-CZmyRTO8.js → code-visibility-DO6O_8h-.js} +43 -50
  23. package/dist/{common-CCrzSQnL.js → common-Coz-wkOd.js} +10640 -10053
  24. package/dist/config-C8MFHQ2E.js +637 -0
  25. package/dist/{copy-icon-BgUO8jsi.js → copy-icon-CtllOdmg.js} +3 -3
  26. package/dist/createReducer-DRqwmaTc.js +67 -0
  27. package/dist/{cynefinDiagram-5FMLGOSQ-DWHuKJs8.js → cynefinDiagram-5FMLGOSQ-CBSD344q.js} +1 -1
  28. package/dist/{dagre-GXQ25YYZ-DYLu-OCU.js → dagre-GXQ25YYZ-JItjh3Ge.js} +3 -3
  29. package/dist/{dagre-BGSfXNEb.js → dagre-mqiMAsFY.js} +531 -680
  30. package/dist/{data-grid-overlay-editor-B141KnZO.js → data-grid-overlay-editor-LbsctrY7.js} +1 -1
  31. package/dist/{debounce-C3jyATpc.js → debounce-DrhhziJv.js} +2 -2
  32. package/dist/{diagram-S7CK7UJ4-PwwcUOHP.js → diagram-S7CK7UJ4-CTD9xTVb.js} +1 -1
  33. package/dist/{diagram-UQ7AKVKN-CvJbL_IM.js → diagram-UQ7AKVKN-DTfnFai8.js} +1 -1
  34. package/dist/{diagram-VX7I27RA-B5RkqnzN.js → diagram-VX7I27RA-BcSnucV-.js} +1 -1
  35. package/dist/{diagram-Z3DM3KII-CyijwTR2.js → diagram-Z3DM3KII-C2ATIE8A.js} +1 -1
  36. package/dist/{dialog-Cc479ZEH.js → dialog-CaYm5imE.js} +32 -32
  37. package/dist/{dist-Bvs24R_E.js → dist-11T5wq3_.js} +31 -30
  38. package/dist/{dist-F8Ep36rk.js → dist-17ugwGZc.js} +59 -58
  39. package/dist/{dist-BMQf5zIS.js → dist-7cRjf--y.js} +123 -122
  40. package/dist/{dist-diIx5qJW.js → dist-B8pkfkzc.js} +31 -30
  41. package/dist/{dist-CN_BeG2I.js → dist-B9UoM_wq.js} +58 -57
  42. package/dist/{dist-CLdpGQVr.js → dist-BGuMTs1i.js} +118 -117
  43. package/dist/{dist-BK4Oj99o.js → dist-BHW11fni.js} +18 -17
  44. package/dist/dist-BLY4m1Wi.js +850 -0
  45. package/dist/{dist-PXYI_yuP.js → dist-BNlcVoxs.js} +24 -23
  46. package/dist/{dist-D6d86eNJ.js → dist-BQYe5Bju.js} +47 -46
  47. package/dist/{dist-CkTTIdBe.js → dist-BX1mn8na.js} +337 -337
  48. package/dist/{dist-DiDibOYr.js → dist-Bh0PTKUW.js} +151 -150
  49. package/dist/{dist-CSJ0MDRw.js → dist-CKaXK92p.js} +56 -55
  50. package/dist/{dist-C8fAKSH1.js → dist-CLhwfhpJ.js} +53 -52
  51. package/dist/{dist-DoE4XJBC.js → dist-CYeqK4Xw.js} +9801 -10649
  52. package/dist/{dist-BLfKmR-l.js → dist-Cxlp3WH6.js} +16 -15
  53. package/dist/{dist-D-wwqlzJ.js → dist-DSJPGj42.js} +158 -157
  54. package/dist/{dist-BorMD-uX.js → dist-DU9ICsWZ.js} +75 -74
  55. package/dist/{dist-DBtSl3sf.js → dist-DWv0ALBi.js} +47 -46
  56. package/dist/{dist-OR1OnN-y.js → dist-DiBpWEsB.js} +31 -30
  57. package/dist/{dist-CrSP_H1M.js → dist-DiLFTlnl.js} +242 -242
  58. package/dist/{dist-CN8zI-XC.js → dist-X9CsotJl.js} +239 -239
  59. package/dist/{dist-CSbh1PNP.js → dist-cVDV5IuI.js} +23 -22
  60. package/dist/{dist-BuaRHxOc.js → dist-fRfaOoq8.js} +44 -43
  61. package/dist/{dist-Cg7gzw-a.js → dist-gTTI-9Px.js} +78 -77
  62. package/dist/{dropdown-menu-BuE2b8Yb.js → dropdown-menu-Bb0bFOIk.js} +2904 -1493
  63. package/dist/{ebnfDiagram-PWID7BFC-DG90ELFp.js → ebnfDiagram-PWID7BFC-B7B9JPxc.js} +2 -2
  64. package/dist/{erDiagram-RLTQ6QDP-FMo_SpyX.js → erDiagram-RLTQ6QDP-v6hDno1O.js} +1 -1
  65. package/dist/{error-banner-CFPHFw4h.js → error-banner-CHCdHVFB.js} +87 -87
  66. package/dist/error-entries-CQl9aZz1.js +2595 -0
  67. package/dist/{esm-AMFssoNp.js → esm-BDqqT86j.js} +329 -329
  68. package/dist/{esm-D2gTsXEV.js → esm-BgKjMvWw.js} +530 -529
  69. package/dist/feedback-button-DQXS8piQ.js +374 -0
  70. package/dist/{flowDiagram-HODETNUW-DQ4JuadE.js → flowDiagram-HODETNUW-aIFlAtOy.js} +2 -2
  71. package/dist/{formats-DRHUWwSK.js → formats-PzBQMUnr.js} +6 -6
  72. package/dist/{glide-data-editor-DLHbRbsj.js → glide-data-editor-CiTOpufo.js} +6630 -2846
  73. package/dist/{glide-utils-pisbYVjH.js → glide-utils-BSQr4d90.js} +107 -76
  74. package/dist/{globals-D2g1BHQ0.js → globals-Bmz_qpY8.js} +3 -3
  75. package/dist/{graphlib-BmY_CCV9.js → graphlib-nlwT3Wvy.js} +177 -220
  76. package/dist/hasIn-C20JsQ2m.js +28 -0
  77. package/dist/{error-entries-DgtRTNaG.js → html-to-image-DbxMq9QA.js} +26294 -26451
  78. package/dist/{infoDiagram-27XIBGKW-CRSDtRrd.js → infoDiagram-27XIBGKW-D6YHLeCP.js} +1 -1
  79. package/dist/isArrayLikeObject-B-HXCsex.js +626 -0
  80. package/dist/isEmpty-CdX7MTE1.js +14 -0
  81. package/dist/{ishikawaDiagram-5VMMS53U-DxLEUldB.js → ishikawaDiagram-5VMMS53U-D1ZvprOX.js} +1 -1
  82. package/dist/{kanban-definition-UXKFOSKX-BLhvu8o4.js → kanban-definition-UXKFOSKX-Bna_3BMr.js} +1 -1
  83. package/dist/{loader-BPdQhmlq.js → loader-DZvtzQoD.js} +3 -3
  84. package/dist/main.js +10276 -8171
  85. package/dist/{mermaid-Bjm6C1qN.js → mermaid-A36unKXJ.js} +62 -62
  86. package/dist/{mindmap-definition-YA3MSWOX-g2LwxnYQ.js → mindmap-definition-YA3MSWOX-CyVCs__G.js} +1 -1
  87. package/dist/{now-jM8-M7IR.js → now-BKZCLE5P.js} +12 -13
  88. package/dist/{number-overlay-editor-DHqP6YVn.js → number-overlay-editor-CXO_e1Yo.js} +1 -1
  89. package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
  90. package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
  91. package/dist/{pegDiagram-XKGWAZYB-CpMAt3Qs.js → pegDiagram-XKGWAZYB-9hNBD2wZ.js} +2 -2
  92. package/dist/pencil-DYUlSKxZ.js +10 -0
  93. package/dist/pick-tCszMUbm.js +35 -0
  94. package/dist/{pieDiagram-E7YTZNPT-CVTthoZo.js → pieDiagram-E7YTZNPT-8tr-NYo7.js} +1 -1
  95. package/dist/{process-output-CuIlhYwn.js → process-output-BHsfwmw9.js} +4 -4
  96. package/dist/{railroadDiagram-O6MQD6OU-ao8cqqFB.js → railroadDiagram-O6MQD6OU-Dzg1dyyp.js} +2 -2
  97. package/dist/{react-vega-BDpbvBCb.js → react-vega-C4T9Rb_w.js} +1 -1
  98. package/dist/{requirementDiagram-BXWQKSXE--J8vyfm-.js → requirementDiagram-BXWQKSXE-B7sNqwGG.js} +1 -1
  99. package/dist/{reveal-component-DYHhtPqq.js → reveal-component-CLRZbwl1.js} +1151 -1128
  100. package/dist/select-DsoP1qe8.js +1200 -0
  101. package/dist/{sequenceDiagram-WJ2MYXX4-CiQbn62x.js → sequenceDiagram-WJ2MYXX4-oP9shbaG.js} +1 -1
  102. package/dist/{spec-D_u2ipzF.js → spec-BZMDxAu7.js} +41 -11
  103. package/dist/{stateDiagram-D77RDMKH-DVEeGs5b.js → stateDiagram-D77RDMKH-CjCv4ogv.js} +4 -4
  104. package/dist/{stateDiagram-v2-MP3YSRHH-1OQRe6iA.js → stateDiagram-v2-MP3YSRHH-BW9X162a.js} +2 -2
  105. package/dist/static-state-D-Q-Ajaa.js +72 -0
  106. package/dist/style.css +1 -1
  107. package/dist/{swimlanes-42K2YHIH-CqkGoGqn.js → swimlanes-42K2YHIH-Ckfs9Wrn.js} +1 -1
  108. package/dist/{swimlanesDiagram-VR7AAH4N-CszjkrKo.js → swimlanesDiagram-VR7AAH4N-DpTNG9YP.js} +2 -2
  109. package/dist/{swiper-component-DKntyn8p.js → swiper-component-DQbK_ZWm.js} +7 -7
  110. package/dist/{timeline-definition-24CTP7MA-DLRUNVAx.js → timeline-definition-24CTP7MA-BXaBlV6U.js} +1 -1
  111. package/dist/toast-BhjIy3Tq.js +491 -0
  112. package/dist/{tooltip-CtBZ5q8p.js → tooltip-DMMiOn2f.js} +321 -297
  113. package/dist/use-restore-focus-CosX7-gx.js +7568 -0
  114. package/dist/{useAsyncData-BneN349z.js → useAsyncData-Ci4AvJff.js} +18 -17
  115. package/dist/{useDateFormatter-DkajGwwd.js → useDateFormatter-CPlava52.js} +2 -2
  116. package/dist/{useDeepCompareMemoize-Z_7R8wTt.js → useDeepCompareMemoize-NaaWoFlX.js} +1 -1
  117. package/dist/useEvent-BRH-aCqi.js +19 -0
  118. package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-BXhDDoCG.js} +1 -1
  119. package/dist/useLifecycle-SniivYmC.js +112 -0
  120. package/dist/{vega-component-1lFfDE_8.js → vega-component-DIxaDQNs.js} +161 -160
  121. package/dist/{vega-embed-container-BgKnsDbB.js → vega-embed-container--LYZqguO.js} +2 -2
  122. package/dist/{vega-loader.browser-CpbZAXub.js → vega-loader.browser-B9Pz0EGP.js} +1 -1
  123. package/dist/{vennDiagram-4TSXK5OY-CypgoBVZ.js → vennDiagram-4TSXK5OY-C-hQ4iNJ.js} +1 -1
  124. package/dist/{wardleyDiagram-VM6X3IG4-B6xjiQ_g.js → wardleyDiagram-VM6X3IG4-C2MQ_Umv.js} +1 -1
  125. package/dist/{xychartDiagram-S5SC5T6Z-e0PefDVs.js → xychartDiagram-S5SC5T6Z-BtTTBn7Q.js} +1 -1
  126. package/package.json +16 -20
  127. package/src/__mocks__/document.tsx +63 -0
  128. package/src/__mocks__/executions.ts +197 -0
  129. package/src/__mocks__/notebook.ts +3 -7
  130. package/src/__mocks__/partial.ts +26 -0
  131. package/src/__mocks__/requests.ts +1 -4
  132. package/src/__tests__/CellStatus.test.tsx +25 -26
  133. package/src/__tests__/fixtures/pair-config.ts +1 -1
  134. package/src/__tests__/main.test.tsx +24 -1
  135. package/src/__tests__/module-entry.test.ts +44 -0
  136. package/src/__tests__/mount.test.ts +1 -21
  137. package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
  138. package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
  139. package/src/components/ai/ai-model-dropdown.tsx +11 -6
  140. package/src/components/app-config/__tests__/state.test.tsx +50 -0
  141. package/src/components/app-config/ai-config.tsx +156 -150
  142. package/src/components/app-config/app-config-button.tsx +6 -5
  143. package/src/components/app-config/app-config-form.tsx +5 -9
  144. package/src/components/app-config/common.tsx +7 -9
  145. package/src/components/app-config/data-form.tsx +112 -113
  146. package/src/components/app-config/mcp-config.tsx +30 -53
  147. package/src/components/app-config/user-config-form.css +91 -0
  148. package/src/components/app-config/user-config-form.tsx +266 -349
  149. package/src/components/chat/__tests__/capabilities-popover.test.tsx +0 -1
  150. package/src/components/chat/__tests__/chat-display.test.tsx +196 -0
  151. package/src/components/chat/__tests__/chat-markdown.test.tsx +43 -0
  152. package/src/components/chat/__tests__/chat-utils.test.ts +93 -1
  153. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  154. package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
  155. package/src/components/chat/__tests__/turn-timing.test.ts +84 -0
  156. package/src/components/chat/__tests__/use-assistant-turn.test.ts +95 -0
  157. package/src/components/chat/__tests__/user-message.test.tsx +27 -0
  158. package/src/components/chat/acp/__tests__/agent-panel-initialization.test.tsx +1 -1
  159. package/src/components/chat/acp/__tests__/agent-panel.test.tsx +22 -17
  160. package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
  161. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  162. package/src/components/chat/acp/agent-panel.tsx +6 -3
  163. package/src/components/chat/acp/blocks.tsx +13 -12
  164. package/src/components/chat/acp/common.tsx +4 -5
  165. package/src/components/chat/acp/model-selector.tsx +1 -1
  166. package/src/components/chat/acp/session-tabs.tsx +8 -3
  167. package/src/components/chat/agent-activity.tsx +132 -0
  168. package/src/components/chat/capabilities-popover.tsx +2 -11
  169. package/src/components/chat/chat-components.tsx +9 -4
  170. package/src/components/chat/chat-display.tsx +131 -57
  171. package/src/components/chat/chat-history-popover.tsx +6 -1
  172. package/src/components/chat/chat-markdown.tsx +15 -0
  173. package/src/components/chat/chat-panel.tsx +216 -294
  174. package/src/components/chat/chat-typography.css +108 -0
  175. package/src/components/chat/chat-utils.ts +24 -35
  176. package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
  177. package/src/components/chat/notebook-access-selector.tsx +100 -0
  178. package/src/components/chat/tool-call/__tests__/tool-labels.test.ts +76 -0
  179. package/src/components/chat/tool-call/__tests__/tool-step.test.tsx +57 -0
  180. package/src/components/chat/tool-call/shared.ts +6 -0
  181. package/src/components/chat/tool-call/tool-call-view.tsx +22 -76
  182. package/src/components/chat/tool-call/tool-labels.ts +172 -0
  183. package/src/components/chat/tool-call/tool-result.tsx +1 -1
  184. package/src/components/chat/tool-call/tool-step.tsx +145 -0
  185. package/src/components/chat/turn-timing.ts +73 -0
  186. package/src/components/chat/use-assistant-turn.ts +65 -0
  187. package/src/components/chat/use-chat-generation.ts +20 -0
  188. package/src/components/chat/user-message.tsx +145 -0
  189. package/src/components/data-table/TableBottomBar.tsx +4 -1
  190. package/src/components/data-table/TableTopBar.tsx +2 -0
  191. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  192. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  193. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  194. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  195. package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
  196. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  197. package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
  198. package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
  199. package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
  200. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  201. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  202. package/src/components/data-table/cell-selection/feature.ts +2 -2
  203. package/src/components/data-table/cell-selection/types.ts +2 -2
  204. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  205. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  206. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  207. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  208. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  209. package/src/components/data-table/charts/charts.tsx +40 -30
  210. package/src/components/data-table/charts/storage.ts +16 -5
  211. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  212. package/src/components/data-table/column-formatting/types.ts +1 -2
  213. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  214. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  215. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  216. package/src/components/data-table/columns.tsx +45 -46
  217. package/src/components/data-table/context-menu.tsx +36 -20
  218. package/src/components/data-table/data-table.tsx +17 -1
  219. package/src/components/data-table/date-popover.tsx +6 -4
  220. package/src/components/data-table/export-actions.tsx +76 -48
  221. package/src/components/data-table/pagination.tsx +44 -33
  222. package/src/components/data-table/range-focus/atoms.ts +4 -6
  223. package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
  224. package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
  225. package/src/components/data-table/renderers.tsx +16 -7
  226. package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
  227. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
  228. package/src/components/data-table/search-highlight.tsx +79 -0
  229. package/src/components/data-table/types.ts +1 -0
  230. package/src/components/data-table/url-detector.tsx +49 -9
  231. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  232. package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
  233. package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
  234. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  235. package/src/components/datasources/__tests__/utils.test.ts +57 -6
  236. package/src/components/datasources/column-preview.tsx +17 -12
  237. package/src/components/datasources/datasources.tsx +56 -43
  238. package/src/components/datasources/utils.ts +32 -23
  239. package/src/components/debugger/debugger-code.tsx +5 -0
  240. package/src/components/dependency-graph/custom-node.tsx +1 -1
  241. package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
  242. package/src/components/dependency-graph/elements.ts +24 -21
  243. package/src/components/dependency-graph/minimap-content.tsx +15 -20
  244. package/src/components/dependency-graph/panels.tsx +4 -2
  245. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  246. package/src/components/editor/SortableCell.tsx +1 -3
  247. package/src/components/editor/__tests__/Output.test.tsx +50 -32
  248. package/src/{core/attachments/__tests__/toast.test.tsx → components/editor/__tests__/agent-toast.test.tsx} +1 -1
  249. package/src/components/editor/__tests__/data-attributes.test.tsx +28 -23
  250. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  251. package/src/components/editor/__tests__/output-persistence.test.tsx +28 -9
  252. package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
  253. package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
  254. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +21 -40
  255. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +41 -14
  256. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +6 -24
  257. package/src/components/editor/actions/__tests__/useCellActionButton.test.tsx +131 -0
  258. package/src/components/editor/actions/name-cell-input.tsx +4 -3
  259. package/src/components/editor/actions/pair-with-agent-commands.ts +10 -7
  260. package/src/components/editor/actions/pair-with-agent-modal.tsx +29 -30
  261. package/src/components/editor/actions/pair-with-agent.tsx +16 -39
  262. package/src/components/editor/actions/useCellActionButton.tsx +47 -35
  263. package/src/components/editor/actions/useConfigActions.tsx +3 -4
  264. package/src/components/editor/actions/useNotebookActions.tsx +25 -29
  265. package/src/components/editor/actions/useRestartKernel.tsx +1 -1
  266. package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
  267. package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
  268. package/src/components/editor/ai/ai-completion-editor.tsx +2 -1
  269. package/src/components/editor/ai/completion-handlers.tsx +0 -37
  270. package/src/components/editor/ai/prompt-input.tsx +189 -0
  271. package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
  272. package/src/components/editor/alerts/connection-notice.tsx +1 -1
  273. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  274. package/src/components/editor/alerts/stdin-blocking-alert.tsx +4 -2
  275. package/src/components/editor/app-container.tsx +1 -1
  276. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
  277. package/src/components/editor/cell/CellStatus.tsx +28 -23
  278. package/src/components/editor/cell/CreateCellButton.tsx +15 -21
  279. package/src/components/editor/cell/DeleteButton.tsx +3 -2
  280. package/src/components/editor/cell/RunButton.tsx +18 -8
  281. package/src/components/editor/cell/StagedAICell.tsx +52 -137
  282. package/src/components/editor/cell/StopButton.tsx +2 -2
  283. package/src/components/editor/cell/__tests__/useRunCells.test.tsx +169 -0
  284. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  285. package/src/components/editor/cell/cell-actions.tsx +12 -1
  286. package/src/components/editor/cell/cell-context-menu.tsx +4 -1
  287. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  288. package/src/components/editor/cell/code/cell-editor.tsx +65 -169
  289. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  290. package/src/components/editor/cell/collapse.tsx +16 -6
  291. package/src/components/editor/cell/useAddCell.ts +4 -8
  292. package/src/components/editor/cell/useDeleteCell.tsx +10 -36
  293. package/src/components/editor/cell/useRunCells.ts +49 -8
  294. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  295. package/src/components/editor/cell/useSplitCell.tsx +10 -6
  296. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
  297. package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
  298. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
  299. package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
  300. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
  301. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  302. package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
  303. package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
  304. package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
  305. package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
  306. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
  307. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  308. package/src/components/editor/chrome/panels/panel-header.tsx +13 -0
  309. package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
  310. package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
  311. package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
  312. package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
  313. package/src/components/editor/chrome/types.ts +1 -1
  314. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +7 -9
  315. package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
  316. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +265 -37
  317. package/src/components/editor/chrome/wrapper/__tests__/useAskAiAboutCell.test.tsx +58 -0
  318. package/src/components/editor/chrome/wrapper/app-chrome.tsx +91 -74
  319. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +4 -4
  320. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
  321. package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
  322. package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
  323. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
  324. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  325. package/src/components/editor/chrome/wrapper/footer.tsx +2 -2
  326. package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
  327. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +143 -72
  328. package/src/components/editor/chrome/wrapper/pending-ai-changes-badge.tsx +25 -0
  329. package/src/components/editor/chrome/wrapper/sidebar.tsx +8 -4
  330. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  331. package/src/components/editor/chrome/wrapper/useAskAiAboutCell.ts +36 -0
  332. package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
  333. package/src/components/editor/columns/cell-column.tsx +1 -1
  334. package/src/components/editor/columns/sortable-column.tsx +2 -2
  335. package/src/components/editor/connections/components.tsx +5 -10
  336. package/src/components/editor/controls/Controls.tsx +4 -4
  337. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  338. package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
  339. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
  340. package/src/components/editor/controls/command-palette.tsx +22 -10
  341. package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
  342. package/src/components/editor/documentation.css +34 -11
  343. package/src/components/editor/dynamic-favicon.tsx +21 -40
  344. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +26 -22
  345. package/src/components/editor/errors/auto-fix.tsx +4 -8
  346. package/src/components/editor/errors/send-error-report-button.tsx +3 -6
  347. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  348. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
  349. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  350. package/src/components/editor/file-tree/file-explorer.tsx +48 -15
  351. package/src/components/editor/file-tree/file-name-input.tsx +1 -0
  352. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  353. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  354. package/src/components/editor/header/__tests__/filename-form.test.tsx +1 -4
  355. package/src/components/editor/header/__tests__/status.test.tsx +5 -3
  356. package/src/components/editor/header/app-header.tsx +1 -1
  357. package/src/components/editor/header/filename-form.tsx +1 -1
  358. package/src/components/editor/header/status.tsx +44 -22
  359. package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
  360. package/src/components/editor/links/cell-link-list.tsx +1 -1
  361. package/src/components/editor/links/cell-link.tsx +21 -11
  362. package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
  363. package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
  364. package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
  365. package/src/components/editor/navigation/clipboard.ts +17 -14
  366. package/src/components/editor/navigation/focus-utils.ts +23 -4
  367. package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
  368. package/src/components/editor/navigation/navigation.ts +74 -72
  369. package/src/components/editor/navigation/selection.ts +30 -29
  370. package/src/components/editor/notebook-banner.tsx +1 -0
  371. package/src/components/editor/notebook-cell.tsx +126 -152
  372. package/src/components/editor/output/MarimoErrorOutput.tsx +41 -4
  373. package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
  374. package/src/components/editor/output/Outputs.css +8 -0
  375. package/src/components/editor/output/VideoOutput.tsx +6 -0
  376. package/src/components/editor/output/__tests__/VideoOutput.test.tsx +131 -0
  377. package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
  378. package/src/components/editor/output/ansi-reduce.ts +33 -20
  379. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  380. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
  381. package/src/components/editor/package-alert.tsx +14 -7
  382. package/src/components/editor/renderers/__tests__/add-cell-buttons.test.tsx +18 -0
  383. package/src/components/editor/renderers/cell-array.tsx +32 -100
  384. package/src/components/editor/renderers/grid-layout/__tests__/grid-layout.test.tsx +75 -0
  385. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +28 -22
  386. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -4
  387. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
  388. package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
  389. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  390. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
  391. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +19 -37
  392. package/src/components/editor/stdin-blocking-alert.tsx +4 -2
  393. package/src/components/home/components.tsx +17 -31
  394. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  395. package/src/components/icons/large-spinner.tsx +3 -14
  396. package/src/components/icons/spinner.tsx +1 -1
  397. package/src/components/markdown/markdown-renderer.tsx +39 -28
  398. package/src/components/mcp/mcp-status-indicator.tsx +18 -14
  399. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  400. package/src/components/pages/edit-page.tsx +19 -17
  401. package/src/components/pages/home-page.tsx +164 -91
  402. package/src/components/scratchpad/scratchpad.test.tsx +89 -0
  403. package/src/components/scratchpad/scratchpad.tsx +47 -33
  404. package/src/components/scratchpad/state.ts +7 -0
  405. package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
  406. package/src/components/slides/__tests__/minimap.test.ts +38 -19
  407. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
  408. package/src/components/slides/minimap.tsx +22 -14
  409. package/src/components/slides/reveal-component.tsx +73 -36
  410. package/src/components/slides/reveal-slides.css +5 -4
  411. package/src/components/slides/slide-cell-view.tsx +37 -34
  412. package/src/components/slides/slide-form.tsx +1 -0
  413. package/src/components/slides/slide-scroll-hint.tsx +3 -1
  414. package/src/components/slides/slide.tsx +3 -4
  415. package/src/components/sort/SortableCellsProvider.tsx +8 -25
  416. package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
  417. package/src/components/tracing/tracing.tsx +46 -42
  418. package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
  419. package/src/components/ui/__tests__/fullscreen.test.tsx +44 -2
  420. package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
  421. package/src/components/ui/alert-dialog.tsx +1 -1
  422. package/src/components/ui/draggable-popover.tsx +24 -2
  423. package/src/components/ui/fullscreen.tsx +25 -1
  424. package/src/components/ui/range-slider.tsx +22 -9
  425. package/src/components/ui/toast.tsx +1 -1
  426. package/src/core/MarimoApp.tsx +3 -1
  427. package/src/core/ai/__tests__/staged-cells.test.ts +89 -608
  428. package/src/core/ai/context/context.ts +2 -0
  429. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
  430. package/src/core/ai/context/providers/__tests__/cell.test.ts +49 -0
  431. package/src/core/ai/context/providers/cell-output.ts +2 -2
  432. package/src/core/ai/context/providers/cell.ts +54 -0
  433. package/src/core/ai/context/providers/datasource.ts +6 -2
  434. package/src/core/ai/staged-cells.ts +56 -323
  435. package/src/core/ai/state.ts +3 -0
  436. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
  437. package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
  438. package/src/core/ai/tools/base.ts +18 -15
  439. package/src/core/ai/tools/edit-notebook-tool.ts +86 -80
  440. package/src/core/ai/tools/registry.ts +13 -10
  441. package/src/core/ai/tools/sample-tool.ts +6 -7
  442. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -527
  443. package/src/core/cells/__tests__/actions.test.ts +623 -35
  444. package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
  445. package/src/core/cells/__tests__/arrange.test.ts +432 -0
  446. package/src/core/cells/__tests__/cell.test.ts +148 -150
  447. package/src/core/cells/__tests__/cells.test.ts +390 -2925
  448. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  449. package/src/core/cells/__tests__/document.test.ts +158 -0
  450. package/src/core/cells/__tests__/editor.test.ts +57 -0
  451. package/src/core/cells/__tests__/flush-document.test.ts +40 -0
  452. package/src/core/cells/__tests__/harness.ts +106 -0
  453. package/src/core/cells/__tests__/layout.test.ts +176 -0
  454. package/src/core/cells/__tests__/logs.test.ts +0 -13
  455. package/src/core/cells/__tests__/notebook-outline.test.ts +122 -0
  456. package/src/core/cells/__tests__/outputs.test.tsx +71 -53
  457. package/src/core/cells/__tests__/pending-delete-service.test.tsx +11 -20
  458. package/src/core/cells/__tests__/session.test.ts +445 -211
  459. package/src/core/cells/__tests__/utils.test.ts +135 -337
  460. package/src/core/cells/actions.ts +677 -6
  461. package/src/core/cells/add-missing-import.ts +47 -43
  462. package/src/core/cells/arrange.ts +529 -0
  463. package/src/core/cells/cell.ts +78 -146
  464. package/src/core/cells/cells.ts +116 -1457
  465. package/src/core/cells/columns.ts +38 -0
  466. package/src/core/cells/document.ts +167 -0
  467. package/src/core/cells/edit.ts +30 -0
  468. package/src/core/cells/editor.ts +82 -0
  469. package/src/core/cells/focus.ts +27 -6
  470. package/src/core/cells/layout.ts +221 -0
  471. package/src/core/cells/outputs.ts +12 -28
  472. package/src/core/cells/pending-delete-service.ts +8 -14
  473. package/src/core/cells/scrollCellIntoView.ts +6 -0
  474. package/src/core/cells/session.ts +76 -53
  475. package/src/core/cells/types.ts +21 -51
  476. package/src/core/cells/utils.ts +85 -87
  477. package/src/core/codemirror/__tests__/format.test.ts +0 -34
  478. package/src/core/codemirror/__tests__/setup.test.ts +61 -29
  479. package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
  480. package/src/core/codemirror/ai/resources.ts +1 -1
  481. package/src/core/codemirror/cells/__tests__/extensions.test.ts +2 -6
  482. package/src/core/codemirror/cells/extensions.ts +18 -30
  483. package/src/core/codemirror/cells/state.ts +2 -6
  484. package/src/core/codemirror/cm.ts +5 -1
  485. package/src/core/codemirror/config/types.ts +1 -1
  486. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
  487. package/src/core/codemirror/copilot/getCodes.ts +2 -2
  488. package/src/core/codemirror/format.ts +6 -23
  489. package/src/core/codemirror/keymaps/vim.ts +4 -8
  490. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  491. package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
  492. package/src/core/codemirror/language/cell-code.ts +114 -0
  493. package/src/core/codemirror/language/extension.ts +52 -35
  494. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  495. package/src/core/codemirror/language/languages/python.ts +19 -13
  496. package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
  497. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  498. package/src/core/codemirror/language/types.ts +7 -7
  499. package/src/core/codemirror/language/utils.ts +9 -39
  500. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
  501. package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
  502. package/src/core/codemirror/lsp/utils.ts +1 -1
  503. package/src/core/codemirror/misc/__tests__/paste.test.ts +3 -1
  504. package/src/core/codemirror/misc/paste.ts +1 -1
  505. package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +75 -0
  506. package/src/core/codemirror/placeholder/extensions.ts +80 -19
  507. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  508. package/src/core/codemirror/readonly/extension.ts +2 -2
  509. package/src/core/codemirror/utils.ts +1 -0
  510. package/src/core/config/__tests__/app-config.test.ts +64 -0
  511. package/src/core/config/__tests__/config-schema.test.ts +56 -6
  512. package/src/core/config/config-schema.ts +17 -4
  513. package/src/core/config/config.ts +65 -20
  514. package/src/core/config/feature-flag.tsx +0 -2
  515. package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
  516. package/src/core/datasets/data-source-discovery.ts +4 -6
  517. package/src/core/documentation/doc-lookup.ts +1 -1
  518. package/src/core/dom/outline.ts +4 -1
  519. package/src/core/edit-app.tsx +22 -28
  520. package/src/core/errors/__tests__/error-entries.test.ts +40 -1
  521. package/src/core/errors/error-entries.ts +6 -4
  522. package/src/core/executions/__tests__/atoms.test.ts +98 -0
  523. package/src/core/executions/__tests__/freshness.test.ts +482 -0
  524. package/src/core/executions/__tests__/hooks.test.tsx +151 -0
  525. package/src/core/executions/__tests__/output.test.ts +266 -0
  526. package/src/core/executions/__tests__/select.test.ts +268 -0
  527. package/src/core/executions/atoms.ts +263 -0
  528. package/src/core/executions/freshness.ts +171 -0
  529. package/src/core/executions/hooks.ts +86 -0
  530. package/src/core/executions/index.ts +48 -0
  531. package/src/core/executions/output.ts +242 -0
  532. package/src/core/executions/select.ts +175 -0
  533. package/src/core/export/__tests__/hooks.test.ts +0 -5
  534. package/src/core/export/hooks.ts +1 -1
  535. package/src/core/export/layout.ts +2 -2
  536. package/src/core/hotkeys/actions.ts +2 -4
  537. package/src/core/hotkeys/hotkeys.ts +2 -1
  538. package/src/core/islands/__tests__/bootstrap.test.ts +69 -17
  539. package/src/core/islands/__tests__/bridge.test.ts +85 -27
  540. package/src/core/islands/bootstrap.ts +49 -54
  541. package/src/core/islands/bridge.ts +84 -25
  542. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  543. package/src/core/islands/components/__tests__/web-components.test.tsx +63 -0
  544. package/src/core/islands/components/output-wrapper.tsx +5 -5
  545. package/src/core/islands/components/web-components.tsx +12 -1
  546. package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
  547. package/src/core/islands/worker/controller.ts +4 -10
  548. package/src/core/islands/worker/worker.tsx +33 -33
  549. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  550. package/src/core/kernel/__tests__/handlers.test.ts +7 -157
  551. package/src/core/kernel/handlers.ts +13 -79
  552. package/src/core/kernel/state.ts +0 -15
  553. package/src/core/lifecycle/render-policy.ts +12 -26
  554. package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
  555. package/src/core/meta/code-visibility.ts +18 -9
  556. package/src/core/network/__tests__/connection.test.ts +1 -1
  557. package/src/core/network/__tests__/requests-lazy.test.ts +6 -8
  558. package/src/core/network/connection-notice.ts +1 -1
  559. package/src/core/network/connection.ts +1 -1
  560. package/src/core/network/requests-lazy.ts +5 -8
  561. package/src/core/network/requests-network.ts +5 -31
  562. package/src/core/network/requests-static.ts +1 -4
  563. package/src/core/network/requests-toasting.tsx +1 -4
  564. package/src/core/network/types.ts +6 -14
  565. package/src/core/network/useConnectionNotice.ts +8 -2
  566. package/src/core/notebook/__tests__/operations.test.ts +51 -0
  567. package/src/core/notebook/attachments.ts +38 -0
  568. package/src/core/notebook/document/__tests__/codemirror.test.ts +759 -0
  569. package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
  570. package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
  571. package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
  572. package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  573. package/src/core/notebook/document/__tests__/model.test.ts +247 -0
  574. package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
  575. package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
  576. package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
  577. package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
  578. package/src/core/notebook/document/__tests__/state.test.ts +459 -0
  579. package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
  580. package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
  581. package/src/core/notebook/document/__tests__/test-host.ts +247 -0
  582. package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
  583. package/src/core/notebook/document/__tests__/user.ts +61 -0
  584. package/src/core/notebook/document/codemirror.ts +216 -0
  585. package/src/core/notebook/document/draft.ts +502 -0
  586. package/src/core/notebook/document/hooks.tsx +118 -0
  587. package/src/core/notebook/document/index.ts +24 -0
  588. package/src/core/notebook/document/model.ts +102 -0
  589. package/src/core/notebook/document/select.ts +41 -0
  590. package/src/core/notebook/document/state.ts +378 -0
  591. package/src/core/notebook/document/sync.ts +369 -0
  592. package/src/core/notebook/index.ts +19 -0
  593. package/src/core/notebook/operations.ts +30 -0
  594. package/src/core/notebook/replica/AGENTS.md +11 -0
  595. package/src/core/{host → notebook/replica}/__tests__/attachments.test.ts +9 -10
  596. package/src/core/{host → notebook/replica}/__tests__/document.test.ts +18 -16
  597. package/src/core/notebook/replica/__tests__/executions.test.ts +200 -0
  598. package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
  599. package/src/core/notebook/replica/__tests__/replica.test.ts +559 -0
  600. package/src/core/notebook/replica/__tests__/results.test.ts +193 -0
  601. package/src/core/notebook/replica/__tests__/runtime.test.ts +78 -0
  602. package/src/core/notebook/replica/backend.ts +19 -0
  603. package/src/core/notebook/replica/connection.ts +42 -0
  604. package/src/core/notebook/replica/index.ts +20 -0
  605. package/src/core/notebook/replica/replica.ts +336 -0
  606. package/src/core/{host → notebook/replica}/resources/attachments.ts +6 -3
  607. package/src/core/{host → notebook/replica}/resources/document.ts +3 -3
  608. package/src/core/notebook/replica/resources/executions.ts +157 -0
  609. package/src/core/notebook/replica/resources/results.ts +48 -0
  610. package/src/core/notebook/replica/resources/runtime.ts +14 -0
  611. package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
  612. package/src/core/packages/useSandboxController.ts +1 -1
  613. package/src/core/run-app.tsx +49 -51
  614. package/src/core/runtime/__tests__/adapter.test.ts +4 -4
  615. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  616. package/src/core/runtime/__tests__/runtime.test.ts +32 -74
  617. package/src/core/runtime/adapter.ts +5 -5
  618. package/src/core/runtime/config.ts +2 -2
  619. package/src/core/runtime/runtime.ts +33 -46
  620. package/src/core/runtime/types.ts +0 -2
  621. package/src/core/saving/__tests__/document.test.tsx +123 -0
  622. package/src/core/saving/__tests__/state.test.ts +111 -0
  623. package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
  624. package/src/core/saving/document.ts +33 -0
  625. package/src/core/saving/filename.ts +1 -1
  626. package/src/core/saving/save-component.tsx +39 -60
  627. package/src/core/saving/state.ts +38 -39
  628. package/src/core/saving/useAutoSave.ts +17 -53
  629. package/src/core/session/__tests__/backend.test.ts +236 -0
  630. package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +186 -0
  631. package/src/core/{websocket → session}/__tests__/useNotebookSession.hook.test.tsx +245 -262
  632. package/src/core/session/active-notebook.ts +28 -0
  633. package/src/core/session/backend.ts +123 -0
  634. package/src/core/session/embedded.ts +7 -0
  635. package/src/core/{websocket → session}/types.ts +2 -2
  636. package/src/core/session/useNotebookReplica.ts +74 -0
  637. package/src/core/{websocket → session}/useNotebookSession.tsx +80 -67
  638. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  639. package/src/core/state/jotai.ts +1 -1
  640. package/src/core/static/__tests__/files.test.ts +38 -10
  641. package/src/core/static/files.ts +2 -0
  642. package/src/core/{websocket → transports}/__tests__/connection-state.test.ts +1 -13
  643. package/src/core/transports/__tests__/server.test.ts +408 -0
  644. package/src/core/transports/__tests__/static.test.ts +306 -0
  645. package/src/core/transports/__tests__/wasm.test.ts +166 -0
  646. package/src/core/{websocket → transports}/connection-state.ts +9 -16
  647. package/src/core/transports/server.ts +152 -0
  648. package/src/core/transports/static.ts +166 -0
  649. package/src/core/transports/wasm.ts +97 -0
  650. package/src/core/vscode/__tests__/vscode-bindings.test.ts +125 -0
  651. package/src/core/vscode/vscode-bindings.ts +14 -2
  652. package/src/core/wasm/__tests__/bridge.test.ts +210 -64
  653. package/src/core/wasm/__tests__/worker.test.ts +188 -0
  654. package/src/core/wasm/bridge.ts +120 -73
  655. package/src/core/wasm/rpc.ts +15 -3
  656. package/src/core/wasm/store.ts +3 -3
  657. package/src/core/wasm/worker/bootstrap.ts +55 -51
  658. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  659. package/src/core/wasm/worker/save-worker.ts +9 -10
  660. package/src/core/wasm/worker/types.ts +30 -18
  661. package/src/core/wasm/worker/worker.ts +118 -72
  662. package/src/css/app/Cell.css +7 -36
  663. package/src/css/app/codemirror.css +1 -1
  664. package/src/css/common.css +1 -1
  665. package/src/css/globals.css +72 -24
  666. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  667. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  668. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  669. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  670. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  671. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  672. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  673. package/src/hooks/useAsyncData.ts +3 -3
  674. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  675. package/src/hooks/useDebounce.ts +6 -10
  676. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  677. package/src/hooks/useDelayElapsed.ts +14 -10
  678. package/src/hooks/useElapsedTime.ts +3 -3
  679. package/src/hooks/useEventListener.ts +1 -2
  680. package/src/hooks/useInputHistory.ts +4 -7
  681. package/src/hooks/useInternalStateWithSync.ts +6 -6
  682. package/src/hooks/useResizeObserver.ts +4 -7
  683. package/src/hooks/useScript.ts +67 -70
  684. package/src/hooks/useStateForKey.ts +93 -0
  685. package/src/mount.tsx +20 -15
  686. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  687. package/src/plugins/core/RenderHTML.tsx +3 -5
  688. package/src/plugins/core/__test__/RenderHTML-copy.test.tsx +60 -0
  689. package/src/plugins/core/registerReactComponent.tsx +5 -14
  690. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  691. package/src/plugins/impl/DataEditorPlugin.tsx +34 -13
  692. package/src/plugins/impl/DataTablePlugin.tsx +69 -37
  693. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  694. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  695. package/src/plugins/impl/FormPlugin.tsx +1 -1
  696. package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
  697. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  698. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  699. package/src/plugins/impl/__tests__/DataEditorPlugin.test.ts +93 -4
  700. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +387 -1
  701. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  702. package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
  703. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  704. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
  705. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  706. package/src/plugins/impl/anywidget/model.ts +3 -1
  707. package/src/plugins/impl/anywidget/registry.ts +18 -14
  708. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  709. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  710. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  711. package/src/plugins/impl/chat/chat-ui.tsx +17 -15
  712. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  713. package/src/plugins/impl/common/error-banner.tsx +5 -3
  714. package/src/plugins/impl/data-editor/__tests__/column-types.test.ts +42 -0
  715. package/src/plugins/impl/data-editor/__tests__/editor-state.test.ts +52 -1
  716. package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +120 -4
  717. package/src/plugins/impl/data-editor/__tests__/glide-utils.test.ts +116 -0
  718. package/src/plugins/impl/data-editor/column-types.ts +55 -0
  719. package/src/plugins/impl/data-editor/editor-state.ts +18 -2
  720. package/src/plugins/impl/data-editor/glide-data-editor.tsx +74 -12
  721. package/src/plugins/impl/data-editor/glide-utils.ts +39 -38
  722. package/src/plugins/impl/data-editor/types.ts +5 -0
  723. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  724. package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
  725. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  726. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  727. package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
  728. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
  729. package/src/plugins/impl/data-frames/panel.tsx +44 -16
  730. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  731. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  732. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  733. package/src/plugins/impl/panel/utils.ts +17 -0
  734. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  735. package/src/plugins/impl/plotly/selection.ts +25 -19
  736. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  737. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  738. package/src/plugins/layout/DownloadPlugin.tsx +7 -11
  739. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  740. package/src/plugins/layout/__test__/DownloadPlugin.test.tsx +205 -0
  741. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  742. package/src/stories/button.stories.tsx +1 -0
  743. package/src/stories/cell-status.stories.tsx +29 -24
  744. package/src/stories/cell.stories.tsx +46 -46
  745. package/src/stories/data-table.stories.tsx +31 -0
  746. package/src/stories/editor.stories.tsx +24 -17
  747. package/src/stories/form-wrapper.stories.tsx +2 -2
  748. package/src/stories/layout/vertical/one-column.stories.tsx +28 -42
  749. package/src/stories/runtime-story.tsx +23 -17
  750. package/src/stories/select.stories.tsx +2 -2
  751. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  752. package/src/theme/__tests__/islands-theme.test.tsx +276 -0
  753. package/src/theme/namespace.tsx +4 -3
  754. package/src/theme/useTheme.ts +71 -41
  755. package/src/utils/__tests__/arrays.test.ts +35 -0
  756. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  757. package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +127 -1
  758. package/src/utils/__tests__/download.test.tsx +183 -23
  759. package/src/utils/__tests__/numbers.test.ts +105 -1
  760. package/src/utils/__tests__/objects.test.ts +21 -0
  761. package/src/utils/arrays.ts +11 -2
  762. package/src/utils/blob.ts +1 -1
  763. package/src/utils/createReducer.ts +115 -79
  764. package/src/utils/download.ts +67 -6
  765. package/src/utils/maps.ts +0 -3
  766. package/src/utils/numbers.ts +79 -18
  767. package/src/utils/objects.ts +4 -9
  768. package/src/utils/time.ts +10 -0
  769. package/src/utils/tracer.ts +9 -5
  770. package/src/utils/zod-utils.ts +1 -3
  771. package/dist/_baseMerge-BiGRwuqv.js +0 -165
  772. package/dist/any-language-editor-D4q-IFcM.js +0 -76
  773. package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
  774. package/dist/assets/worker-HPY9fbhz.js +0 -114
  775. package/dist/feedback-button-CykZqHY-.js +0 -379
  776. package/dist/hasIn-o2Us0uVx.js +0 -132
  777. package/dist/html-to-image--r0l9wUy.js +0 -3251
  778. package/dist/isArrayLikeObject-BZl-15ir.js +0 -450
  779. package/dist/isEmpty-BSZ1LaUo.js +0 -35
  780. package/dist/isSymbol-kQcfYbNX.js +0 -8
  781. package/dist/label-DoysmLMW.js +0 -281
  782. package/dist/pick-CJeoxYOS.js +0 -51
  783. package/dist/select-DemoKT4G.js +0 -1344
  784. package/dist/toDate-gyi35XS2.js +0 -1185
  785. package/dist/toast-PkdZraM8.js +0 -1830
  786. package/dist/use-restore-focus-CKjfFjLM.js +0 -6369
  787. package/dist/useLifecycle-Dfq8UD-b.js +0 -169
  788. package/dist/useTheme-Bu5bBgrh.js +0 -904
  789. package/src/components/chat/reasoning-accordion.tsx +0 -61
  790. package/src/components/chat/tool-call/tool-error-card.tsx +0 -81
  791. package/src/components/chat/tool-call/tool-history-row.tsx +0 -174
  792. package/src/components/editor/ai/__tests__/staged-cell-submission.test.ts +0 -106
  793. package/src/components/editor/ai/add-cell-with-ai.tsx +0 -506
  794. package/src/components/editor/ai/staged-cell-submission.ts +0 -46
  795. package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +0 -64
  796. package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +0 -50
  797. package/src/components/editor/chrome/wrapper/footer-items/rtc-status.tsx +0 -65
  798. package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
  799. package/src/components/editor/navigation/state.ts +0 -65
  800. package/src/components/icons/loading-ellipsis.tsx +0 -46
  801. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
  802. package/src/core/ai/tools/run-cells-tool.ts +0 -303
  803. package/src/core/attachments/state.ts +0 -18
  804. package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
  805. package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
  806. package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
  807. package/src/core/cells/document-changes.ts +0 -944
  808. package/src/core/codemirror/rtc/extension.ts +0 -453
  809. package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +0 -52
  810. package/src/core/codemirror/rtc/loro/awareness.ts +0 -531
  811. package/src/core/codemirror/rtc/loro/colors.ts +0 -38
  812. package/src/core/codemirror/rtc/loro/sync.ts +0 -168
  813. package/src/core/host/AGENTS.md +0 -11
  814. package/src/core/host/__tests__/events.test.ts +0 -46
  815. package/src/core/host/__tests__/fixtures.ts +0 -39
  816. package/src/core/host/__tests__/notebook-client.test.ts +0 -433
  817. package/src/core/host/__tests__/protocol.test.ts +0 -229
  818. package/src/core/host/__tests__/stream.test.ts +0 -209
  819. package/src/core/host/connection.ts +0 -81
  820. package/src/core/host/events.ts +0 -61
  821. package/src/core/host/notebook-client.ts +0 -290
  822. package/src/core/host/protocol.ts +0 -1948
  823. package/src/core/host/resources/resource.ts +0 -47
  824. package/src/core/host/stream.ts +0 -211
  825. package/src/core/rtc/state.ts +0 -34
  826. package/src/core/state/__tests__/jotai.test.ts +0 -25
  827. package/src/core/wasm/worker/message-buffer.ts +0 -33
  828. package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
  829. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -170
  830. package/src/core/websocket/state.ts +0 -7
  831. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  832. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
  833. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  834. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  835. package/src/core/websocket/transports/basic.ts +0 -102
  836. package/src/core/websocket/transports/create.ts +0 -31
  837. package/src/core/websocket/transports/sse.ts +0 -308
  838. package/src/core/websocket/transports/transport.ts +0 -50
  839. package/src/core/websocket/transports/ws.ts +0 -98
  840. package/src/core/websocket/useNotebookClient.ts +0 -88
  841. package/src/utils/__tests__/id-tree.test.ts +0 -2145
  842. package/src/utils/id-tree.tsx +0 -1134
  843. /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
  844. /package/src/core/{websocket → session}/connection-utils.ts +0 -0
@@ -1,944 +0,0 @@
1
- /* Copyright 2026 Marimo. All rights reserved. */
2
-
3
- /**
4
- * Document changes: the bridge between notebook reducer actions and the
5
- * document transaction wire format.
6
- *
7
- * Pure functions:
8
- * - toDocumentChanges: reducer action + state diff → document changes
9
- * - fromDocumentChanges: document changes → reducer actions
10
- * - cancelledCellIds: detect create+delete cancellations
11
- *
12
- * Impure wrappers (for use by the reducer middleware and websocket):
13
- * - documentTransactionMiddleware: debounces and sends changes to the server
14
- * - applyTransactionChanges: dispatches actions from incoming changes
15
- */
16
-
17
- import { debounce } from "lodash-es";
18
- import { assertNever } from "@/utils/assertNever";
19
- import type { DispatchedActionOf } from "@/utils/createReducer";
20
- import { Deferred } from "@/utils/Deferred";
21
- import { Logger } from "@/utils/Logger";
22
- import type { NotificationMessageData } from "../kernel/messages";
23
- import { kioskModeAtom } from "../mode";
24
- import { getRequestClient } from "../network/requests";
25
- import type { NotebookDocumentTransactionRequest } from "../network/types";
26
- import { store } from "../state/jotai";
27
- import type { CellActions, NotebookState } from "./cells";
28
- import type { CellId } from "./ids";
29
- import { SCRATCH_CELL_ID } from "./ids";
30
- import type { CellData } from "./types";
31
-
32
- export type DocumentChange =
33
- NotebookDocumentTransactionRequest["changes"][number];
34
-
35
- type Transaction =
36
- NotificationMessageData<"notebook-document-transaction">["transaction"];
37
- type TransactionChange = Transaction["changes"][number];
38
-
39
- export type CellAction = DispatchedActionOf<CellActions>;
40
-
41
- // ---------------------------------------------------------------------------
42
- // Helpers
43
- // ---------------------------------------------------------------------------
44
-
45
- /**
46
- * Look up a cell in state by ID. Logs a warning and returns undefined
47
- * if the cell doesn't exist.
48
- */
49
- function getCell(
50
- cellId: CellId | undefined,
51
- state: NotebookState,
52
- ): CellData | undefined {
53
- if (!cellId) {
54
- Logger.warn("getCell: cellId is undefined");
55
- return undefined;
56
- }
57
- const cell = state.cellData[cellId];
58
- if (!cell) {
59
- Logger.warn(`getCell: cell ${cellId} not found in state`);
60
- return undefined;
61
- }
62
- return cell;
63
- }
64
-
65
- /**
66
- * Derive the position anchor for a cell from the notebook state.
67
- * Returns `{ after: prevId }` if there's a cell before it,
68
- * `{ before: nextId }` if it's the first cell, or `undefined` if it's alone.
69
- */
70
- function anchorOf(
71
- cellId: CellId,
72
- state: NotebookState,
73
- ): { after: CellId } | { before: CellId } | undefined {
74
- const ids = state.cellIds.inOrderIds;
75
- const idx = ids.indexOf(cellId);
76
- if (idx > 0) {
77
- return { after: ids[idx - 1] };
78
- }
79
- if (idx === 0 && ids.length > 1) {
80
- return { before: ids[1] };
81
- }
82
- return undefined;
83
- }
84
-
85
- /**
86
- * Build a map from cellId → column index for all cells in the state.
87
- */
88
- function columnIndexMap(state: NotebookState): Map<CellId, number> {
89
- const map = new Map<CellId, number>();
90
- const columns = state.cellIds.getColumns();
91
- for (const [col, column] of columns.entries()) {
92
- for (const id of column.inOrderIds) {
93
- map.set(id, col);
94
- }
95
- }
96
- return map;
97
- }
98
-
99
- /**
100
- * Find cells that were added between prevState and newState and return
101
- * create-cell changes for each, with position derived from newState.
102
- */
103
- function newCellChanges(
104
- prevState: NotebookState,
105
- newState: NotebookState,
106
- ): DocumentChange[] {
107
- const prevIds = new Set(prevState.cellIds.inOrderIds);
108
- const changes: DocumentChange[] = [];
109
- for (const id of newState.cellIds.inOrderIds) {
110
- if (!prevIds.has(id)) {
111
- const cell = getCell(id, newState);
112
- if (cell) {
113
- changes.push({
114
- type: "create-cell",
115
- cellId: cell.id,
116
- code: cell.code,
117
- name: cell.name,
118
- config: cell.config,
119
- ...anchorOf(cell.id, newState),
120
- });
121
- }
122
- }
123
- }
124
- return changes;
125
- }
126
-
127
- /**
128
- * Find cells that were removed between prevState and newState and return
129
- * delete-cell changes for each.
130
- */
131
- function deletedCellChanges(
132
- prevState: NotebookState,
133
- newState: NotebookState,
134
- ): DocumentChange[] {
135
- const newIds = new Set(newState.cellIds.inOrderIds);
136
- const changes: DocumentChange[] = [];
137
- for (const id of prevState.cellIds.inOrderIds) {
138
- if (!newIds.has(id)) {
139
- changes.push({ type: "delete-cell", cellId: id });
140
- }
141
- }
142
- return changes;
143
- }
144
-
145
- /**
146
- * Produce set-config changes for cells whose column index changed between
147
- * prevState and newState, plus a reorder-cells change for the new ordering.
148
- */
149
- function columnChanges(
150
- prevState: NotebookState,
151
- newState: NotebookState,
152
- ): DocumentChange[] {
153
- const prevColumns = columnIndexMap(prevState);
154
- const newColumns = columnIndexMap(newState);
155
- const changes: DocumentChange[] = [];
156
-
157
- for (const [cellId, newCol] of newColumns) {
158
- const prevCol = prevColumns.get(cellId);
159
- if (prevCol !== newCol) {
160
- const cell = getCell(cellId, newState);
161
- changes.push({
162
- type: "set-config",
163
- cellId: cellId,
164
- column: newCol,
165
- disabled: cell?.config.disabled ?? false,
166
- hideCode: cell?.config.hide_code ?? false,
167
- expandOutput: cell?.config.expand_output ?? false,
168
- });
169
- }
170
- }
171
-
172
- changes.push({
173
- type: "reorder-cells",
174
- cellIds: newState.cellIds.inOrderIds,
175
- });
176
-
177
- return changes;
178
- }
179
-
180
- // ---------------------------------------------------------------------------
181
- // toDocumentChanges: action + state → changes
182
- // ---------------------------------------------------------------------------
183
-
184
- /**
185
- * Given a reducer action and the before/after notebook state, return the
186
- * document changes that represent the diff. Returns an empty array for
187
- * actions that don't affect document structure.
188
- */
189
- export function toDocumentChanges(
190
- prevState: NotebookState,
191
- newState: NotebookState,
192
- action: DispatchedActionOf<CellActions>,
193
- ): DocumentChange[] {
194
- switch (action.type) {
195
- // createNewCell → create-cell
196
- // Reads code, name, and config from the newly created cell in newState.
197
- // Position is derived from newState via anchorOf (after or before neighbor).
198
- case "createNewCell":
199
- return newCellChanges(prevState, newState);
200
-
201
- // deleteCell → delete-cell
202
- // Direct 1:1 mapping. Only the cellId is needed.
203
- case "deleteCell":
204
- return [{ type: "delete-cell", cellId: action.payload.cellId }];
205
-
206
- // moveCell/sendToTop/sendToBottom → move-cell
207
- // All three change a single cell's position. We derive the final
208
- // position from newState via anchorOf rather than interpreting the
209
- // action's before/direction payload.
210
- case "moveCell":
211
- case "sendToTop":
212
- case "sendToBottom": {
213
- const { cellId } = action.payload;
214
- return [
215
- {
216
- type: "move-cell",
217
- cellId: cellId,
218
- ...anchorOf(cellId, newState),
219
- },
220
- ];
221
- }
222
-
223
- // dropCellOverCell/dropCellOverColumn/moveCellToIndex/moveCellsRelativeTo → set-config + reorder-cells
224
- // Drag-and-drop reorders can move cells within or across columns.
225
- // We emit config changes for cells whose column changed, then
226
- // the full ordering.
227
- case "dropCellOverCell":
228
- case "dropCellOverColumn":
229
- case "moveCellToIndex":
230
- case "moveCellsRelativeTo":
231
- return columnChanges(prevState, newState);
232
-
233
- // updateCellCode → set-code
234
- // Reads the code from newState via getCell.
235
- case "updateCellCode": {
236
- const cell = getCell(action.payload.cellId, newState);
237
- if (!cell) {
238
- return [];
239
- }
240
- return [
241
- {
242
- type: "set-code",
243
- cellId: cell.id,
244
- code: cell.code,
245
- },
246
- ];
247
- }
248
-
249
- // updateCellName → set-name
250
- // Reads the name from newState via getCell.
251
- case "updateCellName": {
252
- const cell = getCell(action.payload.cellId, newState);
253
- if (!cell) {
254
- return [];
255
- }
256
- return [
257
- {
258
- type: "set-name",
259
- cellId: cell.id,
260
- name: cell.name,
261
- },
262
- ];
263
- }
264
-
265
- // updateCellConfig → set-config
266
- // SetConfig is full-replacement: emit the cell's complete config from
267
- // newState (which already merged the action's partial payload).
268
- case "updateCellConfig": {
269
- const { cellId } = action.payload;
270
- const cell = getCell(cellId, newState);
271
- if (!cell) {
272
- return [];
273
- }
274
- return [
275
- {
276
- type: "set-config",
277
- cellId: cellId,
278
- column: cell.config.column ?? null,
279
- disabled: cell.config.disabled ?? false,
280
- hideCode: cell.config.hide_code ?? false,
281
- expandOutput: cell.config.expand_output ?? false,
282
- },
283
- ];
284
- }
285
-
286
- // Column structure changes → set-config + reorder-cells
287
- // All of these change column layout. We emit config changes for
288
- // cells whose column index changed, then the full ordering.
289
- case "dropOverNewColumn":
290
- case "moveColumn":
291
- case "addColumnBreakpoint":
292
- case "deleteColumn":
293
- case "mergeAllColumns":
294
- case "compactColumns":
295
- return columnChanges(prevState, newState);
296
-
297
- // addColumn creates a new column with a new empty cell.
298
- // Emits create-cell for the new cell plus column layout changes.
299
- case "addColumn":
300
- return [
301
- ...newCellChanges(prevState, newState),
302
- ...columnChanges(prevState, newState),
303
- ];
304
-
305
- // undoDeleteCell restores a deleted cell from history.
306
- case "undoDeleteCell": {
307
- const changes = newCellChanges(prevState, newState);
308
- const colChanges = columnChanges(prevState, newState);
309
- // Undo-cut has no new cells — always emit reorder to sync the move.
310
- if (changes.length === 0) {
311
- return colChanges;
312
- }
313
- // Only include column changes if layout actually changed
314
- // (colChanges always has at least a reorder-cells change)
315
- return colChanges.length > 1 ? [...changes, ...colChanges] : changes;
316
- }
317
-
318
- // splitCell: original cell gets truncated code, new cell gets remainder.
319
- case "splitCell": {
320
- const { cellId } = action.payload;
321
- const cell = getCell(cellId, newState);
322
- if (!cell) {
323
- return [];
324
- }
325
- return [
326
- { type: "set-code", cellId, code: cell.code },
327
- ...newCellChanges(prevState, newState),
328
- ];
329
- }
330
-
331
- // undoSplitCell: merge next cell back into current, delete the next cell.
332
- case "undoSplitCell": {
333
- const { cellId } = action.payload;
334
- const cell = getCell(cellId, newState);
335
- if (!cell) {
336
- return [];
337
- }
338
- return [
339
- { type: "set-code", cellId, code: cell.code },
340
- ...deletedCellChanges(prevState, newState),
341
- ];
342
- }
343
-
344
- // moveToNextCell: may create a new cell at boundary.
345
- case "moveToNextCell":
346
- return newCellChanges(prevState, newState);
347
-
348
- // addSetupCellIfDoesntExist: creates setup cell if missing.
349
- case "addSetupCellIfDoesntExist":
350
- return newCellChanges(prevState, newState);
351
-
352
- // UI-only actions — no document changes.
353
- case "focusCell":
354
- case "focusTopCell":
355
- case "focusBottomCell":
356
- case "scrollToTarget":
357
- case "showCellIfHidden":
358
- case "markTouched":
359
- case "markUntouched":
360
- return [];
361
-
362
- // Kernel/runtime state — never produces document changes.
363
- case "prepareForRun":
364
- case "handleCellMessage":
365
- case "setCellIds":
366
- case "rebuildCellColumns":
367
- case "setCellCodes":
368
- case "setCells":
369
- case "setStdinResponse":
370
- case "clearSerializedEditorState":
371
- case "clearCellOutput":
372
- case "clearCellConsoleOutput":
373
- case "clearAllCellOutputs":
374
- case "clearLogs":
375
- case "addLogs":
376
- return [];
377
-
378
- // Editor UI state — no document changes.
379
- case "foldAll":
380
- case "unfoldAll":
381
- case "collapseCell":
382
- case "expandCell":
383
- case "collapseAllCells":
384
- case "expandAllCells":
385
- return [];
386
-
387
- default:
388
- assertNever(action);
389
- }
390
- }
391
-
392
- // ---------------------------------------------------------------------------
393
- // fromDocumentChanges: changes → actions
394
- // ---------------------------------------------------------------------------
395
-
396
- /**
397
- * Find cell IDs that are both created and deleted in a set of changes.
398
- * These cancel out and should be skipped.
399
- */
400
- export function cancelledCellIds(changes: TransactionChange[]): Set<string> {
401
- const created = new Set<string>();
402
- const deleted = new Set<string>();
403
- for (const change of changes) {
404
- if (change.type === "create-cell") {
405
- created.add(change.cellId);
406
- } else if (change.type === "delete-cell") {
407
- deleted.add(change.cellId);
408
- }
409
- }
410
- return created.intersection(deleted);
411
- }
412
-
413
- /**
414
- * Given document changes (from the server) and the current cell ordering,
415
- * return the reducer actions that apply them to frontend state.
416
- */
417
- export function fromDocumentChanges(
418
- changes: TransactionChange[],
419
- getCurrentCellIds: () => CellId[],
420
- ): CellAction[] {
421
- const actions: CellAction[] = [];
422
-
423
- for (const change of changes) {
424
- switch (change.type) {
425
- // create-cell → createNewCell + updateCellName + updateCellConfig
426
- // Translates the change's before/after anchor into createNewCell's
427
- // cellId+before pair. The change carries code, name, and a full CellConfig.
428
- // createNewCell only accepts hideCode, so name and remaining config
429
- // (disabled, column) are applied as separate follow-up actions.
430
- case "create-cell": {
431
- let cellId: CellId | "__end__" = "__end__";
432
- let before = false;
433
- if (change.after) {
434
- cellId = change.after;
435
- before = false;
436
- } else if (change.before) {
437
- cellId = change.before;
438
- before = true;
439
- }
440
- actions.push({
441
- type: "createNewCell",
442
- payload: {
443
- cellId,
444
- before,
445
- code: change.code,
446
- newCellId: change.cellId,
447
- autoFocus: false,
448
- hideCode: change.config?.hide_code ?? false,
449
- },
450
- });
451
- if (change.name) {
452
- actions.push({
453
- type: "updateCellName",
454
- payload: { cellId: change.cellId, name: change.name },
455
- });
456
- }
457
- if (
458
- change.config?.disabled != null ||
459
- change.config?.column != null ||
460
- change.config?.expand_output != null
461
- ) {
462
- actions.push({
463
- type: "updateCellConfig",
464
- payload: {
465
- cellId: change.cellId,
466
- config: {
467
- ...(change.config.disabled != null && {
468
- disabled: change.config.disabled,
469
- }),
470
- ...(change.config.column != null && {
471
- column: change.config.column,
472
- }),
473
- ...(change.config.expand_output != null && {
474
- expand_output: change.config.expand_output,
475
- }),
476
- },
477
- },
478
- });
479
- }
480
- break;
481
- }
482
-
483
- // delete-cell → deleteCell
484
- // Direct 1:1 mapping.
485
- case "delete-cell":
486
- actions.push({
487
- type: "deleteCell",
488
- payload: { cellId: change.cellId },
489
- });
490
- break;
491
-
492
- // move-cell → setCellIds
493
- // Reconstructs the full ordering by splicing the cell out and
494
- // reinserting it relative to the before/after anchor. Falls back
495
- // to appending (after) or prepending (before) if the anchor is
496
- // missing. No-ops if the cell itself doesn't exist.
497
- case "move-cell": {
498
- const ids = [...getCurrentCellIds()];
499
- const cellId = change.cellId;
500
- const idx = ids.indexOf(cellId);
501
- if (idx < 0) {
502
- break;
503
- }
504
- ids.splice(idx, 1);
505
- if (change.after) {
506
- const afterIdx = ids.indexOf(change.after);
507
- if (afterIdx >= 0) {
508
- ids.splice(afterIdx + 1, 0, cellId);
509
- } else {
510
- ids.push(cellId);
511
- }
512
- } else if (change.before) {
513
- const beforeIdx = ids.indexOf(change.before);
514
- if (beforeIdx >= 0) {
515
- ids.splice(beforeIdx, 0, cellId);
516
- } else {
517
- ids.unshift(cellId);
518
- }
519
- } else {
520
- ids.push(cellId);
521
- }
522
- actions.push({
523
- type: "setCellIds",
524
- payload: { cellIds: ids },
525
- });
526
- break;
527
- }
528
-
529
- // reorder-cells → setCellIds
530
- // Replaces the full cell ordering. Used for drag-and-drop and
531
- // bulk reorders where expressing individual moves is impractical.
532
- case "reorder-cells":
533
- actions.push({
534
- type: "setCellIds",
535
- payload: { cellIds: change.cellIds },
536
- });
537
- break;
538
-
539
- // set-code → setCellCodes
540
- // Marks the code as stale (codeIsStale: true) since it came from
541
- // an external source and hasn't been executed yet.
542
- case "set-code":
543
- actions.push({
544
- type: "setCellCodes",
545
- payload: {
546
- ids: [change.cellId],
547
- codes: [change.code],
548
- codeIsStale: true,
549
- },
550
- });
551
- break;
552
-
553
- // set-name → updateCellName
554
- // Direct 1:1 mapping.
555
- case "set-name":
556
- actions.push({
557
- type: "updateCellName",
558
- payload: { cellId: change.cellId, name: change.name },
559
- });
560
- break;
561
-
562
- // set-config → updateCellConfig
563
- case "set-config":
564
- actions.push({
565
- type: "updateCellConfig",
566
- payload: {
567
- cellId: change.cellId,
568
- config: {
569
- column: change.column,
570
- disabled: change.disabled,
571
- hide_code: change.hideCode,
572
- expand_output: change.expandOutput,
573
- },
574
- },
575
- });
576
- break;
577
- }
578
- }
579
-
580
- return actions;
581
- }
582
-
583
- // ---------------------------------------------------------------------------
584
- // Coalescing: reduce a buffered change sequence to its net effect
585
- // ---------------------------------------------------------------------------
586
-
587
- const COLLAPSIBLE_TYPES = new Set(["set-code", "set-name", "set-config"]);
588
- const DROPPABLE_ON_DELETE = new Set([
589
- "set-code",
590
- "set-name",
591
- "set-config",
592
- "move-cell",
593
- ]);
594
-
595
- /**
596
- * Reduce a buffered sequence of changes to an equivalent batch that reflects
597
- * net effect rather than edit history. The server applies a transaction
598
- * atomically and rejects internally contradictory batches (e.g. updating a
599
- * cell that is also deleted in the same transaction), so a debounced sequence
600
- * of edits must be reconciled before it is sent.
601
- *
602
- * Two reductions, both order-preserving:
603
- * - For any cell deleted in the batch, drop its property/move changes. The
604
- * `create-cell` and `delete-cell` are kept so anchors referencing the cell
605
- * stay resolvable on the server; create+delete applies to a net no-op.
606
- * - Collapse repeated `set-code`/`set-name`/`set-config` for a surviving cell
607
- * to the last occurrence.
608
- */
609
- export function coalesceChanges(changes: DocumentChange[]): DocumentChange[] {
610
- const deletedIds = new Set<CellId>();
611
- for (const change of changes) {
612
- if (change.type === "delete-cell") {
613
- deletedIds.add(change.cellId);
614
- }
615
- }
616
-
617
- const withoutEditsToDeletedCells = changes.filter(
618
- (change) =>
619
- !(
620
- DROPPABLE_ON_DELETE.has(change.type) &&
621
- "cellId" in change &&
622
- deletedIds.has(change.cellId)
623
- ),
624
- );
625
-
626
- const lastIndexByKey = new Map<string, number>();
627
- withoutEditsToDeletedCells.forEach((change, index) => {
628
- if (COLLAPSIBLE_TYPES.has(change.type) && "cellId" in change) {
629
- lastIndexByKey.set(`${change.type}:${change.cellId}`, index);
630
- }
631
- });
632
-
633
- return withoutEditsToDeletedCells.filter((change, index) => {
634
- if (COLLAPSIBLE_TYPES.has(change.type) && "cellId" in change) {
635
- return lastIndexByKey.get(`${change.type}:${change.cellId}`) === index;
636
- }
637
- return true;
638
- });
639
- }
640
-
641
- // ---------------------------------------------------------------------------
642
- // Middleware: debounced change dispatch to the server
643
- // ---------------------------------------------------------------------------
644
-
645
- let pendingChanges: DocumentChange[] = [];
646
- let stagedTransactions: DocumentChange[][] = [];
647
- let transactionQueue: Promise<void> = Promise.resolve();
648
- let transactionGeneration = 0;
649
- let activeDocumentSave: Deferred<void> | null = null;
650
-
651
- type TransactionSyncState =
652
- | { status: "synchronized" }
653
- | { status: "failed"; error: unknown };
654
-
655
- interface DocumentResync {
656
- failure: Extract<TransactionSyncState, { status: "failed" }>;
657
- includedChanges: DocumentChange[];
658
- includedTransactions: DocumentChange[][];
659
- }
660
-
661
- let transactionSyncState: TransactionSyncState = { status: "synchronized" };
662
-
663
- function stagePendingTransaction(): void {
664
- if (transactionSyncState.status === "failed") {
665
- return;
666
- }
667
- const changes = coalesceChanges(pendingChanges);
668
- pendingChanges = [];
669
- if (changes.length > 0) {
670
- stagedTransactions.push(changes);
671
- }
672
- }
673
-
674
- async function sendStagedTransactions(generation: number): Promise<void> {
675
- if (generation !== transactionGeneration) {
676
- return;
677
- }
678
- if (transactionSyncState.status === "failed") {
679
- throw transactionSyncState.error;
680
- }
681
-
682
- while (stagedTransactions.length > 0) {
683
- const changes = stagedTransactions[0];
684
-
685
- try {
686
- await getRequestClient().sendDocumentTransaction({ changes });
687
- } catch (error) {
688
- if (generation !== transactionGeneration) {
689
- return;
690
- }
691
- // A transport failure is ambiguous: the server may have applied the
692
- // transaction before the response was lost. Keep the failure sticky so
693
- // an export cannot claim synchronization without a fresh document.
694
- transactionSyncState = { status: "failed", error };
695
- stagedTransactions = stagedTransactions.slice(1);
696
- throw error;
697
- }
698
- if (generation !== transactionGeneration) {
699
- return;
700
- }
701
- stagedTransactions.shift();
702
- }
703
- }
704
-
705
- function queuePendingTransactions(): Promise<void> {
706
- const generation = transactionGeneration;
707
- const saveBarrier = activeDocumentSave?.promise ?? Promise.resolve();
708
- const queued = Promise.all([
709
- transactionQueue.catch(() => undefined),
710
- saveBarrier,
711
- ]).then(() => sendStagedTransactions(generation));
712
- transactionQueue = queued;
713
- return queued;
714
- }
715
-
716
- const flushChanges = debounce(() => {
717
- stagePendingTransaction();
718
- void queuePendingTransactions().catch(() => undefined);
719
- }, 400);
720
-
721
- export async function flushDocumentChanges(): Promise<void> {
722
- if (transactionSyncState.status === "failed") {
723
- throw transactionSyncState.error;
724
- }
725
- flushChanges.cancel();
726
- stagePendingTransaction();
727
- let awaitedQueue = queuePendingTransactions();
728
- while (true) {
729
- await awaitedQueue;
730
- flushChanges.cancel();
731
- stagePendingTransaction();
732
- if (
733
- pendingChanges.length === 0 &&
734
- stagedTransactions.length === 0 &&
735
- transactionQueue === awaitedQueue
736
- ) {
737
- return;
738
- }
739
- awaitedQueue =
740
- transactionQueue === awaitedQueue
741
- ? queuePendingTransactions()
742
- : transactionQueue;
743
- }
744
- }
745
-
746
- export function beginDocumentResync(): DocumentResync | null {
747
- if (transactionSyncState.status !== "failed") {
748
- return null;
749
- }
750
- flushChanges.cancel();
751
- const includedChanges = pendingChanges;
752
- const includedTransactions = stagedTransactions;
753
- pendingChanges = [];
754
- stagedTransactions = [];
755
- return {
756
- failure: transactionSyncState,
757
- includedChanges,
758
- includedTransactions,
759
- };
760
- }
761
-
762
- export function abortDocumentResync(resync: DocumentResync | null): void {
763
- if (resync === null || transactionSyncState !== resync.failure) {
764
- return;
765
- }
766
- pendingChanges = [...resync.includedChanges, ...pendingChanges];
767
- stagedTransactions = [...resync.includedTransactions, ...stagedTransactions];
768
- }
769
-
770
- export async function completeDocumentResync(
771
- resync: DocumentResync | null,
772
- ): Promise<void> {
773
- if (resync === null) {
774
- return;
775
- }
776
- await transactionQueue.catch(() => undefined);
777
- if (transactionSyncState !== resync.failure) {
778
- return;
779
- }
780
- transactionSyncState = { status: "synchronized" };
781
- transactionQueue = Promise.resolve();
782
- if (pendingChanges.length > 0) {
783
- flushChanges();
784
- }
785
- }
786
-
787
- function releaseDocumentSave(barrier: Deferred<void>): void {
788
- if (activeDocumentSave === barrier) {
789
- activeDocumentSave = null;
790
- }
791
- barrier.resolve();
792
- }
793
-
794
- /**
795
- * Runs a full save after earlier document transactions and holds later
796
- * transactions until the save settles. A failed transaction makes the save
797
- * the authoritative document resync boundary.
798
- */
799
- export async function withDocumentSave<T>(save: () => Promise<T>): Promise<T> {
800
- let resync: DocumentResync | null = null;
801
- try {
802
- await flushDocumentChanges();
803
- } catch (error) {
804
- resync = beginDocumentResync();
805
- if (resync === null) {
806
- throw error;
807
- }
808
- }
809
-
810
- const barrier = new Deferred<void>();
811
- activeDocumentSave = barrier;
812
- try {
813
- const result = await save();
814
- releaseDocumentSave(barrier);
815
- await completeDocumentResync(resync);
816
- return result;
817
- } catch (error) {
818
- abortDocumentResync(resync);
819
- releaseDocumentSave(barrier);
820
- throw error;
821
- }
822
- }
823
-
824
- function isScratchChange(change: DocumentChange): boolean {
825
- if ("cellId" in change && change.cellId === SCRATCH_CELL_ID) {
826
- return true;
827
- }
828
- return false;
829
- }
830
-
831
- function enqueue(change: DocumentChange) {
832
- if (store.get(kioskModeAtom)) {
833
- return;
834
- }
835
- // The scratchpad cell is local-only — don't sync it to the document.
836
- if (isScratchChange(change)) {
837
- return;
838
- }
839
- pendingChanges.push(change);
840
- if (transactionSyncState.status === "synchronized") {
841
- flushChanges();
842
- }
843
- }
844
-
845
- /**
846
- * Middleware for the notebook reducer. Converts actions to document changes
847
- * via toDocumentChanges and enqueues them for debounced dispatch.
848
- */
849
- export function documentTransactionMiddleware(
850
- prevState: NotebookState,
851
- newState: NotebookState,
852
- action: CellAction,
853
- ): void {
854
- for (const change of toDocumentChanges(prevState, newState, action)) {
855
- enqueue(change);
856
- }
857
- }
858
-
859
- // ---------------------------------------------------------------------------
860
- // Apply: dispatch incoming changes as reducer actions
861
- // ---------------------------------------------------------------------------
862
-
863
- /**
864
- * Apply document transaction changes to the frontend cell state.
865
- *
866
- * Each change is applied immediately and in order so that subsequent changes
867
- * see the state produced by earlier changes (e.g. move-cell after create-cell).
868
- */
869
- export function applyTransactionChanges(
870
- changes: TransactionChange[],
871
- actions: CellActions,
872
- getCurrentCellIds: () => CellId[],
873
- ): void {
874
- const cancelled = cancelledCellIds(changes);
875
-
876
- // Process set-config changes after everything else. The tree must be fully
877
- // restructured (create-cell, delete-cell, reorder-cells, move-cell) before
878
- // we start applying column metadata, since the follow-up rebuildCellColumns
879
- // step interprets each cell's config.column against the *final* flat order.
880
- // Sorting is stable within each group.
881
- const sortedChanges: TransactionChange[] = [
882
- ...changes.filter((c) => c.type !== "set-config"),
883
- ...changes.filter((c) => c.type === "set-config"),
884
- ];
885
-
886
- // Track whether any change updated a cell's column, and remember the final
887
- // flat order produced by a reorder-cells change (if any). After all changes
888
- // are applied, these are used to rebuild the MultiColumn tree so that cells
889
- // physically move to the column their metadata says they belong in.
890
- let hasColumnChange = false;
891
- let reorderOrder: CellId[] | null = null;
892
-
893
- for (const change of sortedChanges) {
894
- if (
895
- cancelled.size > 0 &&
896
- "cellId" in change &&
897
- cancelled.has(change.cellId)
898
- ) {
899
- continue;
900
- }
901
- if (change.type === "set-config") {
902
- hasColumnChange = true;
903
- }
904
- if (change.type === "create-cell" && change.config?.column != null) {
905
- hasColumnChange = true;
906
- }
907
- if (change.type === "reorder-cells") {
908
- reorderOrder = change.cellIds as CellId[];
909
- }
910
- for (const action of fromDocumentChanges([change], getCurrentCellIds)) {
911
- // @ts-expect-error - TypeScript is not smart enough to know we have correctly mapped type -> payload
912
- actions[action.type](action.payload);
913
- }
914
- }
915
-
916
- if (hasColumnChange) {
917
- actions.rebuildCellColumns({
918
- cellIds: reorderOrder ?? getCurrentCellIds(),
919
- });
920
- }
921
- }
922
-
923
- // ---------------------------------------------------------------------------
924
- // Test helpers
925
- // ---------------------------------------------------------------------------
926
-
927
- export const exportedForTesting = {
928
- cancelPendingChanges: () => {
929
- flushChanges.cancel();
930
- activeDocumentSave?.resolve();
931
- activeDocumentSave = null;
932
- transactionGeneration += 1;
933
- pendingChanges = [];
934
- stagedTransactions = [];
935
- transactionSyncState = { status: "synchronized" };
936
- transactionQueue = Promise.resolve();
937
- },
938
- drainChanges: (): DocumentChange[] => {
939
- flushChanges.cancel();
940
- const drained = pendingChanges;
941
- pendingChanges = [];
942
- return drained;
943
- },
944
- };