@marimo-team/islands 0.25.3-dev20 → 0.25.3-dev201

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 (688) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CNMliVzw.js → ConnectedDataExplorerComponent-BsWiIPFk.js} +22 -20
  2. package/dist/{ErrorBoundary-DAPIRYqd.js → ErrorBoundary-JYAf40sB.js} +19 -19
  3. package/dist/{abnfDiagram-VCTEODGH-D-Ez91gV.js → abnfDiagram-VCTEODGH-I2x4Yu25.js} +2 -2
  4. package/dist/any-language-editor-BVFHDDQ3.js +75 -0
  5. package/dist/{architectureDiagram-5GKGNRK7-CTpcNtO8.js → architectureDiagram-5GKGNRK7-1bSQMKzK.js} +1 -1
  6. package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
  7. package/dist/assets/__vite-browser-external-BCJsx8QS.js +1 -0
  8. package/dist/assets/worker-DodjWT_Z.js +113 -0
  9. package/dist/{button-CvjkwdSk.js → button-BQRdqQi1.js} +199 -192
  10. package/dist/{capabilities-CQ5IjhzL.js → capabilities-C2QUNRXi.js} +2 -2
  11. package/dist/{chat-ui-DaHynk8g.js → chat-ui-DXDoSuS4.js} +370 -369
  12. package/dist/{check-EDwSwP89.js → check-C9Mp9eCK.js} +1 -1
  13. package/dist/{chunk-IMKFNOWR-DGxi-zeo.js → chunk-IMKFNOWR-fsCGAJ9G.js} +1 -1
  14. package/dist/{chunk-SHT3W25Y-CV9J3rAB.js → chunk-SHT3W25Y-D2STW4hj.js} +1 -1
  15. package/dist/{chunk-SVP7TREG-BL-9Fqgg.js → chunk-SVP7TREG-CiY7cQG-.js} +1 -1
  16. package/dist/{chunk-TICWLB2K-Cu_XMjDM.js → chunk-TICWLB2K-C_t5RBp9.js} +1 -1
  17. package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
  18. package/dist/{classDiagram-ZZMXUADV-BXXV13Hq.js → classDiagram-ZZMXUADV-B2JvZAP4.js} +2 -2
  19. package/dist/{classDiagram-v2-VYDZK3BY-B7FXJ1Cp.js → classDiagram-v2-VYDZK3BY-L8VsZG5A.js} +2 -2
  20. package/dist/code-visibility-BKyYMfr_.js +134 -0
  21. package/dist/{common-DsUPhkD6.js → common-BCY25vum.js} +6040 -5865
  22. package/dist/{copy-icon-Ft7t9bqz.js → copy-icon-De584pZ4.js} +3 -3
  23. package/dist/{cynefinDiagram-5FMLGOSQ-CH96rwba.js → cynefinDiagram-5FMLGOSQ-DdllC264.js} +1 -1
  24. package/dist/{dagre-GXQ25YYZ-BD3PmpFY.js → dagre-GXQ25YYZ-BaWHw4_f.js} +1 -1
  25. package/dist/{data-grid-overlay-editor-D7UuVsgB.js → data-grid-overlay-editor-gQmJxgU-.js} +5 -5
  26. package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
  27. package/dist/{diagram-S7CK7UJ4-BsSJJldB.js → diagram-S7CK7UJ4-pFt-tUDe.js} +1 -1
  28. package/dist/{diagram-UQ7AKVKN-muQtNZc4.js → diagram-UQ7AKVKN-DqGJiBp4.js} +1 -1
  29. package/dist/{diagram-VX7I27RA-CdhuZAqR.js → diagram-VX7I27RA-Dr-yzMjf.js} +1 -1
  30. package/dist/{diagram-Z3DM3KII-BD8mXjOj.js → diagram-Z3DM3KII-8xzJzv-w.js} +1 -1
  31. package/dist/{dialog-CEBFZNyc.js → dialog-DVRfQuhD.js} +25 -25
  32. package/dist/{dist-F8Ep36rk.js → dist-B1M0bGO3.js} +1 -1
  33. package/dist/{dist-D6d86eNJ.js → dist-BA13RJj5.js} +1 -1
  34. package/dist/{dist-Bvs24R_E.js → dist-BJtmSgcE.js} +48 -48
  35. package/dist/{dist-CN_BeG2I.js → dist-Ba2VIn1K.js} +53 -53
  36. package/dist/{dist-PXYI_yuP.js → dist-Bj4bmwUm.js} +12 -12
  37. package/dist/{dist-DoE4XJBC.js → dist-BmS-ZGjl.js} +8626 -8626
  38. package/dist/{dist-BorMD-uX.js → dist-Bzogh7CW.js} +87 -87
  39. package/dist/{dist-CN8zI-XC.js → dist-CThPVKaP.js} +1385 -1382
  40. package/dist/{dist-DiDibOYr.js → dist-CTi5FTiV.js} +87 -87
  41. package/dist/{dist-diIx5qJW.js → dist-Ck_C32ye.js} +2 -2
  42. package/dist/{dist-BLfKmR-l.js → dist-D1fnFp1J.js} +1 -1
  43. package/dist/{dist-OR1OnN-y.js → dist-D3x9__Fu.js} +46 -46
  44. package/dist/{dist-BMQf5zIS.js → dist-D7mrh5sO.js} +36 -36
  45. package/dist/{dist-CSJ0MDRw.js → dist-D9Q3xjiP.js} +1 -1
  46. package/dist/{dist-BuaRHxOc.js → dist-DP60Ubh8.js} +2 -2
  47. package/dist/{dist-CSbh1PNP.js → dist-DTv9KkpW.js} +12 -12
  48. package/dist/{dist-D-wwqlzJ.js → dist-DVVwOfrD.js} +109 -109
  49. package/dist/{dist-C8fAKSH1.js → dist-DYXM73-k.js} +36 -36
  50. package/dist/{dist-DBtSl3sf.js → dist-DjeybPOb.js} +1 -1
  51. package/dist/{dist-CrSP_H1M.js → dist-DtGn9N4h.js} +197 -197
  52. package/dist/{dist-CLdpGQVr.js → dist-KN80qWCP.js} +2 -2
  53. package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
  54. package/dist/{dist-Cg7gzw-a.js → dist-O0qFpEJh.js} +56 -56
  55. package/dist/{dist-CkTTIdBe.js → dist-OUle2RT7.js} +207 -207
  56. package/dist/{dist-BK4Oj99o.js → dist-T5rh6JvL.js} +1 -1
  57. package/dist/{dropdown-menu-CP_qCYHC.js → dropdown-menu-NlnsmNA6.js} +1481 -1433
  58. package/dist/{ebnfDiagram-PWID7BFC-BIN1sweE.js → ebnfDiagram-PWID7BFC-Br04Wy-E.js} +2 -2
  59. package/dist/{erDiagram-RLTQ6QDP-Ctp5cfoN.js → erDiagram-RLTQ6QDP-D5-XVgvv.js} +1 -1
  60. package/dist/{error-banner-D-WCIiMt.js → error-banner-DxJ3s8YO.js} +86 -86
  61. package/dist/{error-entries-Bv6bZPF3.js → error-entries-C2Ux0Fjt.js} +8404 -9095
  62. package/dist/{esm-D2gTsXEV.js → esm-Bbw_Njjx.js} +575 -575
  63. package/dist/{esm-AMFssoNp.js → esm-mDQNEFe_.js} +354 -354
  64. package/dist/feedback-button-BKgw9MHY.js +374 -0
  65. package/dist/{flowDiagram-HODETNUW-3EfLrlFb.js → flowDiagram-HODETNUW-CVl2kREF.js} +2 -2
  66. package/dist/{formats-27CW_UP4.js → formats-BCYthwyc.js} +3 -3
  67. package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
  68. package/dist/{glide-data-editor-KvS90MGh.js → glide-data-editor-CzS51bb2.js} +370 -368
  69. package/dist/{glide-utils-DJyqh0EM.js → glide-utils-D98laidb.js} +16 -16
  70. package/dist/{globals-yruoELTW.js → globals-DQ4tv_a-.js} +3 -3
  71. package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
  72. package/dist/{html-to-image-Bf8QMGi4.js → html-to-image-CkH7vdBZ.js} +477 -380
  73. package/dist/{infoDiagram-27XIBGKW-DipQoHxl.js → infoDiagram-27XIBGKW-BJ4vNcZE.js} +1 -1
  74. package/dist/{ishikawaDiagram-5VMMS53U-DgFMjSGz.js → ishikawaDiagram-5VMMS53U-B_Jy1Dsm.js} +1 -1
  75. package/dist/{kanban-definition-UXKFOSKX-w1ACVjgl.js → kanban-definition-UXKFOSKX-C6MkS9vw.js} +1 -1
  76. package/dist/{label-BDKF3Afc.js → label-Qvw1E97W.js} +3 -3
  77. package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
  78. package/dist/{loader-BQOfjTIJ.js → loader-DOVB0Syl.js} +12 -12
  79. package/dist/main.js +9706 -7709
  80. package/dist/{mermaid-CHo49Yv-.js → mermaid-Bh918qrq.js} +52 -52
  81. package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
  82. package/dist/{mindmap-definition-YA3MSWOX-CrT0KSfX.js → mindmap-definition-YA3MSWOX-BP3ZTuir.js} +1 -1
  83. package/dist/{number-overlay-editor-R2i0FdxV.js → number-overlay-editor-B3ZE3-6d.js} +3 -3
  84. package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
  85. package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
  86. package/dist/{pegDiagram-XKGWAZYB-BqvywNJA.js → pegDiagram-XKGWAZYB-nNGOQtnt.js} +2 -2
  87. package/dist/{pieDiagram-E7YTZNPT-BfxJ_XCc.js → pieDiagram-E7YTZNPT-CpRz5BZz.js} +1 -1
  88. package/dist/precisionRound-DhAzeRcm.js +49 -0
  89. package/dist/{process-output-BZg56CCb.js → process-output-OujAtFW4.js} +5 -5
  90. package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
  91. package/dist/{railroadDiagram-O6MQD6OU-8vFLVTPu.js → railroadDiagram-O6MQD6OU-BqOEN4I0.js} +2 -2
  92. package/dist/{react-vega-BED0DjiB.js → react-vega-C4T9Rb_w.js} +12284 -12270
  93. package/dist/{requirementDiagram-BXWQKSXE-a_MxGvxe.js → requirementDiagram-BXWQKSXE-CEfg6vu9.js} +1 -1
  94. package/dist/{reveal-component-C42-YBfQ.js → reveal-component-DXa9FXf6.js} +733 -710
  95. package/dist/{select-BButFi-d.js → select-2KOiReNY.js} +536 -457
  96. package/dist/{sequenceDiagram-WJ2MYXX4-CXFMnxGh.js → sequenceDiagram-WJ2MYXX4-IOmpQcOi.js} +1 -1
  97. package/dist/{spec-BwarBpUJ.js → spec-Dkp64vVQ.js} +41 -11
  98. package/dist/{stateDiagram-D77RDMKH-DQeA_CwI.js → stateDiagram-D77RDMKH-tgU-EY9_.js} +2 -2
  99. package/dist/{stateDiagram-v2-MP3YSRHH-BxxQucm1.js → stateDiagram-v2-MP3YSRHH-BofhG6q1.js} +2 -2
  100. package/dist/style.css +1 -1
  101. package/dist/{swimlanes-42K2YHIH-Do6L-cYg.js → swimlanes-42K2YHIH-DW4vWDBd.js} +1 -1
  102. package/dist/{swimlanesDiagram-VR7AAH4N-DUzPvSVU.js → swimlanesDiagram-VR7AAH4N-BJcrqUJr.js} +2 -2
  103. package/dist/{swiper-component-DKntyn8p.js → swiper-component-BVfnhbnt.js} +2 -2
  104. package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
  105. package/dist/{timeline-definition-24CTP7MA-D3c46WM5.js → timeline-definition-24CTP7MA-D_QU3NGs.js} +1 -1
  106. package/dist/{toDate-UtiwmnH2.js → toDate-BNDEXbfV.js} +44 -43
  107. package/dist/{toast-B9UMEi8u.js → toast-B5t9o6s_.js} +219 -201
  108. package/dist/{tooltip-BO1REbqs.js → tooltip-s4zZxwKe.js} +325 -301
  109. package/dist/{use-restore-focus-BEM7sFWl.js → use-restore-focus-BgDTd2tc.js} +1482 -1433
  110. package/dist/{useAsyncData-Deh5kszT.js → useAsyncData-ASDni9vH.js} +15 -14
  111. package/dist/{useDateFormatter-D8XruNGG.js → useDateFormatter-D3Tkfzej.js} +2 -2
  112. package/dist/{useDeepCompareMemoize-DXwzRINI.js → useDeepCompareMemoize-B1Ogyf53.js} +1 -1
  113. package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-6a_yDNXp.js} +1 -1
  114. package/dist/{useLifecycle-j7D9uD1o.js → useLifecycle-Bfpa2m7k.js} +28 -25
  115. package/dist/{useTheme-CRnjkku0.js → useTheme-5TwyOh3B.js} +522 -314
  116. package/dist/{vega-component-BeF9dfyO.js → vega-component-BHS9UOtC.js} +158 -158
  117. package/dist/{vega-embed-container-BNHE18G9.js → vega-embed-container--LYZqguO.js} +2 -2
  118. package/dist/{vega-loader.browser-DNST6uVf.js → vega-loader.browser-B9Pz0EGP.js} +298 -507
  119. package/dist/{vennDiagram-4TSXK5OY-BSZD8JcZ.js → vennDiagram-4TSXK5OY-YFYsNIAh.js} +1 -1
  120. package/dist/{wardleyDiagram-VM6X3IG4-48cUWkfA.js → wardleyDiagram-VM6X3IG4-i_n8mAWC.js} +1 -1
  121. package/dist/{xychartDiagram-S5SC5T6Z-CswYgYeu.js → xychartDiagram-S5SC5T6Z-BYGN95wW.js} +2 -2
  122. package/package.json +16 -16
  123. package/src/__mocks__/document.tsx +63 -0
  124. package/src/__mocks__/notebook.ts +3 -4
  125. package/src/__mocks__/partial.ts +26 -0
  126. package/src/__mocks__/requests.ts +0 -3
  127. package/src/__tests__/main.test.tsx +24 -1
  128. package/src/__tests__/module-entry.test.ts +44 -0
  129. package/src/__tests__/mount.test.ts +1 -21
  130. package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
  131. package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
  132. package/src/components/ai/ai-model-dropdown.tsx +11 -6
  133. package/src/components/app-config/ai-config.tsx +7 -2
  134. package/src/components/app-config/app-config-form.tsx +5 -9
  135. package/src/components/app-config/user-config-form.tsx +35 -0
  136. package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
  137. package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
  138. package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
  139. package/src/components/chat/acp/__tests__/state.test.ts +2 -2
  140. package/src/components/chat/acp/blocks.tsx +3 -2
  141. package/src/components/chat/acp/session-tabs.tsx +8 -3
  142. package/src/components/chat/chat-components.tsx +2 -0
  143. package/src/components/chat/chat-panel.tsx +20 -101
  144. package/src/components/chat/chat-utils.ts +4 -8
  145. package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
  146. package/src/components/chat/notebook-access-selector.tsx +100 -0
  147. package/src/components/data-table/TableBottomBar.tsx +4 -1
  148. package/src/components/data-table/TableTopBar.tsx +2 -0
  149. package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
  150. package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
  151. package/src/components/data-table/__tests__/columns.test.tsx +105 -0
  152. package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
  153. package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
  154. package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
  155. package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
  156. package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
  157. package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
  158. package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
  159. package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
  160. package/src/components/data-table/cell-selection/feature.ts +2 -2
  161. package/src/components/data-table/cell-selection/types.ts +2 -2
  162. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
  163. package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
  164. package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
  165. package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
  166. package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
  167. package/src/components/data-table/charts/charts.tsx +40 -30
  168. package/src/components/data-table/charts/storage.ts +16 -5
  169. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  170. package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
  171. package/src/components/data-table/column-summary/column-summary.tsx +2 -4
  172. package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
  173. package/src/components/data-table/columns.tsx +45 -46
  174. package/src/components/data-table/context-menu.tsx +36 -20
  175. package/src/components/data-table/data-table.tsx +17 -1
  176. package/src/components/data-table/date-popover.tsx +6 -4
  177. package/src/components/data-table/export-actions.tsx +76 -48
  178. package/src/components/data-table/pagination.tsx +44 -33
  179. package/src/components/data-table/range-focus/atoms.ts +4 -6
  180. package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
  181. package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
  182. package/src/components/data-table/renderers.tsx +16 -7
  183. package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
  184. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
  185. package/src/components/data-table/search-highlight.tsx +79 -0
  186. package/src/components/data-table/types.ts +1 -0
  187. package/src/components/data-table/url-detector.tsx +49 -9
  188. package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
  189. package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
  190. package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
  191. package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
  192. package/src/components/datasources/__tests__/utils.test.ts +57 -6
  193. package/src/components/datasources/column-preview.tsx +17 -12
  194. package/src/components/datasources/datasources.tsx +56 -43
  195. package/src/components/datasources/utils.ts +32 -23
  196. package/src/components/debugger/debugger-code.tsx +5 -0
  197. package/src/components/dependency-graph/custom-node.tsx +1 -1
  198. package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
  199. package/src/components/dependency-graph/elements.ts +24 -21
  200. package/src/components/dependency-graph/minimap-content.tsx +13 -19
  201. package/src/components/dependency-graph/panels.tsx +4 -2
  202. package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
  203. package/src/components/editor/SortableCell.tsx +1 -3
  204. package/src/components/editor/__tests__/Output.test.tsx +50 -32
  205. package/src/{core/attachments/__tests__/toast.test.tsx → components/editor/__tests__/agent-toast.test.tsx} +1 -1
  206. package/src/components/editor/__tests__/data-attributes.test.tsx +28 -14
  207. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  208. package/src/components/editor/__tests__/output-persistence.test.tsx +6 -2
  209. package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
  210. package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
  211. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +34 -8
  212. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +2 -6
  213. package/src/components/editor/actions/name-cell-input.tsx +4 -3
  214. package/src/components/editor/actions/pair-with-agent-commands.ts +2 -2
  215. package/src/components/editor/actions/pair-with-agent-modal.tsx +19 -16
  216. package/src/components/editor/actions/useCellActionButton.tsx +26 -31
  217. package/src/components/editor/actions/useConfigActions.tsx +3 -4
  218. package/src/components/editor/actions/useNotebookActions.tsx +19 -23
  219. package/src/components/editor/actions/useRestartKernel.tsx +1 -1
  220. package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
  221. package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
  222. package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
  223. package/src/components/editor/ai/ai-completion-editor.tsx +1 -0
  224. package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
  225. package/src/components/editor/alerts/connection-notice.tsx +1 -1
  226. package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
  227. package/src/components/editor/alerts/stdin-blocking-alert.tsx +1 -1
  228. package/src/components/editor/app-container.tsx +1 -1
  229. package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
  230. package/src/components/editor/cell/CreateCellButton.tsx +15 -21
  231. package/src/components/editor/cell/DeleteButton.tsx +3 -2
  232. package/src/components/editor/cell/RunButton.tsx +2 -2
  233. package/src/components/editor/cell/StagedAICell.tsx +10 -2
  234. package/src/components/editor/cell/StopButton.tsx +2 -2
  235. package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +3 -1
  236. package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
  237. package/src/components/editor/cell/cell-actions.tsx +12 -1
  238. package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
  239. package/src/components/editor/cell/code/cell-editor.tsx +36 -43
  240. package/src/components/editor/cell/code/language-toggle.tsx +8 -7
  241. package/src/components/editor/cell/collapse.tsx +11 -4
  242. package/src/components/editor/cell/useAddCell.ts +4 -8
  243. package/src/components/editor/cell/useDeleteCell.tsx +10 -36
  244. package/src/components/editor/cell/useRunCells.ts +2 -5
  245. package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
  246. package/src/components/editor/cell/useSplitCell.tsx +10 -6
  247. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
  248. package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
  249. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
  250. package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
  251. package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
  252. package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
  253. package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
  254. package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
  255. package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
  256. package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
  257. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
  258. package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
  259. package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
  260. package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
  261. package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
  262. package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
  263. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +9 -18
  264. package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
  265. package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +61 -2
  266. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +4 -4
  267. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
  268. package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
  269. package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
  270. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
  271. package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
  272. package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
  273. package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
  274. package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +12 -2
  275. package/src/components/editor/chrome/wrapper/storage.ts +1 -1
  276. package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
  277. package/src/components/editor/columns/cell-column.tsx +1 -1
  278. package/src/components/editor/columns/sortable-column.tsx +2 -2
  279. package/src/components/editor/connections/components.tsx +5 -10
  280. package/src/components/editor/controls/Controls.tsx +4 -4
  281. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  282. package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
  283. package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
  284. package/src/components/editor/controls/command-palette.tsx +22 -10
  285. package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
  286. package/src/components/editor/documentation.css +34 -11
  287. package/src/components/editor/dynamic-favicon.tsx +21 -40
  288. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +17 -29
  289. package/src/components/editor/errors/auto-fix.tsx +4 -8
  290. package/src/components/editor/errors/send-error-report-button.tsx +3 -6
  291. package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
  292. package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
  293. package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
  294. package/src/components/editor/file-tree/file-explorer.tsx +48 -15
  295. package/src/components/editor/file-tree/file-name-input.tsx +1 -0
  296. package/src/components/editor/file-tree/file-viewer.tsx +4 -2
  297. package/src/components/editor/file-tree/use-file-search.ts +35 -21
  298. package/src/components/editor/header/__tests__/status.test.tsx +5 -3
  299. package/src/components/editor/header/app-header.tsx +1 -1
  300. package/src/components/editor/header/status.tsx +40 -20
  301. package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
  302. package/src/components/editor/links/cell-link-list.tsx +1 -1
  303. package/src/components/editor/links/cell-link.tsx +17 -7
  304. package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
  305. package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
  306. package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
  307. package/src/components/editor/navigation/clipboard.ts +17 -14
  308. package/src/components/editor/navigation/focus-utils.ts +23 -4
  309. package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
  310. package/src/components/editor/navigation/navigation.ts +71 -70
  311. package/src/components/editor/navigation/selection.ts +30 -29
  312. package/src/components/editor/notebook-banner.tsx +1 -0
  313. package/src/components/editor/notebook-cell.tsx +29 -31
  314. package/src/components/editor/output/MarimoErrorOutput.tsx +2 -1
  315. package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
  316. package/src/components/editor/output/Outputs.css +8 -0
  317. package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
  318. package/src/components/editor/output/ansi-reduce.ts +33 -20
  319. package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
  320. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
  321. package/src/components/editor/package-alert.tsx +14 -7
  322. package/src/components/editor/renderers/cell-array.tsx +22 -33
  323. package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
  324. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -1
  325. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
  326. package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
  327. package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
  328. package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
  329. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +1 -1
  330. package/src/components/editor/stdin-blocking-alert.tsx +1 -1
  331. package/src/components/home/components.tsx +17 -31
  332. package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
  333. package/src/components/icons/large-spinner.tsx +3 -14
  334. package/src/components/icons/spinner.tsx +1 -1
  335. package/src/components/markdown/markdown-renderer.tsx +4 -8
  336. package/src/components/mcp/mcp-status-indicator.tsx +1 -1
  337. package/src/components/pages/__tests__/home-page.test.tsx +116 -0
  338. package/src/components/pages/edit-page.tsx +19 -17
  339. package/src/components/pages/home-page.tsx +164 -91
  340. package/src/components/scratchpad/scratchpad.test.tsx +97 -0
  341. package/src/components/scratchpad/scratchpad.tsx +20 -11
  342. package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
  343. package/src/components/slides/__tests__/minimap.test.ts +38 -19
  344. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
  345. package/src/components/slides/minimap.tsx +17 -12
  346. package/src/components/slides/reveal-component.tsx +58 -26
  347. package/src/components/slides/reveal-slides.css +5 -4
  348. package/src/components/slides/slide-cell-view.tsx +4 -5
  349. package/src/components/slides/slide-form.tsx +1 -0
  350. package/src/components/slides/slide-scroll-hint.tsx +3 -1
  351. package/src/components/sort/SortableCellsProvider.tsx +8 -25
  352. package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
  353. package/src/components/tracing/tracing.tsx +46 -42
  354. package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
  355. package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
  356. package/src/components/ui/alert-dialog.tsx +1 -1
  357. package/src/components/ui/draggable-popover.tsx +24 -2
  358. package/src/components/ui/range-slider.tsx +22 -9
  359. package/src/core/MarimoApp.tsx +1 -1
  360. package/src/core/ai/__tests__/staged-cells.test.ts +27 -26
  361. package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
  362. package/src/core/ai/context/providers/cell-output.ts +2 -2
  363. package/src/core/ai/context/providers/datasource.ts +6 -2
  364. package/src/core/ai/staged-cells.ts +15 -18
  365. package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
  366. package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
  367. package/src/core/ai/tools/base.ts +18 -15
  368. package/src/core/ai/tools/edit-notebook-tool.ts +86 -80
  369. package/src/core/ai/tools/registry.ts +13 -10
  370. package/src/core/ai/tools/sample-tool.ts +6 -7
  371. package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -37
  372. package/src/core/cells/__tests__/actions.test.ts +624 -35
  373. package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
  374. package/src/core/cells/__tests__/arrange.test.ts +432 -0
  375. package/src/core/cells/__tests__/cell.test.ts +39 -0
  376. package/src/core/cells/__tests__/cells.test.ts +218 -2491
  377. package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
  378. package/src/core/cells/__tests__/document.test.ts +341 -0
  379. package/src/core/cells/__tests__/editor.test.ts +57 -0
  380. package/src/core/cells/__tests__/flush-document.test.ts +40 -0
  381. package/src/core/cells/__tests__/harness.ts +106 -0
  382. package/src/core/cells/__tests__/layout.test.ts +177 -0
  383. package/src/core/cells/__tests__/notebook-outline.test.ts +120 -0
  384. package/src/core/cells/__tests__/outputs.test.tsx +71 -53
  385. package/src/core/cells/__tests__/session.test.ts +445 -211
  386. package/src/core/cells/__tests__/utils.test.ts +9 -108
  387. package/src/core/cells/__tests__/with-document-save.test.ts +67 -0
  388. package/src/core/cells/actions.ts +636 -6
  389. package/src/core/cells/add-missing-import.ts +47 -43
  390. package/src/core/cells/arrange.ts +529 -0
  391. package/src/core/cells/cell.ts +14 -3
  392. package/src/core/cells/cells.ts +120 -1337
  393. package/src/core/cells/columns.ts +38 -0
  394. package/src/core/cells/document.ts +289 -0
  395. package/src/core/cells/edit.ts +30 -0
  396. package/src/core/cells/editor.ts +82 -0
  397. package/src/core/cells/layout.ts +221 -0
  398. package/src/core/cells/outputs.ts +12 -28
  399. package/src/core/cells/pending-delete-service.ts +3 -7
  400. package/src/core/cells/session.ts +76 -53
  401. package/src/core/cells/types.ts +22 -6
  402. package/src/core/cells/utils.ts +10 -8
  403. package/src/core/codemirror/__tests__/setup.test.ts +29 -29
  404. package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
  405. package/src/core/codemirror/ai/resources.ts +1 -1
  406. package/src/core/codemirror/cells/__tests__/extensions.test.ts +42 -1
  407. package/src/core/codemirror/cells/extensions.ts +27 -9
  408. package/src/core/codemirror/cells/state.ts +1 -1
  409. package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
  410. package/src/core/codemirror/copilot/getCodes.ts +2 -2
  411. package/src/core/codemirror/format.ts +6 -5
  412. package/src/core/codemirror/keymaps/vim.ts +4 -8
  413. package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
  414. package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
  415. package/src/core/codemirror/language/cell-code.ts +114 -0
  416. package/src/core/codemirror/language/extension.ts +52 -35
  417. package/src/core/codemirror/language/languages/markdown.ts +8 -6
  418. package/src/core/codemirror/language/languages/python.ts +16 -10
  419. package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
  420. package/src/core/codemirror/language/panel/panel.tsx +1 -0
  421. package/src/core/codemirror/language/types.ts +7 -7
  422. package/src/core/codemirror/language/utils.ts +9 -39
  423. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
  424. package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
  425. package/src/core/codemirror/lsp/utils.ts +1 -1
  426. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  427. package/src/core/codemirror/readonly/extension.ts +2 -2
  428. package/src/core/codemirror/rtc/extension.ts +24 -13
  429. package/src/core/codemirror/rtc/loro/awareness.ts +34 -19
  430. package/src/core/codemirror/rtc/loro/sync.ts +1 -0
  431. package/src/core/codemirror/utils.ts +1 -0
  432. package/src/core/config/__tests__/app-config.test.ts +64 -0
  433. package/src/core/config/__tests__/config-schema.test.ts +13 -6
  434. package/src/core/config/config-schema.ts +13 -3
  435. package/src/core/config/config.ts +26 -12
  436. package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
  437. package/src/core/datasets/data-source-discovery.ts +4 -6
  438. package/src/core/documentation/doc-lookup.ts +1 -1
  439. package/src/core/edit-app.tsx +21 -28
  440. package/src/core/errors/error-entries.ts +4 -1
  441. package/src/core/export/hooks.ts +1 -1
  442. package/src/core/export/layout.ts +2 -2
  443. package/src/core/hotkeys/actions.ts +2 -4
  444. package/src/core/islands/__tests__/bootstrap.test.ts +69 -43
  445. package/src/core/islands/__tests__/bridge.test.ts +72 -25
  446. package/src/core/islands/bootstrap.ts +46 -54
  447. package/src/core/islands/bridge.ts +74 -23
  448. package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
  449. package/src/core/islands/components/web-components.tsx +1 -1
  450. package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
  451. package/src/core/islands/worker/controller.ts +4 -10
  452. package/src/core/islands/worker/worker.tsx +33 -33
  453. package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
  454. package/src/core/kernel/__tests__/handlers.test.ts +7 -153
  455. package/src/core/kernel/handlers.ts +19 -72
  456. package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
  457. package/src/core/meta/code-visibility.ts +18 -9
  458. package/src/core/network/__tests__/connection.test.ts +1 -1
  459. package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
  460. package/src/core/network/connection-notice.ts +1 -1
  461. package/src/core/network/connection.ts +1 -1
  462. package/src/core/network/requests-lazy.ts +1 -4
  463. package/src/core/network/requests-network.ts +0 -25
  464. package/src/core/network/requests-static.ts +0 -3
  465. package/src/core/network/requests-toasting.tsx +0 -3
  466. package/src/core/network/types.ts +0 -12
  467. package/src/core/network/useConnectionNotice.ts +8 -2
  468. package/src/core/notebook/__tests__/operations.test.ts +51 -0
  469. package/src/core/notebook/attachments.ts +38 -0
  470. package/src/core/notebook/document/__tests__/codemirror.test.ts +586 -0
  471. package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
  472. package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
  473. package/src/core/notebook/document/__tests__/hold.test.ts +88 -0
  474. package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
  475. package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
  476. package/src/core/notebook/document/__tests__/model.test.ts +247 -0
  477. package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
  478. package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
  479. package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
  480. package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
  481. package/src/core/notebook/document/__tests__/state.test.ts +459 -0
  482. package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
  483. package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
  484. package/src/core/notebook/document/__tests__/test-host.ts +247 -0
  485. package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
  486. package/src/core/notebook/document/__tests__/user.ts +61 -0
  487. package/src/core/notebook/document/codemirror.ts +216 -0
  488. package/src/core/notebook/document/draft.ts +502 -0
  489. package/src/core/notebook/document/hooks.tsx +118 -0
  490. package/src/core/notebook/document/index.ts +24 -0
  491. package/src/core/notebook/document/model.ts +105 -0
  492. package/src/core/notebook/document/select.ts +41 -0
  493. package/src/core/notebook/document/state.ts +378 -0
  494. package/src/core/notebook/document/sync.ts +418 -0
  495. package/src/core/notebook/index.ts +19 -0
  496. package/src/core/notebook/operations.ts +30 -0
  497. package/src/core/notebook/replica/AGENTS.md +11 -0
  498. package/src/core/notebook/replica/__tests__/attachments.test.ts +56 -0
  499. package/src/core/{host → notebook/replica}/__tests__/document.test.ts +18 -16
  500. package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
  501. package/src/core/notebook/replica/__tests__/replica.test.ts +550 -0
  502. package/src/core/notebook/replica/backend.ts +19 -0
  503. package/src/core/notebook/replica/connection.ts +42 -0
  504. package/src/core/notebook/replica/index.ts +13 -0
  505. package/src/core/notebook/replica/replica.ts +286 -0
  506. package/src/core/notebook/replica/resources/attachments.ts +22 -0
  507. package/src/core/{host → notebook/replica}/resources/document.ts +4 -4
  508. package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
  509. package/src/core/packages/useSandboxController.ts +1 -1
  510. package/src/core/run-app.tsx +48 -51
  511. package/src/core/runtime/__tests__/adapter.test.ts +1 -1
  512. package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
  513. package/src/core/runtime/__tests__/runtime.test.ts +32 -58
  514. package/src/core/runtime/adapter.ts +1 -1
  515. package/src/core/runtime/config.ts +2 -2
  516. package/src/core/runtime/runtime.ts +38 -42
  517. package/src/core/runtime/types.ts +0 -2
  518. package/src/core/saving/__tests__/state.test.ts +111 -0
  519. package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
  520. package/src/core/saving/filename.ts +1 -1
  521. package/src/core/saving/save-component.tsx +28 -36
  522. package/src/core/saving/state.ts +38 -39
  523. package/src/core/saving/useAutoSave.ts +17 -53
  524. package/src/core/session/__tests__/backend.test.ts +236 -0
  525. package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +184 -0
  526. package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +663 -0
  527. package/src/core/session/active-notebook.ts +22 -0
  528. package/src/core/session/backend.ts +123 -0
  529. package/src/core/session/embedded.ts +7 -0
  530. package/src/core/{websocket → session}/types.ts +2 -2
  531. package/src/core/session/useNotebookReplica.ts +74 -0
  532. package/src/core/{websocket → session}/useNotebookSession.tsx +77 -72
  533. package/src/core/state/__tests__/jotai.test.tsx +108 -0
  534. package/src/core/state/jotai.ts +1 -1
  535. package/src/core/static/__tests__/files.test.ts +38 -10
  536. package/src/core/static/files.ts +2 -0
  537. package/src/core/{websocket → transports}/__tests__/connection-state.test.ts +1 -13
  538. package/src/core/transports/__tests__/server.test.ts +408 -0
  539. package/src/core/transports/__tests__/static.test.ts +306 -0
  540. package/src/core/transports/__tests__/wasm.test.ts +166 -0
  541. package/src/core/{websocket → transports}/connection-state.ts +9 -16
  542. package/src/core/transports/server.ts +152 -0
  543. package/src/core/transports/static.ts +166 -0
  544. package/src/core/transports/wasm.ts +97 -0
  545. package/src/core/wasm/__tests__/bridge.test.ts +214 -50
  546. package/src/core/wasm/__tests__/worker.test.ts +187 -0
  547. package/src/core/wasm/bridge.ts +75 -69
  548. package/src/core/wasm/rpc.ts +15 -3
  549. package/src/core/wasm/store.ts +3 -3
  550. package/src/core/wasm/worker/bootstrap.ts +55 -51
  551. package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
  552. package/src/core/wasm/worker/save-worker.ts +9 -10
  553. package/src/core/wasm/worker/types.ts +29 -18
  554. package/src/core/wasm/worker/worker.ts +88 -44
  555. package/src/css/globals.css +66 -22
  556. package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
  557. package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
  558. package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
  559. package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
  560. package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
  561. package/src/hooks/__tests__/useScript.test.tsx +77 -0
  562. package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
  563. package/src/hooks/useAsyncData.ts +3 -3
  564. package/src/hooks/useDataSourceDiscovery.ts +6 -4
  565. package/src/hooks/useDebounce.ts +6 -10
  566. package/src/hooks/useDeepCompareMemoize.ts +1 -1
  567. package/src/hooks/useDelayElapsed.ts +14 -10
  568. package/src/hooks/useElapsedTime.ts +3 -3
  569. package/src/hooks/useEventListener.ts +1 -2
  570. package/src/hooks/useInputHistory.ts +4 -7
  571. package/src/hooks/useInternalStateWithSync.ts +6 -6
  572. package/src/hooks/useResizeObserver.ts +4 -7
  573. package/src/hooks/useScript.ts +67 -70
  574. package/src/hooks/useStateForKey.ts +93 -0
  575. package/src/mount.tsx +20 -15
  576. package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
  577. package/src/plugins/core/registerReactComponent.tsx +1 -1
  578. package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
  579. package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
  580. package/src/plugins/impl/DataTablePlugin.tsx +69 -37
  581. package/src/plugins/impl/DropdownPlugin.tsx +2 -6
  582. package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
  583. package/src/plugins/impl/FormPlugin.tsx +1 -1
  584. package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
  585. package/src/plugins/impl/RefreshPlugin.tsx +1 -0
  586. package/src/plugins/impl/SliderPlugin.tsx +6 -8
  587. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +387 -1
  588. package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
  589. package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
  590. package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
  591. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
  592. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
  593. package/src/plugins/impl/anywidget/model.ts +3 -1
  594. package/src/plugins/impl/anywidget/registry.ts +18 -14
  595. package/src/plugins/impl/anywidget/runtime.ts +21 -9
  596. package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
  597. package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
  598. package/src/plugins/impl/chat/chat-ui.tsx +14 -11
  599. package/src/plugins/impl/code/any-language-editor.tsx +2 -2
  600. package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
  601. package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
  602. package/src/plugins/impl/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
  603. package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
  604. package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
  605. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
  606. package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
  607. package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
  608. package/src/plugins/impl/data-frames/panel.tsx +43 -16
  609. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
  610. package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
  611. package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
  612. package/src/plugins/impl/panel/utils.ts +17 -0
  613. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
  614. package/src/plugins/impl/plotly/selection.ts +25 -19
  615. package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
  616. package/src/plugins/impl/vega/make-selectable.ts +4 -7
  617. package/src/plugins/layout/RoutesPlugin.tsx +1 -1
  618. package/src/stories/__tests__/editor-story.test.tsx +33 -0
  619. package/src/stories/button.stories.tsx +1 -0
  620. package/src/stories/cell.stories.tsx +2 -5
  621. package/src/stories/data-table.stories.tsx +31 -0
  622. package/src/stories/editor.stories.tsx +24 -17
  623. package/src/stories/form-wrapper.stories.tsx +2 -2
  624. package/src/stories/layout/vertical/one-column.stories.tsx +2 -5
  625. package/src/stories/runtime-story.tsx +23 -17
  626. package/src/stories/select.stories.tsx +2 -2
  627. package/src/stories/switchable-multi-select.stories.tsx +1 -1
  628. package/src/utils/__tests__/arrays.test.ts +35 -0
  629. package/src/utils/__tests__/batch-requests.test.ts +3 -3
  630. package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +29 -0
  631. package/src/utils/__tests__/numbers.test.ts +105 -1
  632. package/src/utils/__tests__/objects.test.ts +21 -0
  633. package/src/utils/arrays.ts +11 -2
  634. package/src/utils/blob.ts +1 -1
  635. package/src/utils/createReducer.ts +53 -26
  636. package/src/utils/maps.ts +0 -3
  637. package/src/utils/numbers.ts +79 -18
  638. package/src/utils/objects.ts +4 -9
  639. package/src/utils/once.ts +19 -19
  640. package/src/utils/tracer.ts +9 -5
  641. package/src/utils/zod-utils.ts +1 -3
  642. package/dist/any-language-editor-DZ_YTVus.js +0 -76
  643. package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
  644. package/dist/assets/worker-HPY9fbhz.js +0 -114
  645. package/dist/code-visibility-DkCqn-PO.js +0 -138
  646. package/dist/feedback-button-wnAMXOGA.js +0 -379
  647. package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
  648. package/dist/precisionRound-DMIVQrt2.js +0 -97
  649. package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
  650. package/src/components/editor/navigation/state.ts +0 -65
  651. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
  652. package/src/core/ai/tools/run-cells-tool.ts +0 -303
  653. package/src/core/attachments/state.ts +0 -21
  654. package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
  655. package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
  656. package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
  657. package/src/core/cells/document-changes.ts +0 -944
  658. package/src/core/host/AGENTS.md +0 -11
  659. package/src/core/host/__tests__/events.test.ts +0 -46
  660. package/src/core/host/__tests__/fixtures.ts +0 -39
  661. package/src/core/host/__tests__/notebook-client.test.ts +0 -303
  662. package/src/core/host/__tests__/protocol.test.ts +0 -214
  663. package/src/core/host/__tests__/stream.test.ts +0 -211
  664. package/src/core/host/connection.ts +0 -81
  665. package/src/core/host/events.ts +0 -60
  666. package/src/core/host/notebook-client.ts +0 -272
  667. package/src/core/host/protocol.ts +0 -1943
  668. package/src/core/host/resources/resource.ts +0 -59
  669. package/src/core/host/stream.ts +0 -213
  670. package/src/core/state/__tests__/jotai.test.ts +0 -25
  671. package/src/core/wasm/worker/message-buffer.ts +0 -33
  672. package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
  673. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -140
  674. package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +0 -883
  675. package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
  676. package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
  677. package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
  678. package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
  679. package/src/core/websocket/transports/basic.ts +0 -102
  680. package/src/core/websocket/transports/create.ts +0 -31
  681. package/src/core/websocket/transports/sse.ts +0 -308
  682. package/src/core/websocket/transports/transport.ts +0 -50
  683. package/src/core/websocket/transports/ws.ts +0 -98
  684. package/src/core/websocket/useNotebookClient.ts +0 -80
  685. package/src/utils/__tests__/id-tree.test.ts +0 -2145
  686. package/src/utils/id-tree.tsx +0 -1134
  687. /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
  688. /package/src/core/{websocket → session}/connection-utils.ts +0 -0
@@ -6,11 +6,10 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
6
6
  import { Mocks } from "@/__mocks__/common";
7
7
  import { cellId } from "@/__tests__/branded";
8
8
  import { parseOutline } from "@/core/dom/outline";
9
- import { MultiColumn, visibleForTesting } from "@/utils/id-tree";
10
9
  import { invariant } from "@/utils/invariant";
11
10
  import { Logger } from "@/utils/Logger";
12
11
  import { SETUP_CELL_ID } from "../ids";
13
- import { notebookStateFromSession } from "../session";
12
+ import { readExport } from "../session";
14
13
 
15
14
  // Mock dependencies
16
15
  vi.mock("@/utils/Logger", () => ({ Logger: Mocks.quietLogger() }));
@@ -25,10 +24,16 @@ type NotebookCell = api.Notebook["NotebookV1"]["cells"][0];
25
24
  // Test constants
26
25
  const CELL_1 = cellId("cell-1");
27
26
 
28
- describe("notebookStateFromSession", () => {
27
+ /** The snapshot's record of a cell. */
28
+ function cellIn(result: ReturnType<typeof readExport>, id: string) {
29
+ const cell = result.snapshot?.cells.find((cell) => cell.id === id);
30
+ invariant(cell, `no cell ${id}`);
31
+ return cell;
32
+ }
33
+
34
+ describe("readExport", () => {
29
35
  beforeEach(() => {
30
36
  vi.clearAllMocks();
31
- visibleForTesting.reset();
32
37
  });
33
38
 
34
39
  // Test data factories
@@ -46,10 +51,17 @@ describe("notebookStateFromSession", () => {
46
51
 
47
52
  const createNotebookCell = (
48
53
  id: string,
49
- code: string | null = null,
50
- name: string | null = null,
51
- config: NotebookCell["config"] | null = null,
52
- code_hash: string | null = null,
54
+ {
55
+ code = null,
56
+ name = null,
57
+ config = null,
58
+ code_hash = null,
59
+ }: {
60
+ code?: string | null;
61
+ name?: string | null;
62
+ config?: NotebookCell["config"] | null;
63
+ code_hash?: string | null;
64
+ } = {},
53
65
  ): NotebookCell => ({
54
66
  id,
55
67
  code,
@@ -81,72 +93,113 @@ describe("notebookStateFromSession", () => {
81
93
 
82
94
  describe("validation", () => {
83
95
  it("logs error for both session and notebook null/undefined", () => {
84
- const result = notebookStateFromSession(null, null);
85
- expect(result).toBeNull();
96
+ const result = readExport({
97
+ session: null,
98
+ notebook: null,
99
+ filename: null,
100
+ appConfig: {},
101
+ });
102
+ expect(result.snapshot).toBeNull();
86
103
  });
87
104
 
88
105
  it("logs error when session and notebook have different cells", () => {
89
106
  const session = createSession([createSessionCell("cell-1")]);
90
- const notebook = createNotebook([createNotebookCell("cell-2")]);
107
+ const notebook = createNotebook([createNotebookCell("cell-2", {})]);
91
108
 
92
- const result = notebookStateFromSession(session, notebook);
109
+ const result = readExport({
110
+ session: session,
111
+ notebook: notebook,
112
+ filename: null,
113
+ appConfig: {},
114
+ });
93
115
 
94
116
  expect(Logger.warn).toHaveBeenCalledWith(
95
117
  "Session and notebook have different cells, attempted merge.",
96
118
  );
97
119
  // Should have the same cell structure as notebook
98
- expect(result).not.toBeNull();
99
- invariant(result, "result is null");
100
- expect(result.cellIds.inOrderIds).toEqual(
101
- MultiColumn.from([["cell-2"]]).inOrderIds,
102
- );
120
+ invariant(result.snapshot, "no snapshot");
121
+ expect(result.snapshot.document.order).toEqual(["cell-2"]);
103
122
  });
104
123
  });
105
124
 
106
125
  describe("null/undefined inputs", () => {
107
126
  it("returns null when both session and notebook are null", () => {
108
- const result = notebookStateFromSession(null, null);
109
- expect(result).toBeNull();
127
+ const result = readExport({
128
+ session: null,
129
+ notebook: null,
130
+ filename: null,
131
+ appConfig: {},
132
+ });
133
+ expect(result.snapshot).toBeNull();
110
134
  });
111
135
 
112
136
  it("returns null when both session and notebook are undefined", () => {
113
- const result = notebookStateFromSession(undefined, undefined);
114
- expect(result).toBeNull();
137
+ const result = readExport({
138
+ session: undefined,
139
+ notebook: undefined,
140
+ filename: null,
141
+ appConfig: {},
142
+ });
143
+ expect(result.snapshot).toBeNull();
115
144
  });
116
145
 
117
146
  it("returns null when session is null and notebook is undefined", () => {
118
- const result = notebookStateFromSession(null, undefined);
119
- expect(result).toBeNull();
147
+ const result = readExport({
148
+ session: null,
149
+ notebook: undefined,
150
+ filename: null,
151
+ appConfig: {},
152
+ });
153
+ expect(result.snapshot).toBeNull();
120
154
  });
121
155
  });
122
156
 
123
157
  describe("session only scenarios", () => {
124
158
  it("creates state from session with single cell", () => {
125
159
  const session = createSession([createSessionCell("cell-1")]);
126
- const result = notebookStateFromSession(session, null);
160
+ const result = readExport({
161
+ session: session,
162
+ notebook: null,
163
+ filename: null,
164
+ appConfig: {},
165
+ });
127
166
 
128
- expect(result).not.toBeNull();
129
- invariant(result, "result is null");
130
- expect(result.cellIds.inOrderIds).toEqual(
131
- MultiColumn.from([[CELL_1]]).inOrderIds,
132
- );
133
- expect(result.cellData[CELL_1].code).toBe("");
167
+ invariant(result.snapshot, "no snapshot");
168
+ expect(result.snapshot.document.order).toEqual([CELL_1]);
169
+ // The session knows outputs, not source; the host withholds it as null.
170
+ expect(cellIn(result, CELL_1).code).toBeNull();
134
171
  expect(result.cellRuntime[CELL_1]).toBeDefined();
135
172
  });
136
173
 
174
+ it("carries the page's filename and app config into the snapshot", () => {
175
+ const session = createSession([createSessionCell("cell-1")]);
176
+ const result = readExport({
177
+ session,
178
+ notebook: null,
179
+ filename: "notebook.py",
180
+ appConfig: { width: "full" },
181
+ });
182
+
183
+ invariant(result.snapshot, "no snapshot");
184
+ expect(result.snapshot.notebook.name).toBe("notebook.py");
185
+ expect(result.snapshot.document.app_config).toEqual({ width: "full" });
186
+ });
187
+
137
188
  it("creates state from session with multiple cells", () => {
138
189
  const session = createSession([
139
190
  createSessionCell("cell-1"),
140
191
  createSessionCell("cell-2"),
141
192
  ]);
142
- const result = notebookStateFromSession(session, null);
193
+ const result = readExport({
194
+ session: session,
195
+ notebook: null,
196
+ filename: null,
197
+ appConfig: {},
198
+ });
143
199
 
144
- expect(result).not.toBeNull();
145
- invariant(result, "result is null");
146
- expect(result.cellIds.inOrderIds).toEqual(
147
- MultiColumn.from([["cell-1", "cell-2"]]).inOrderIds,
148
- );
149
- expect(Object.keys((result as any).cellData)).toEqual([
200
+ invariant(result.snapshot, "no snapshot");
201
+ expect(result.snapshot.document.order).toEqual(["cell-1", "cell-2"]);
202
+ expect(result.snapshot.cells.map((cell) => cell.id)).toEqual([
150
203
  "cell-1",
151
204
  "cell-2",
152
205
  ]);
@@ -166,10 +219,14 @@ describe("notebookStateFromSession", () => {
166
219
  const session = createSession([
167
220
  createSessionCell("cell-1", [errorOutput]),
168
221
  ]);
169
- const result = notebookStateFromSession(session, null);
222
+ const result = readExport({
223
+ session: session,
224
+ notebook: null,
225
+ filename: null,
226
+ appConfig: {},
227
+ });
170
228
 
171
- expect(result).not.toBeNull();
172
- invariant(result, "result is null");
229
+ invariant(result.snapshot, "no snapshot");
173
230
  expect(result.cellRuntime[CELL_1].output).toEqual({
174
231
  channel: "marimo-error",
175
232
  data: [
@@ -212,8 +269,13 @@ describe("notebookStateFromSession", () => {
212
269
  ],
213
270
  ),
214
271
  ]);
215
- const state = notebookStateFromSession(session, null);
216
- invariant(state, "state is null");
272
+ const state = readExport({
273
+ session: session,
274
+ notebook: null,
275
+ filename: null,
276
+ appConfig: {},
277
+ });
278
+ invariant(state.snapshot, "no snapshot");
217
279
  expect(state.cellRuntime[CELL_1].output).toMatchObject({
218
280
  code,
219
281
  data: [
@@ -242,10 +304,14 @@ describe("notebookStateFromSession", () => {
242
304
  const session = createSession([
243
305
  createSessionCell("cell-1", [dataOutput]),
244
306
  ]);
245
- const result = notebookStateFromSession(session, null);
307
+ const result = readExport({
308
+ session: session,
309
+ notebook: null,
310
+ filename: null,
311
+ appConfig: {},
312
+ });
246
313
 
247
- expect(result).not.toBeNull();
248
- invariant(result, "result is null");
314
+ invariant(result.snapshot, "no snapshot");
249
315
  expect(result.cellRuntime[CELL_1].output).toEqual({
250
316
  channel: "output",
251
317
  data: "Hello World",
@@ -272,10 +338,14 @@ describe("notebookStateFromSession", () => {
272
338
  const session = createSession([
273
339
  createSessionCell("cell-1", [], consoleOutputs),
274
340
  ]);
275
- const result = notebookStateFromSession(session, null);
341
+ const result = readExport({
342
+ session: session,
343
+ notebook: null,
344
+ filename: null,
345
+ appConfig: {},
346
+ });
276
347
 
277
- expect(result).not.toBeNull();
278
- invariant(result, "result is null");
348
+ invariant(result.snapshot, "no snapshot");
279
349
  expect(result.cellRuntime[CELL_1].consoleOutputs).toEqual([
280
350
  {
281
351
  channel: "stdout",
@@ -303,7 +373,12 @@ describe("notebookStateFromSession", () => {
303
373
  const session = createSession([
304
374
  createSessionCell("cell-1", [dataOutput]),
305
375
  ]);
306
- const result = notebookStateFromSession(session, null);
376
+ const result = readExport({
377
+ session: session,
378
+ notebook: null,
379
+ filename: null,
380
+ appConfig: {},
381
+ });
307
382
 
308
383
  expect(parseOutline).toHaveBeenCalledWith({
309
384
  channel: "output",
@@ -311,16 +386,21 @@ describe("notebookStateFromSession", () => {
311
386
  mimetype: "text/html",
312
387
  timestamp: 0,
313
388
  });
314
- invariant(result, "result is null");
389
+ invariant(result.snapshot, "no snapshot");
315
390
  expect(result.cellRuntime[CELL_1].outline).toBe(mockOutline);
316
391
  });
317
392
 
318
393
  it("sets outline to null when no output exists", () => {
319
394
  const session = createSession([createSessionCell("cell-1")]);
320
- const result = notebookStateFromSession(session, null);
395
+ const result = readExport({
396
+ session: session,
397
+ notebook: null,
398
+ filename: null,
399
+ appConfig: {},
400
+ });
321
401
 
322
402
  expect(parseOutline).not.toHaveBeenCalled();
323
- invariant(result, "result is null");
403
+ invariant(result.snapshot, "no snapshot");
324
404
  expect(result.cellRuntime[CELL_1].outline).toBeNull();
325
405
  });
326
406
  });
@@ -328,46 +408,59 @@ describe("notebookStateFromSession", () => {
328
408
  describe("notebook only scenarios", () => {
329
409
  it("creates state from notebook with single cell", () => {
330
410
  const notebook = createNotebook([
331
- createNotebookCell("cell-1", "print('hello')", "my_cell"),
411
+ createNotebookCell("cell-1", {
412
+ code: "print('hello')",
413
+ name: "my_cell",
414
+ }),
332
415
  ]);
333
- const result = notebookStateFromSession(null, notebook);
416
+ const result = readExport({
417
+ session: null,
418
+ notebook: notebook,
419
+ filename: null,
420
+ appConfig: {},
421
+ });
334
422
 
335
- expect(result).not.toBeNull();
336
- invariant(result, "result is null");
337
- expect(result.cellIds.inOrderIds).toEqual(
338
- MultiColumn.from([[CELL_1]]).inOrderIds,
339
- );
340
- expect(result.cellData[CELL_1]).toEqual({
341
- id: "cell-1",
423
+ invariant(result.snapshot, "no snapshot");
424
+ expect(result.snapshot.document.order).toEqual([CELL_1]);
425
+ expect(cellIn(result, CELL_1)).toEqual({
426
+ id: CELL_1,
427
+ notebook_id: "embedded",
342
428
  name: "my_cell",
343
429
  code: "print('hello')",
344
- edited: false,
345
- lastCodeRun: null,
346
- lastExecutionTime: null,
347
430
  config: {
348
431
  hide_code: false,
349
432
  disabled: false,
350
433
  column: null,
351
434
  expand_output: false,
352
435
  },
353
- serializedEditorState: null,
436
+ etag: `embedded:${CELL_1}`,
437
+ code_hash: `embedded:${CELL_1}:code`,
438
+ version: 1,
354
439
  });
355
440
  });
356
441
 
357
442
  it("creates state from notebook with custom config", () => {
358
443
  const notebook = createNotebook([
359
- createNotebookCell("cell-1", "code", "name", {
360
- hide_code: true,
361
- disabled: true,
362
- column: 1,
363
- expand_output: true,
444
+ createNotebookCell("cell-1", {
445
+ code: "code",
446
+ name: "name",
447
+ config: {
448
+ hide_code: true,
449
+ disabled: true,
450
+ column: 1,
451
+ expand_output: true,
452
+ },
364
453
  }),
365
454
  ]);
366
- const result = notebookStateFromSession(null, notebook);
455
+ const result = readExport({
456
+ session: null,
457
+ notebook: notebook,
458
+ filename: null,
459
+ appConfig: {},
460
+ });
367
461
 
368
- expect(result).not.toBeNull();
369
- invariant(result, "result is null");
370
- expect(result.cellData[CELL_1].config).toEqual({
462
+ invariant(result.snapshot, "no snapshot");
463
+ expect(cellIn(result, CELL_1).config).toEqual({
371
464
  hide_code: true,
372
465
  disabled: true,
373
466
  column: 1,
@@ -388,24 +481,28 @@ describe("notebookStateFromSession", () => {
388
481
  },
389
482
  };
390
483
  const notebook = createNotebook([notebookCell]);
391
- const result = notebookStateFromSession(null, notebook);
484
+ const result = readExport({
485
+ session: null,
486
+ notebook: notebook,
487
+ filename: null,
488
+ appConfig: {},
489
+ });
392
490
 
393
- expect(result).not.toBeNull();
394
- invariant(result, "result is null");
395
- expect(result.cellData[CELL_1]).toEqual({
396
- id: "cell-1",
397
- name: "",
398
- code: "",
399
- edited: false,
400
- lastCodeRun: null,
401
- lastExecutionTime: null,
491
+ invariant(result.snapshot, "no snapshot");
492
+ expect(cellIn(result, CELL_1)).toEqual({
493
+ id: CELL_1,
494
+ notebook_id: "embedded",
495
+ name: "_",
496
+ code: null,
402
497
  config: {
403
498
  hide_code: false,
404
499
  disabled: false,
405
500
  column: null,
406
501
  expand_output: false,
407
502
  },
408
- serializedEditorState: null,
503
+ etag: `embedded:${CELL_1}`,
504
+ code_hash: `embedded:${CELL_1}:code`,
505
+ version: 1,
409
506
  });
410
507
  });
411
508
 
@@ -422,27 +519,29 @@ describe("notebookStateFromSession", () => {
422
519
  },
423
520
  };
424
521
  const notebook = createNotebook([notebookCell as any]);
425
- const result = notebookStateFromSession(null, notebook);
522
+ const result = readExport({
523
+ session: null,
524
+ notebook: notebook,
525
+ filename: null,
526
+ appConfig: {},
527
+ });
426
528
 
427
- expect(result).not.toBeNull();
428
- invariant(result, "result is null");
429
- expect(result.cellIds.inOrderIds).toEqual(
430
- MultiColumn.from([[SETUP_CELL_ID]]).inOrderIds,
431
- );
432
- expect(result.cellData[SETUP_CELL_ID]).toEqual({
529
+ invariant(result.snapshot, "no snapshot");
530
+ expect(result.snapshot.document.order).toEqual([SETUP_CELL_ID]);
531
+ expect(cellIn(result, SETUP_CELL_ID)).toEqual({
433
532
  id: SETUP_CELL_ID,
533
+ notebook_id: "embedded",
434
534
  name: "setup",
435
535
  code: "import marimo as mo",
436
- edited: false,
437
- lastCodeRun: null,
438
- lastExecutionTime: null,
439
536
  config: {
440
537
  hide_code: false,
441
538
  disabled: false,
442
539
  column: null,
443
540
  expand_output: false,
444
541
  },
445
- serializedEditorState: null,
542
+ etag: `embedded:${SETUP_CELL_ID}`,
543
+ code_hash: `embedded:${SETUP_CELL_ID}:code`,
544
+ version: 1,
446
545
  });
447
546
  });
448
547
  });
@@ -464,26 +563,33 @@ describe("notebookStateFromSession", () => {
464
563
  ),
465
564
  ]);
466
565
  const notebook = createNotebook([
467
- createNotebookCell("cell-1", "print('hello')", "my_cell"),
566
+ createNotebookCell("cell-1", {
567
+ code: "print('hello')",
568
+ name: "my_cell",
569
+ }),
468
570
  ]);
469
- const result = notebookStateFromSession(session, notebook);
571
+ const result = readExport({
572
+ session: session,
573
+ notebook: notebook,
574
+ filename: null,
575
+ appConfig: {},
576
+ });
470
577
 
471
- expect(result).not.toBeNull();
472
- invariant(result, "result is null");
473
- expect(result.cellData[CELL_1]).toEqual({
474
- id: "cell-1",
578
+ invariant(result.snapshot, "no snapshot");
579
+ expect(cellIn(result, CELL_1)).toEqual({
580
+ id: CELL_1,
581
+ notebook_id: "embedded",
475
582
  name: "my_cell",
476
583
  code: "print('hello')",
477
- edited: false,
478
- lastCodeRun: null,
479
- lastExecutionTime: null,
480
584
  config: {
481
585
  hide_code: false,
482
586
  disabled: false,
483
587
  column: null,
484
588
  expand_output: false,
485
589
  },
486
- serializedEditorState: null,
590
+ etag: `embedded:${CELL_1}`,
591
+ code_hash: `embedded:${CELL_1}:code`,
592
+ version: 1,
487
593
  });
488
594
  // Null result means no output.
489
595
  expect(result.cellRuntime[CELL_1].consoleOutputs).toEqual([]);
@@ -495,17 +601,19 @@ describe("notebookStateFromSession", () => {
495
601
  createSessionCell("cell-2"),
496
602
  ]);
497
603
  const notebook = createNotebook([
498
- createNotebookCell("cell-2"),
499
- createNotebookCell("cell-1"),
604
+ createNotebookCell("cell-2", {}),
605
+ createNotebookCell("cell-1", {}),
500
606
  ]);
501
607
 
502
- const result = notebookStateFromSession(session, notebook);
608
+ const result = readExport({
609
+ session: session,
610
+ notebook: notebook,
611
+ filename: null,
612
+ appConfig: {},
613
+ });
503
614
 
504
- expect(result).not.toBeNull();
505
- invariant(result, "result is null");
506
- expect(result.cellIds.inOrderIds).toEqual(
507
- MultiColumn.from([["cell-2", "cell-1"]]).inOrderIds,
508
- );
615
+ invariant(result.snapshot, "no snapshot");
616
+ expect(result.snapshot.document.order).toEqual(["cell-2", "cell-1"]);
509
617
  });
510
618
 
511
619
  it("creates state when session and notebook have identical cell arrays", () => {
@@ -514,52 +622,73 @@ describe("notebookStateFromSession", () => {
514
622
  createSessionCell("cell-2"),
515
623
  ]);
516
624
  const notebook = createNotebook([
517
- createNotebookCell("cell-1"),
518
- createNotebookCell("cell-2"),
625
+ createNotebookCell("cell-1", {}),
626
+ createNotebookCell("cell-2", {}),
519
627
  ]);
520
628
 
521
- const result = notebookStateFromSession(session, notebook);
629
+ const result = readExport({
630
+ session: session,
631
+ notebook: notebook,
632
+ filename: null,
633
+ appConfig: {},
634
+ });
522
635
 
523
636
  expect(Logger.error).not.toHaveBeenCalled();
524
- expect(result).not.toBeNull();
525
- invariant(result, "result is null");
526
- expect(result.cellIds.inOrderIds).toEqual(
527
- MultiColumn.from([["cell-1", "cell-2"]]).inOrderIds,
528
- );
637
+ invariant(result.snapshot, "no snapshot");
638
+ expect(result.snapshot.document.order).toEqual(["cell-1", "cell-2"]);
529
639
  });
530
640
  });
531
641
 
532
642
  describe("empty cells scenarios", () => {
533
643
  it("warns and returns null when session has empty cells array", () => {
534
644
  const session = createSession([]);
535
- const result = notebookStateFromSession(session, null);
645
+ const result = readExport({
646
+ session: session,
647
+ notebook: null,
648
+ filename: null,
649
+ appConfig: {},
650
+ });
536
651
 
537
- expect(result).toBeNull();
652
+ expect(result.snapshot).toBeNull();
538
653
  });
539
654
 
540
655
  it("warns and returns null when notebook has empty cells array", () => {
541
656
  const notebook = createNotebook([]);
542
- const result = notebookStateFromSession(null, notebook);
657
+ const result = readExport({
658
+ session: null,
659
+ notebook: notebook,
660
+ filename: null,
661
+ appConfig: {},
662
+ });
543
663
 
544
- expect(result).toBeNull();
664
+ expect(result.snapshot).toBeNull();
545
665
  });
546
666
 
547
667
  it("warns and returns null when both have empty cells arrays", () => {
548
668
  const session = createSession([]);
549
669
  const notebook = createNotebook([]);
550
- const result = notebookStateFromSession(session, notebook);
670
+ const result = readExport({
671
+ session: session,
672
+ notebook: notebook,
673
+ filename: null,
674
+ appConfig: {},
675
+ });
551
676
 
552
- expect(result).toBeNull();
677
+ expect(result.snapshot).toBeNull();
553
678
  });
554
679
  });
555
680
 
556
681
  describe("edge cases", () => {
557
682
  it("handles session cell with no outputs", () => {
558
683
  const session = createSession([createSessionCell("cell-1", [])]);
559
- const result = notebookStateFromSession(session, null);
684
+ const result = readExport({
685
+ session: session,
686
+ notebook: null,
687
+ filename: null,
688
+ appConfig: {},
689
+ });
560
690
 
561
- expect(result).not.toBeNull();
562
- invariant(result, "result is null");
691
+ invariant(result.snapshot, "no snapshot");
563
692
  expect(result.cellRuntime[CELL_1].output).toBeNull();
564
693
  expect(result.cellRuntime[CELL_1].consoleOutputs).toEqual([]);
565
694
  expect(result.cellRuntime[CELL_1].outline).toBeNull();
@@ -567,10 +696,14 @@ describe("notebookStateFromSession", () => {
567
696
 
568
697
  it("handles session cell with empty console array", () => {
569
698
  const session = createSession([createSessionCell("cell-1", [], [])]);
570
- const result = notebookStateFromSession(session, null);
699
+ const result = readExport({
700
+ session: session,
701
+ notebook: null,
702
+ filename: null,
703
+ appConfig: {},
704
+ });
571
705
 
572
- expect(result).not.toBeNull();
573
- invariant(result, "result is null");
706
+ invariant(result.snapshot, "no snapshot");
574
707
  expect(result.cellRuntime[CELL_1].consoleOutputs).toEqual([]);
575
708
  });
576
709
 
@@ -580,10 +713,14 @@ describe("notebookStateFromSession", () => {
580
713
  { type: "data" as const, data: { "text/plain": "Second" } },
581
714
  ];
582
715
  const session = createSession([createSessionCell("cell-1", outputs)]);
583
- const result = notebookStateFromSession(session, null);
716
+ const result = readExport({
717
+ session: session,
718
+ notebook: null,
719
+ filename: null,
720
+ appConfig: {},
721
+ });
584
722
 
585
- expect(result).not.toBeNull();
586
- invariant(result, "result is null");
723
+ invariant(result.snapshot, "no snapshot");
587
724
  expect(result.cellRuntime[CELL_1].output).toEqual({
588
725
  channel: "output",
589
726
  data: "First",
@@ -603,10 +740,14 @@ describe("notebookStateFromSession", () => {
603
740
  const session = createSession([
604
741
  createSessionCell("cell-1", [dataOutput]),
605
742
  ]);
606
- const result = notebookStateFromSession(session, null);
743
+ const result = readExport({
744
+ session: session,
745
+ notebook: null,
746
+ filename: null,
747
+ appConfig: {},
748
+ });
607
749
 
608
- expect(result).not.toBeNull();
609
- invariant(result, "result is null");
750
+ invariant(result.snapshot, "no snapshot");
610
751
  expect(result.cellRuntime[CELL_1].output).toEqual({
611
752
  channel: "output",
612
753
  data: "Plain text",
@@ -623,10 +764,14 @@ describe("notebookStateFromSession", () => {
623
764
  const session = createSession([
624
765
  createSessionCell("cell-1", [dataOutput]),
625
766
  ]);
626
- const result = notebookStateFromSession(session, null);
767
+ const result = readExport({
768
+ session: session,
769
+ notebook: null,
770
+ filename: null,
771
+ appConfig: {},
772
+ });
627
773
 
628
- expect(result).not.toBeNull();
629
- invariant(result, "result is null");
774
+ invariant(result.snapshot, "no snapshot");
630
775
  expect(result.cellRuntime[CELL_1].output).toEqual({
631
776
  channel: "output",
632
777
  data: undefined,
@@ -637,22 +782,29 @@ describe("notebookStateFromSession", () => {
637
782
 
638
783
  it("returns correct structure with all expected properties", () => {
639
784
  const session = createSession([createSessionCell("cell-1")]);
640
- const result = notebookStateFromSession(session, null);
641
-
642
- expect(result).not.toBeNull();
643
- invariant(result, "result is null");
644
- expect(result).toHaveProperty("cellIds");
645
- expect(result).toHaveProperty("cellData");
646
- expect(result).toHaveProperty("cellRuntime");
647
- expect(result).toHaveProperty("cellHandles");
648
- expect(result).toHaveProperty("history");
649
- expect(result).toHaveProperty("scrollKey");
650
- expect(result).toHaveProperty("cellLogs");
651
-
652
- expect(result.cellHandles).toEqual({});
653
- expect(result.history).toEqual([]);
654
- expect(result.scrollKey).toBeNull();
655
- expect(result.cellLogs).toEqual([]);
785
+ const result = readExport({
786
+ session: session,
787
+ notebook: null,
788
+ filename: null,
789
+ appConfig: {},
790
+ });
791
+
792
+ invariant(result.snapshot, "no snapshot");
793
+ expect(result.snapshot.notebook).toEqual({
794
+ id: "embedded",
795
+ project_id: "embedded",
796
+ path: null,
797
+ name: "",
798
+ updated_at: null,
799
+ });
800
+ expect(result.snapshot.document).toMatchObject({
801
+ notebook_id: "embedded",
802
+ order: result.snapshot.cells.map((cell) => cell.id),
803
+ version: 1,
804
+ });
805
+ expect(Object.keys(result.cellRuntime)).toEqual(
806
+ result.snapshot.document.order,
807
+ );
656
808
  });
657
809
  });
658
810
 
@@ -669,12 +821,42 @@ describe("notebookStateFromSession", () => {
669
821
  };
670
822
  // Create notebook cells with code values 'a' through 'f'
671
823
  const notebookCells = [
672
- createNotebookCell("cell-a", "a", null, null, hashes.a),
673
- createNotebookCell("cell-b", "b", null, null, hashes.b),
674
- createNotebookCell("cell-c", "c", null, null, hashes.c),
675
- createNotebookCell("cell-d", "d", null, null, hashes.d),
676
- createNotebookCell("cell-e", "e", null, null, hashes.e),
677
- createNotebookCell("cell-f", "f", null, null, hashes.f),
824
+ createNotebookCell("cell-a", {
825
+ code: "a",
826
+ name: null,
827
+ config: null,
828
+ code_hash: hashes.a,
829
+ }),
830
+ createNotebookCell("cell-b", {
831
+ code: "b",
832
+ name: null,
833
+ config: null,
834
+ code_hash: hashes.b,
835
+ }),
836
+ createNotebookCell("cell-c", {
837
+ code: "c",
838
+ name: null,
839
+ config: null,
840
+ code_hash: hashes.c,
841
+ }),
842
+ createNotebookCell("cell-d", {
843
+ code: "d",
844
+ name: null,
845
+ config: null,
846
+ code_hash: hashes.d,
847
+ }),
848
+ createNotebookCell("cell-e", {
849
+ code: "e",
850
+ name: null,
851
+ config: null,
852
+ code_hash: hashes.e,
853
+ }),
854
+ createNotebookCell("cell-f", {
855
+ code: "f",
856
+ name: null,
857
+ config: null,
858
+ code_hash: hashes.f,
859
+ }),
678
860
  ];
679
861
  // Create session cells with matching code_hashes
680
862
  const sessionCells = [
@@ -717,19 +899,26 @@ describe("notebookStateFromSession", () => {
717
899
  ];
718
900
  const session = createSession(sessionCells);
719
901
  const notebook = createNotebook(notebookCells);
720
- const result = notebookStateFromSession(session, notebook);
721
- expect(result).not.toBeNull();
722
- invariant(result, "result is null");
902
+ const result = readExport({
903
+ session: session,
904
+ notebook: notebook,
905
+ filename: null,
906
+ appConfig: {},
907
+ });
908
+ invariant(result.snapshot, "no snapshot");
723
909
  // Should have all cell IDs in order
724
- expect(result.cellIds.inOrderIds).toEqual(
725
- MultiColumn.from([
726
- ["cell-a", "cell-b", "cell-c", "cell-d", "cell-e", "cell-f"],
727
- ]).inOrderIds,
728
- );
910
+ expect(result.snapshot.document.order).toEqual([
911
+ "cell-a",
912
+ "cell-b",
913
+ "cell-c",
914
+ "cell-d",
915
+ "cell-e",
916
+ "cell-f",
917
+ ]);
729
918
  // Should have correct code and output for each cell
730
919
  for (const code of ["a", "b", "c", "d", "e", "f"]) {
731
920
  const cid = cellId(`cell-${code}`);
732
- expect(result.cellData[cid].code).toBe(code);
921
+ expect(cellIn(result, cid).code).toBe(code);
733
922
  expect(result.cellRuntime[cid].output).toEqual({
734
923
  channel: "output",
735
924
  data: `${code.toUpperCase()}!`,
@@ -787,32 +976,64 @@ describe("notebookStateFromSession", () => {
787
976
 
788
977
  // Notebook has cells with code 'a', 'c', 'z', 'e', 'g'
789
978
  const notebookCells = [
790
- createNotebookCell("cell-a", "a", null, null, hashes.a),
791
- createNotebookCell("cell-c", "c", null, null, hashes.c),
792
- createNotebookCell("cell-z", "z", null, null, hashes.z),
793
- createNotebookCell("cell-e", "e", null, null, hashes.e),
794
- createNotebookCell("cell-g", "g", null, null, hashes.g),
979
+ createNotebookCell("cell-a", {
980
+ code: "a",
981
+ name: null,
982
+ config: null,
983
+ code_hash: hashes.a,
984
+ }),
985
+ createNotebookCell("cell-c", {
986
+ code: "c",
987
+ name: null,
988
+ config: null,
989
+ code_hash: hashes.c,
990
+ }),
991
+ createNotebookCell("cell-z", {
992
+ code: "z",
993
+ name: null,
994
+ config: null,
995
+ code_hash: hashes.z,
996
+ }),
997
+ createNotebookCell("cell-e", {
998
+ code: "e",
999
+ name: null,
1000
+ config: null,
1001
+ code_hash: hashes.e,
1002
+ }),
1003
+ createNotebookCell("cell-g", {
1004
+ code: "g",
1005
+ name: null,
1006
+ config: null,
1007
+ code_hash: hashes.g,
1008
+ }),
795
1009
  ];
796
1010
 
797
1011
  const session = createSession(sessionCells);
798
1012
  const notebook = createNotebook(notebookCells);
799
- const result = notebookStateFromSession(session, notebook);
1013
+ const result = readExport({
1014
+ session: session,
1015
+ notebook: notebook,
1016
+ filename: null,
1017
+ appConfig: {},
1018
+ });
800
1019
 
801
- expect(result).not.toBeNull();
802
- invariant(result, "result is null");
1020
+ invariant(result.snapshot, "no snapshot");
803
1021
 
804
1022
  // Should have notebook cell IDs in order (notebook is canonical)
805
- expect(result.cellIds.inOrderIds).toEqual(
806
- MultiColumn.from([["cell-a", "cell-c", "cell-z", "cell-e", "cell-g"]])
807
- .inOrderIds,
808
- );
1023
+ expect(result.snapshot.document.order).toEqual([
1024
+ "cell-a",
1025
+ "cell-c",
1026
+ "cell-z",
1027
+ "cell-e",
1028
+ "cell-g",
1029
+ ]);
809
1030
 
810
1031
  // Should have correct code for each cell
811
- expect(result.cellData[cellId("cell-a")].code).toBe("a");
812
- expect(result.cellData[cellId("cell-c")].code).toBe("c");
813
- expect(result.cellData[cellId("cell-z")].code).toBe("z");
814
- expect(result.cellData[cellId("cell-e")].code).toBe("e");
815
- expect(result.cellData[cellId("cell-g")].code).toBe("g");
1032
+ expect(cellIn(result, "cell-a").code).toBe("a");
1033
+ expect(cellIn(result, "cell-c").code).toBe("c");
1034
+ expect(cellIn(result, "cell-z").code).toBe("z");
1035
+ expect(cellIn(result, "cell-e").code).toBe("e");
1036
+ expect(cellIn(result, "cell-g").code).toBe("g");
816
1037
 
817
1038
  // Should have session outputs for matching cells (a, c, e)
818
1039
  expect(result.cellRuntime[cellId("cell-a")].output).toEqual({
@@ -908,35 +1129,48 @@ describe("notebookStateFromSession", () => {
908
1129
 
909
1130
  // Notebook has cells: cell-1 (1 / 0, no hash), cell-2 (mo.md("Hello"), hash=moMd), cell-3 (slider, hash=slider)
910
1131
  const notebookCells = [
911
- createNotebookCell("cell-1", "1 / 0", null, null, null), // no hash
912
- createNotebookCell("cell-2", 'mo.md("Hello")', null, null, hashes.moMd),
913
- createNotebookCell(
914
- "cell-3",
915
- "x = mo.ui.slider(0, 10)",
916
- null,
917
- null,
918
- hashes.slider,
919
- ),
1132
+ createNotebookCell("cell-1", {
1133
+ code: "1 / 0",
1134
+ name: null,
1135
+ config: null,
1136
+ code_hash: null,
1137
+ }), // no hash
1138
+ createNotebookCell("cell-2", {
1139
+ code: 'mo.md("Hello")',
1140
+ name: null,
1141
+ config: null,
1142
+ code_hash: hashes.moMd,
1143
+ }),
1144
+ createNotebookCell("cell-3", {
1145
+ code: "x = mo.ui.slider(0, 10)",
1146
+ name: null,
1147
+ config: null,
1148
+ code_hash: hashes.slider,
1149
+ }),
920
1150
  ];
921
1151
 
922
1152
  const session = createSession(sessionCells);
923
1153
  const notebook = createNotebook(notebookCells);
924
- const result = notebookStateFromSession(session, notebook);
1154
+ const result = readExport({
1155
+ session: session,
1156
+ notebook: notebook,
1157
+ filename: null,
1158
+ appConfig: {},
1159
+ });
925
1160
 
926
- expect(result).not.toBeNull();
927
- invariant(result, "result is null");
1161
+ invariant(result.snapshot, "no snapshot");
928
1162
 
929
1163
  // Should have notebook cell IDs in order (notebook is canonical)
930
- expect(result.cellIds.inOrderIds).toEqual(
931
- MultiColumn.from([["cell-1", "cell-2", "cell-3"]]).inOrderIds,
932
- );
1164
+ expect(result.snapshot.document.order).toEqual([
1165
+ "cell-1",
1166
+ "cell-2",
1167
+ "cell-3",
1168
+ ]);
933
1169
 
934
1170
  // Should have correct code from notebook
935
- expect(result.cellData[cellId("cell-1")].code).toBe("1 / 0");
936
- expect(result.cellData[cellId("cell-2")].code).toBe('mo.md("Hello")');
937
- expect(result.cellData[cellId("cell-3")].code).toBe(
938
- "x = mo.ui.slider(0, 10)",
939
- );
1171
+ expect(cellIn(result, "cell-1").code).toBe("1 / 0");
1172
+ expect(cellIn(result, "cell-2").code).toBe('mo.md("Hello")');
1173
+ expect(cellIn(result, "cell-3").code).toBe("x = mo.ui.slider(0, 10)");
940
1174
 
941
1175
  // cell-1: No matching session cell (hash is null), gets stub session cell
942
1176
  expect(result.cellRuntime[cellId("cell-1")].output).toBeNull();