@marimo-team/islands 0.24.3-dev2 → 0.24.3-dev22

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 (284) hide show
  1. package/dist/{ConnectedDataExplorerComponent-qIKbwYin.js → ConnectedDataExplorerComponent-BLO7UDpo.js} +18 -18
  2. package/dist/{ErrorBoundary-CR-ZQN_c.js → ErrorBoundary-B7uSdDUm.js} +6 -6
  3. package/dist/{ImageComparisonComponent-2a9TMMm2.js → ImageComparisonComponent-RspMflu6.js} +3 -3
  4. package/dist/{Plot-C-9MQeGP.js → Plot-CTyjbQDT.js} +21032 -20666
  5. package/dist/_baseMerge-Bnytch8P.js +165 -0
  6. package/dist/{abnfDiagram-N423BO3Z-CQKwzX8t.js → abnfDiagram-VCTEODGH-DCb2K_RB.js} +17 -18
  7. package/dist/{any-language-editor-CpTnK43-.js → any-language-editor-C0dftc2Z.js} +8 -8
  8. package/dist/arc-7ra3iNdN.js +81 -0
  9. package/dist/architecture-7GRP2DOG-BWLylgiA.js +3 -0
  10. package/dist/{architectureDiagram-T3A2C74G-CncrDpfa.js → architectureDiagram-5GKGNRK7-Bb_n642s.js} +25 -25
  11. package/dist/assets/__vite-browser-external-BajL8aoc.js +1 -0
  12. package/dist/assets/worker-BemUy60C.js +109 -0
  13. package/dist/blockDiagram-I7D4REHJ-BbXEXJRu.js +1922 -0
  14. package/dist/{button-CKBkqR9J.js → button-DdXAm8iz.js} +5 -5
  15. package/dist/{c4Diagram-5PPSVZJV-DarUk3Yq.js → c4Diagram-7LVT6UL2-DcLsbQmR.js} +696 -668
  16. package/dist/{capabilities-CMBBJTcc.js → capabilities-B3ce_GNu.js} +1 -1
  17. package/dist/{channel-CyiYUzJv.js → channel-B5XnTarr.js} +1 -1
  18. package/dist/chat-ui-Cn1TFk66.js +5835 -0
  19. package/dist/{check-CHig47QV.js → check-mcQyZmFG.js} +1 -1
  20. package/dist/{chunk-2Q5K7J3B-BMuJl2jB.js → chunk-2Q5K7J3B-BMkUkeuy.js} +2 -2
  21. package/dist/chunk-4HAMMTFA-D2qv8E0X.js +4188 -0
  22. package/dist/{chunk-5VM5RSS4-Bcq0ftdy.js → chunk-5VM5RSS4-DKsmPCL6.js} +2 -2
  23. package/dist/{chunk-NSK5VX7P-CDTMcJB0.js → chunk-75Z2AOVW-5_HsvXwr.js} +23 -23
  24. package/dist/{chunk-I66GZJ75-BqyTCAPf.js → chunk-DU6HZSFF-BUgAHvnM.js} +21 -4
  25. package/dist/{chunk-2GRJ4B5K-DgO8Qudq.js → chunk-F27PBJKO-DHmYWZXr.js} +4 -4
  26. package/dist/{chunk-KEIR6QF5-C4KX3XYh.js → chunk-FOHPRMQF-BpYR8RqP.js} +4 -4
  27. package/dist/{chunk-WRU74C26-BpWsbiDK.js → chunk-GMAD6QVW-Czynz8aA.js} +486 -258
  28. package/dist/chunk-GVQU2GXP-yQEdulRS.js +37 -0
  29. package/dist/{chunk-5RXB4S5H-tLNUVDdO.js → chunk-IMKFNOWR-Du9BN2Ul.js} +11 -11
  30. package/dist/{chunk-JWPE2WC7-BJwjGUnF.js → chunk-JWPE2WC7-DJvv1t8U.js} +2 -2
  31. package/dist/chunk-L3NEJ4N5-DwRWnDDK.js +245 -0
  32. package/dist/{chunk-7Z6QIM7H-Dc18hFxH.js → chunk-OSK3NFVY-BBKU_Ign.js} +222 -144
  33. package/dist/{chunk-W5SLKNZC-DLnvpEtV.js → chunk-P2QGCYS3-C0iGU29N.js} +20 -20
  34. package/dist/{chunk-KBJHAD2P-BuqWqkcW.js → chunk-POPQ4Y6H-BCbS3Ozc.js} +4 -4
  35. package/dist/{chunk-4I5QYGJK-DpytHuZQ.js → chunk-PWAF6VOD-CTFCL0jI.js} +4 -4
  36. package/dist/{chunk-JQJVKLGR-CgqCwe8E.js → chunk-SHT3W25Y-tUelricH.js} +109 -63
  37. package/dist/{chunk-6Q2QTUOP-DmTcEBMn.js → chunk-SVP7TREG-DK3egkfQ.js} +5 -5
  38. package/dist/{chunk-GF5L2VYU-B0wgCQgS.js → chunk-TICWLB2K-DRANTdnp.js} +13 -13
  39. package/dist/{chunk-XXDRQBXY-D73H4IN0.js → chunk-XXDRQBXY-Dnl5VBqG.js} +3 -3
  40. package/dist/{chunk-Y2CYZVJY-DoegUj_e.js → chunk-Y2CYZVJY-DKKS1VyV.js} +1 -1
  41. package/dist/{chunk-5FQGJX7Z-B85XCPv6.js → chunk-YOKDWASO-DrWbKnxA.js} +6925 -5460
  42. package/dist/classDiagram-ZZMXUADV-7wCSVH7o.js +30 -0
  43. package/dist/classDiagram-v2-VYDZK3BY-QwnvcnhB.js +30 -0
  44. package/dist/{common-C4UahYwr.js → common-DIyUaEO6.js} +7398 -6912
  45. package/dist/{compiler-runtime-CAH9RLw2.js → compiler-runtime-Cj8ZWiNS.js} +2 -2
  46. package/dist/{copy-CD7S58CY.js → copy-C0N4m1lm.js} +4 -4
  47. package/dist/{cose-bilkent-JH36ORCC-FUWHkXFX.js → cose-bilkent-JH36ORCC-_LyRKVqm.js} +2 -2
  48. package/dist/cubic-OaEBhQPK.js +1404 -0
  49. package/dist/cynefin-OW5HDTMX-obq-i80l.js +3 -0
  50. package/dist/{cynefinDiagram-MW4NZA55-BXSFK93J.js → cynefinDiagram-5FMLGOSQ-CB7O4IZB.js} +10 -10
  51. package/dist/{dagre-CGyalH38.js → dagre-DfYd3btw.js} +678 -537
  52. package/dist/dagre-GXQ25YYZ-C-a95ISW.js +425 -0
  53. package/dist/{data-grid-overlay-editor-DZM4BAaI.js → data-grid-overlay-editor-C5eUZVTo.js} +8 -9
  54. package/dist/{data-grid-types-BnZwWG8z.js → data-grid-types-BucVmDDp.js} +1 -1
  55. package/dist/{defaultLocale-DKaU_opG.js → defaultLocale-JI_lnoCe.js} +1 -1
  56. package/dist/{diagram-7IWD3JNH-BjfzDNvj.js → diagram-S7CK7UJ4-BsKLYQaH.js} +40 -39
  57. package/dist/{diagram-UB23O5K3-DDg-7wLA.js → diagram-UQ7AKVKN-ppYdvuTN.js} +10 -10
  58. package/dist/{diagram-B4RE2ZJO-CKccR9eE.js → diagram-VSXAHHWV-BKpmG23x.js} +10 -10
  59. package/dist/{diagram-Q27KOJAE-Zhz01ss7.js → diagram-VX7I27RA-CAMK2l0E.js} +21 -21
  60. package/dist/{diagram-LBJQPF4R-CJ-bOruh.js → diagram-Z3DM3KII-CxQ7MggT.js} +10 -10
  61. package/dist/{dist-dAqZAPcF.js → dist-1HDa70oE.js} +3 -3
  62. package/dist/{dist-3_o3T78I.js → dist-6ChWbo8z.js} +13 -13
  63. package/dist/{dist-Re9sOPOx.js → dist-9x1ZRe-e.js} +2 -2
  64. package/dist/{dist-DEeLqRlU.js → dist-B1vYLK28.js} +1 -1
  65. package/dist/{dist-C5Bn52W4.js → dist-B8D7McG3.js} +3 -3
  66. package/dist/{dist-_XvgytiS.js → dist-BHCHt1NI.js} +1 -1
  67. package/dist/{dist-CRjAdnqF.js → dist-BRxfaJgs.js} +3 -3
  68. package/dist/{dist-Byj2bV8o.js → dist-BVGtK7Ht.js} +1 -1
  69. package/dist/{dist-BIN5LKyE.js → dist-BaHjhkpZ.js} +2 -2
  70. package/dist/{dist-DVFbIwc5.js → dist-BtKIs9N-.js} +1 -1
  71. package/dist/{dist-BrQGcfQ9.js → dist-C2KzV-vf.js} +2 -2
  72. package/dist/{dist-DJFiGP2k.js → dist-C2wDlYdD.js} +2 -2
  73. package/dist/{dist-BVRM2y1P.js → dist-C8xMLVYi.js} +2 -2
  74. package/dist/dist-CMh_W4y4.js +538 -0
  75. package/dist/{dist-BzN60Z2s.js → dist-CPGxfVGX.js} +1 -1
  76. package/dist/{dist-C7v-9nUK.js → dist-Cm3iAFMD.js} +3 -3
  77. package/dist/{dist-CGAxEiaM.js → dist-Cs2FijYk.js} +2 -2
  78. package/dist/{dist-hXd65f0_.js → dist-D1PpnuZB.js} +1 -1
  79. package/dist/{dist-VdvbxG72.js → dist-DHOTQar0.js} +1 -1
  80. package/dist/{dist-DcgzXCfy.js → dist-DPcEtqmG.js} +2 -2
  81. package/dist/{dist-D4Z_qdP4.js → dist-Df0wKI0F.js} +1 -1
  82. package/dist/{dist-qhLI-SHd.js → dist-DszxuxS1.js} +2 -2
  83. package/dist/{dist-BEmkrGoQ.js → dist-Kxgjxakw.js} +1 -1
  84. package/dist/{dist-BbSMhhD2.js → dist-KzZ7WELx.js} +2 -2
  85. package/dist/{dist-jWUab2d1.js → dist-lA1Cttkb.js} +1 -1
  86. package/dist/{dropdown-menu-DhCfcscX.js → dropdown-menu-C73aTomr.js} +184 -184
  87. package/dist/{ebnfDiagram-BXEA7PRR-Dm75pCAS.js → ebnfDiagram-PWID7BFC-DzybELvk.js} +17 -18
  88. package/dist/{erDiagram-JOGREHBK-rVDG3VSQ.js → erDiagram-RLTQ6QDP-BVxV97ld.js} +1037 -798
  89. package/dist/{error-banner-WDhUzJyg.js → error-banner-hCaH06e3.js} +207 -207
  90. package/dist/{esm-CR1nhb1c.js → esm-BElI3qKH.js} +22 -22
  91. package/dist/{esm-C1d0g6Bv.js → esm-G4Fhsgng.js} +51 -37
  92. package/dist/{esm-CesmlDrs.js → esm-blALgIVy.js} +332 -319
  93. package/dist/eventmodeling-NTZA5JFV-D7nP7Uyu.js +3 -0
  94. package/dist/{extends-BPB6_lTK.js → extends-Do6pRuJa.js} +8 -8
  95. package/dist/flowDiagram-HODETNUW-BKvXsWYX.js +16 -0
  96. package/dist/{formats-CJMVUfb3.js → formats-vDAoRpYs.js} +8 -8
  97. package/dist/{ganttDiagram-PKOTCBZU-9D-LXF6P.js → ganttDiagram-EL5Y4UJY-DbzEBLbl.js} +15 -15
  98. package/dist/gitGraph-4MIJSDKK-Dy9uQXGh.js +3 -0
  99. package/dist/{gitGraphDiagram-DS77QQ5N-BfpsXTLf.js → gitGraphDiagram-WWUBYQGX-BMf0iKi1.js} +10 -10
  100. package/dist/{glide-data-editor-sPZ8fUFn.js → glide-data-editor-Bcy8iaZa.js} +2785 -2562
  101. package/dist/{glide-utils-NShAPPtn.js → glide-utils-BMnFm0vZ.js} +4 -4
  102. package/dist/highlighted-body-KPVGNVTW-Ad3MKZ18.js +38 -0
  103. package/dist/{html-to-image-BTYnN4ev.js → html-to-image-CSU-_5BI.js} +5716 -5451
  104. package/dist/info-A6RAGUB7-DKoayiHY.js +3 -0
  105. package/dist/{infoDiagram-6WML65LV-DqCTXHVy.js → infoDiagram-27XIBGKW-B_ucqo-U.js} +7 -7
  106. package/dist/{ishikawaDiagram-WSZJBQD7-BCUYmZ1v.js → ishikawaDiagram-5VMMS53U-BZFx9b-o.js} +8 -8
  107. package/dist/{journeyDiagram-NVQOT4AX-BXB6M4zN.js → journeyDiagram-3NMN7TZE-D2LcKDUO.js} +8 -8
  108. package/dist/{jsx-runtime-CpoKNRgu.js → jsx-runtime-DgDPJV9S.js} +1 -1
  109. package/dist/{kanban-definition-27J2QSJJ-CGRhrDUX.js → kanban-definition-UXKFOSKX-BpIfcu3G.js} +29 -29
  110. package/dist/katex-DFBiSucW.js +21840 -0
  111. package/dist/{label-lwzzBHUW.js → label-e37ixur5.js} +6 -6
  112. package/dist/{linear-D5r_1YqD.js → linear-Cnaq3Tfb.js} +4 -4
  113. package/dist/{loader-VZ__bv4g.js → loader-D2W4oM-3.js} +15 -15
  114. package/dist/main.js +7018 -12382
  115. package/dist/mermaid-B1Jb9HfY.js +3084 -0
  116. package/dist/mermaid-HWGCJPDP-DYCzSILp.js +2 -0
  117. package/dist/mermaid-parser.core-DxuSfYwJ.js +638 -0
  118. package/dist/{mhchem-BjwrxcV-.js → mhchem-DWCF06w9.js} +1 -1
  119. package/dist/{micromark-factory-space-DruVGzeG.js → micromark-factory-space-DGxAzmw8.js} +2 -2
  120. package/dist/{mindmap-definition-FAOFIHXS-C9gRhzZq.js → mindmap-definition-YA3MSWOX-CmpAfv8K.js} +17 -17
  121. package/dist/{node-sql-parser-DesT1xNw.js → node-sql-parser-BiZOJ-FS.js} +0 -3
  122. package/dist/{number-overlay-editor-De2CabLL.js → number-overlay-editor-CFofZaOi.js} +5 -5
  123. package/dist/packet-AYTQ26CC-Yw7ajchJ.js +3 -0
  124. package/dist/{pegDiagram-VL7TDLO6-Df9IUjMD.js → pegDiagram-XKGWAZYB-DO-0Q8SE.js} +19 -20
  125. package/dist/{pick-SnHlmIBN.js → pick-B7vX8zxG.js} +1 -1
  126. package/dist/pie-WAS4IAKB-BKdKOAkL.js +3 -0
  127. package/dist/{pieDiagram-7S7Q4E2Y-BmRzQ8ZP.js → pieDiagram-E7YTZNPT-B1MbuA_g.js} +29 -31
  128. package/dist/{process-output-CsALk6tp.js → process-output-B6HE2ojm.js} +4 -4
  129. package/dist/purify.es-DgKyQviY.js +805 -0
  130. package/dist/{quadrantDiagram-CIZ2JOQS-wFBvWcxS.js → quadrantDiagram-AXDQQJYC-DftINo6g.js} +5 -5
  131. package/dist/radar-RG4KPBEZ-ScR_D_Ts.js +3 -0
  132. package/dist/railroad-74A4TZTK-DQvPSdo5.js +3 -0
  133. package/dist/railroad-abnf-HS5TGJTU-CsJQG2O8.js +3 -0
  134. package/dist/railroad-ebnf-LZEXJU2U-BgEobkSn.js +3 -0
  135. package/dist/railroad-peg-WCYAUIDC-DjLAjofI.js +3 -0
  136. package/dist/{railroadDiagram-AXF67PYL-DxbIatiN.js → railroadDiagram-O6MQD6OU-DPVOQUXC.js} +17 -18
  137. package/dist/{react-dom-C94wmq5w.js → react-dom-BUgJ-ab_.js} +3 -3
  138. package/dist/{react-DMWcHin-.js → react-ofJbxM4x.js} +2 -2
  139. package/dist/{react-vega-DSD5aT7_.js → react-vega-5AcMW8gG.js} +10012 -9369
  140. package/dist/{requirementDiagram-LRYGKXZP-X_x-Y713.js → requirementDiagram-BXWQKSXE-CC7wZ-tM.js} +20 -19
  141. package/dist/{reveal-component-ChYEzi00.js → reveal-component-GEGc56E6.js} +1171 -1105
  142. package/dist/{sankeyDiagram-W5VNT64P-BYJALbbm.js → sankeyDiagram-P5KCCOFB-CDKR5TJH.js} +4 -4
  143. package/dist/schemas-BDZr-nP0.js +5727 -0
  144. package/dist/{select-3qHpFKF9.js → select-UMOSCa3W.js} +246 -246
  145. package/dist/{sequenceDiagram-SI44F4Z6-BiPBe3Sv.js → sequenceDiagram-WJ2MYXX4-DomSyoJI.js} +11 -11
  146. package/dist/{sizeCapture-X5ZJPWSS-BKLDeh5H.js → sizeCapture-INFHLROL-Dx5SpkQF.js} +2 -2
  147. package/dist/{spec-CutWdqo3.js → spec-g740fOWu.js} +4 -4
  148. package/dist/{src-C31ngt98.js → src-CA_m4ONl.js} +298 -303
  149. package/dist/{stateDiagram-OKZ733FA-B7QyNBxH.js → stateDiagram-D77RDMKH-SQLLjdtF.js} +19 -20
  150. package/dist/stateDiagram-v2-MP3YSRHH-Dup4KkIr.js +30 -0
  151. package/dist/style.css +2 -2
  152. package/dist/{swimlanes-SLNWSIFB-B4f8VP3b.js → swimlanes-42K2YHIH-ZXbhyGv6.js} +1501 -1591
  153. package/dist/swimlanesDiagram-VR7AAH4N-CluwxV0g.js +30 -0
  154. package/dist/{swiper-component-C90YjhaV.js → swiper-component-IOUowglM.js} +39 -26
  155. package/dist/{time-aWGfjN8x.js → time-BieKwdYS.js} +42 -42
  156. package/dist/{timeline-definition-Z64GVDOM-Dacq_5lr.js → timeline-definition-24CTP7MA-B8i6B9RR.js} +7 -7
  157. package/dist/{toDate-D-Rx3ux5.js → toDate-C3JOXlJT.js} +10 -9
  158. package/dist/{tooltip-Dt77sBeT.js → tooltip-CdE8k0pS.js} +42 -42
  159. package/dist/treeView-Q6P3EWNA-DuRV97YF.js +3 -0
  160. package/dist/treemap-WGGIJYW6-AsLq-uwC.js +3 -0
  161. package/dist/{use-vega-container-remeasure-DUW4tRxq.js → use-vega-container-remeasure-4DwJbPWu.js} +2 -2
  162. package/dist/{useAsyncData-CH6-CgJF.js → useAsyncData-C0f7qnnN.js} +3 -3
  163. package/dist/{useDateFormatter-Cp9Jdxls.js → useDateFormatter-BKpQHt-W.js} +8 -8
  164. package/dist/{useDeepCompareMemoize-JC87C_jO.js → useDeepCompareMemoize-QCa0HbWB.js} +2 -2
  165. package/dist/{useIframeCapabilities-De3C-9b4.js → useIframeCapabilities-CVtNkI3Y.js} +2 -2
  166. package/dist/{useLifecycle-B4RGlyf0.js → useLifecycle-BGRBkTFT.js} +6 -6
  167. package/dist/useTheme-iQ0VoptU.js +904 -0
  168. package/dist/{vega-component-D-IXRnlx.js → vega-component-DRI4BDLQ.js} +15 -15
  169. package/dist/{vega-embed-container-TJ5z5dZw.js → vega-embed-container-CbnTccZi.js} +6 -6
  170. package/dist/vega-loader.browser-D95WfUcj.js +1139 -0
  171. package/dist/{vennDiagram-T6HMQDX7-D-Rcq3Iu.js → vennDiagram-4TSXK5OY-CS7lHhxI.js} +9 -9
  172. package/dist/wardley-WFR3VGLG-Na-tFhQJ.js +3 -0
  173. package/dist/{wardleyDiagram-T6FBY63Y-Z-Og7_Wd.js → wardleyDiagram-VM6X3IG4-BSm-L8JI.js} +10 -10
  174. package/dist/{xychartDiagram-ELKLHX3M-BDJ2dITA.js → xychartDiagram-S5SC5T6Z-8fKCJGrJ.js} +248 -139
  175. package/package.json +52 -52
  176. package/src/__mocks__/requests.ts +7 -2
  177. package/src/__tests__/__snapshots__/CellStatus.test.tsx.snap +12 -12
  178. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
  179. package/src/components/data-table/column-visibility-dropdown.tsx +9 -3
  180. package/src/components/datasources/components.tsx +4 -2
  181. package/src/components/editor/chrome/components/feedback-button.tsx +10 -9
  182. package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +143 -0
  183. package/src/components/editor/chrome/panels/packages-panel.tsx +145 -51
  184. package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
  185. package/src/components/editor/code/readonly-diff.tsx +1 -1
  186. package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
  187. package/src/components/editor/file-tree/tree-actions.tsx +11 -14
  188. package/src/components/editor/output/Outputs.css +1 -0
  189. package/src/components/editor/package-alert.tsx +25 -1
  190. package/src/components/home/components.tsx +17 -0
  191. package/src/components/pages/gallery-page.tsx +2 -4
  192. package/src/components/pages/home-page.tsx +2 -4
  193. package/src/components/terminal/terminal.tsx +4 -4
  194. package/src/components/tracing/tracing-spec.ts +1 -1
  195. package/src/components/ui/table.tsx +1 -1
  196. package/src/core/cells/pending-delete-service.ts +12 -16
  197. package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
  198. package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
  199. package/src/core/codemirror/rtc/extension.ts +5 -2
  200. package/src/core/datasets/__tests__/data-source.test.ts +2 -0
  201. package/src/core/datasets/data-source-connections.ts +15 -10
  202. package/src/core/islands/__tests__/parse.test.ts +140 -7
  203. package/src/core/islands/parse.ts +20 -0
  204. package/src/core/packages/__tests__/useInstallPackage.test.tsx +47 -1
  205. package/src/core/packages/toast-components.tsx +26 -0
  206. package/src/core/packages/useInstallPackage.ts +7 -2
  207. package/src/core/runtime/__tests__/runtime.test.ts +11 -0
  208. package/src/core/runtime/runtime.ts +7 -2
  209. package/src/core/wasm/bridge.ts +1 -0
  210. package/src/core/websocket/transports/transport.ts +1 -1
  211. package/src/core/websocket/transports/ws.ts +1 -1
  212. package/src/css/app/Cell.css +2 -0
  213. package/src/plugins/core/RenderHTML.tsx +22 -2
  214. package/src/plugins/core/__test__/RenderHTML.test.ts +187 -0
  215. package/src/plugins/layout/AccordionPlugin.tsx +7 -2
  216. package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
  217. package/dist/_baseMerge-Dv8bBloN.js +0 -73
  218. package/dist/_initCloneObject---vediN2.js +0 -95
  219. package/dist/arc-DOVLrCPd.js +0 -82
  220. package/dist/architecture-TIHT7OUA-MiJpPpQW.js +0 -3
  221. package/dist/array-CApNbSU9.js +0 -6
  222. package/dist/assets/__vite-browser-external-BdKGjRZ4.js +0 -1
  223. package/dist/assets/worker-DlIBfp9S.js +0 -98
  224. package/dist/blockDiagram-VBNYF7ZC-Bc--I65C.js +0 -3158
  225. package/dist/chat-ui-DttQ-5Ut.js +0 -8455
  226. package/dist/chunk-3NCLNEKW-BIp_lB_4.js +0 -14
  227. package/dist/chunk-5FCAYU7R-C_HO9A1J.js +0 -23
  228. package/dist/chunk-5HE753X5-Bixm_MV-.js +0 -38
  229. package/dist/chunk-5JV3BV7I-CH5J3iZY.js +0 -54
  230. package/dist/chunk-5TONJI2A-DG6gDiSS.js +0 -62
  231. package/dist/chunk-7BUUIJ7U-5afmIPeo.js +0 -82
  232. package/dist/chunk-BIQX33UG-7TMBUf89.js +0 -23
  233. package/dist/chunk-CQNSW5MT-Cnqqsxt-.js +0 -38
  234. package/dist/chunk-CYSBUYHQ-BAbymFHR.js +0 -23
  235. package/dist/chunk-EMLP6XTP-Bsz-QL77.js +0 -23
  236. package/dist/chunk-J7OUQ5F2-CM_meqZH.js +0 -57
  237. package/dist/chunk-JG7HCLWE-DUnCDgPk.js +0 -62
  238. package/dist/chunk-MOZMSUNE-BG6IHvzT.js +0 -35
  239. package/dist/chunk-OSBZ3O6U-CYwj_bvR.js +0 -23
  240. package/dist/chunk-QBLGF6JB-B4vJ4j8J.js +0 -23
  241. package/dist/chunk-QR6OTTB3-D4wH2ldi.js +0 -3738
  242. package/dist/chunk-R7FJI6CG-Blf8FcmZ.js +0 -64
  243. package/dist/chunk-RYQCIY6F-BWbIlBIH.js +0 -241
  244. package/dist/chunk-U6XO7XAA-COw445DS.js +0 -63
  245. package/dist/chunk-UBXNYLIW-BHigVU4H.js +0 -32
  246. package/dist/chunk-YOTPTUD7-Dn044Q_d.js +0 -30
  247. package/dist/chunk-ZIRB5QZD-BR4TMfOa.js +0 -1153
  248. package/dist/classDiagram-JCYQIIEL-DmXSLxe_.js +0 -30
  249. package/dist/classDiagram-v2-OCEON4UE-CooqVexA.js +0 -30
  250. package/dist/click-outside-container-D_URcm3D.js +0 -167
  251. package/dist/code-block-37QAKDTI-CQrzBOr-.js +0 -107
  252. package/dist/cynefin-VYW2F7L2-CeHAxOEX.js +0 -3
  253. package/dist/dagre-VZM6K2ZE-CJggWPTJ.js +0 -328
  254. package/dist/dist-ABQjhuek.js +0 -64
  255. package/dist/dist-CO5R6VMi.js +0 -538
  256. package/dist/eventmodeling-45OFAUF4-B_lWZ-Pd.js +0 -3
  257. package/dist/flowDiagram-UKHOOZJN-g1AmrZzM.js +0 -17
  258. package/dist/gitGraph-TEB2WS4Q-Dj-eXUph.js +0 -3
  259. package/dist/info-DKCQHKI2-Bhb-pe2e.js +0 -3
  260. package/dist/line-CuKjIQa1.js +0 -34
  261. package/dist/map-BJpOfPlL.js +0 -149
  262. package/dist/math-BXtKgYah.js +0 -10
  263. package/dist/mermaid-4DMBBIKO-Ddp9TgNp.js +0 -2
  264. package/dist/mermaid-BsHdQeQf.js +0 -1173
  265. package/dist/mermaid-parser.core-Din9FvSi.js +0 -99
  266. package/dist/packet-7NZHBO7P-fbkIIyKE.js +0 -3
  267. package/dist/path-BNHuHZP8.js +0 -87
  268. package/dist/pie-RZYD4A2V-CLRIsxY1.js +0 -3
  269. package/dist/purify.es-CB-YO1Hn.js +0 -774
  270. package/dist/radar-I7S5WNFK-BGzCbgXu.js +0 -3
  271. package/dist/railroad-3IZDKUUU-CvQIIcuU.js +0 -3
  272. package/dist/railroad-abnf-AHOZXSZD-CMwtlNtu.js +0 -3
  273. package/dist/railroad-ebnf-EBAXGLYW-n1QUOAsh.js +0 -3
  274. package/dist/railroad-peg-LSFZ7HO6-PjnrpmCs.js +0 -3
  275. package/dist/schemas-DzK6U94N.js +0 -6057
  276. package/dist/stateDiagram-v2-UEYNNEHI-BTRUs8Il.js +0 -30
  277. package/dist/step-CKczO72Q.js +0 -670
  278. package/dist/swimlanesDiagram-ULZ7WXOC-NBmgBl9G.js +0 -31
  279. package/dist/timer-DpDyj9G0.js +0 -596
  280. package/dist/treeView-QDETBFTQ-DU8LwHuf.js +0 -3
  281. package/dist/treemap-6X3UGDF4-DUk4-k_O.js +0 -3
  282. package/dist/useTheme-CVJ0UOf2.js +0 -841
  283. package/dist/vega-loader.browser-DEggZzni.js +0 -1083
  284. package/dist/wardley-OPB4EBWU-Db-AaGas.js +0 -3
@@ -7,7 +7,7 @@ const Table = React.forwardRef<
7
7
  HTMLTableElement,
8
8
  React.HTMLAttributes<HTMLTableElement>
9
9
  >(({ className, ...props }, ref) => (
10
- <div className="w-full overflow-auto scrollbar-thin flex-1 print:overflow-hidden">
10
+ <div className="w-full overflow-auto overscroll-contain scrollbar-thin flex-1 print:overflow-hidden">
11
11
  <table
12
12
  ref={ref}
13
13
  className={cn("w-full caption-bottom text-sm", className)}
@@ -1,7 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { useAtomValue, useStore } from "jotai";
4
- import { useMemo } from "react";
5
4
  import {
6
5
  useDeleteCellCallback,
7
6
  useDeleteManyCellsCallback,
@@ -130,21 +129,18 @@ export function usePendingDeleteService() {
130
129
  const { entries } = useAtomValue(pendingDeleteStateAtom);
131
130
  const deleteCell = useDeleteCellCallback();
132
131
  const deleteManyCells = useDeleteManyCellsCallback();
133
- return useMemo(
134
- () => ({
135
- submit: (cellIds: CellId[]) => {
136
- submit({ cellIds, deleteCell, deleteManyCells, store });
137
- },
138
- clear,
139
- get idle() {
140
- return entries.size === 0;
141
- },
142
- get shouldConfirmDelete() {
143
- return entries.size > 1;
144
- },
145
- }),
146
- [store, submit, clear, entries, deleteCell, deleteManyCells],
147
- );
132
+ return {
133
+ submit: (cellIds: CellId[]) => {
134
+ submit({ cellIds, deleteCell, deleteManyCells, store });
135
+ },
136
+ clear,
137
+ get idle() {
138
+ return entries.size === 0;
139
+ },
140
+ get shouldConfirmDelete() {
141
+ return entries.size > 1;
142
+ },
143
+ };
148
144
  }
149
145
 
150
146
  export function usePendingDelete(cellId: CellId) {
@@ -17,6 +17,7 @@ import type {
17
17
  import type { DataSourceConnection } from "@/core/datasets/data-source-connections";
18
18
  import {
19
19
  dataSourceConnectionsAtom,
20
+ exportedForTesting as dataSourceTesting,
20
21
  setLatestEngineSelected,
21
22
  } from "@/core/datasets/data-source-connections";
22
23
  import { type ConnectionName, DUCKDB_ENGINE } from "@/core/datasets/engines";
@@ -550,8 +551,8 @@ _df = mo.sql(
550
551
  const getLatestEngine = () =>
551
552
  store.get(dataSourceConnectionsAtom).latestEngineSelected;
552
553
 
553
- it("should use default engine initially", () => {
554
- expect(getLatestEngine()).toBe(DUCKDB_ENGINE);
554
+ it("should have no selected engine initially", () => {
555
+ expect(getLatestEngine()).toBeNull();
555
556
  });
556
557
 
557
558
  it("should persist the selected engine", () => {
@@ -622,6 +623,73 @@ _df = mo.sql(
622
623
  });
623
624
 
624
625
  describe("defaultCode", () => {
626
+ it("should prefer the newest usable connection until an engine is selected", () => {
627
+ const previousState = store.get(dataSourceConnectionsAtom);
628
+ const connection: DataSourceConnection = {
629
+ name: "first_connection" as ConnectionName,
630
+ source: "sqlite",
631
+ display_name: "SQLite",
632
+ dialect: "sqlite",
633
+ databases: [],
634
+ };
635
+ const newestConnection = {
636
+ ...connection,
637
+ name: "newest_connection" as ConnectionName,
638
+ };
639
+ const icebergConnection = {
640
+ ...connection,
641
+ name: "catalog" as ConnectionName,
642
+ source: "iceberg",
643
+ };
644
+ try {
645
+ store.set(dataSourceConnectionsAtom, {
646
+ latestEngineSelected: null,
647
+ connectionsMap: new Map(),
648
+ });
649
+ expect(adapter.defaultMetadata.engine).toBe(DUCKDB_ENGINE);
650
+ expect(adapter.defaultCode).toBe('_df = mo.sql(f"""SELECT * FROM """)');
651
+
652
+ store.set(dataSourceConnectionsAtom, {
653
+ latestEngineSelected: null,
654
+ connectionsMap: new Map([
655
+ [connection.name, connection],
656
+ [newestConnection.name, newestConnection],
657
+ [icebergConnection.name, icebergConnection],
658
+ [DUCKDB_ENGINE, { ...connection, name: DUCKDB_ENGINE }],
659
+ ]),
660
+ });
661
+ expect(adapter.defaultMetadata.engine).toBe(newestConnection.name);
662
+ expect(adapter.defaultCode).toContain("engine=newest_connection");
663
+ expect(
664
+ store.get(dataSourceConnectionsAtom).latestEngineSelected,
665
+ ).toBeNull();
666
+
667
+ const refreshConnection = (connection: DataSourceConnection) => {
668
+ store.set(
669
+ dataSourceConnectionsAtom,
670
+ dataSourceTesting.reducer(store.get(dataSourceConnectionsAtom), {
671
+ type: "addDataSourceConnection",
672
+ payload: { connections: [connection] },
673
+ }),
674
+ );
675
+ };
676
+ refreshConnection(connection);
677
+ expect(adapter.defaultMetadata.engine).toBe(connection.name);
678
+ expect(adapter.defaultCode).toContain("engine=first_connection");
679
+
680
+ setLatestEngineSelected(connection.name);
681
+ refreshConnection(newestConnection);
682
+ expect(adapter.defaultCode).toContain("engine=first_connection");
683
+
684
+ setLatestEngineSelected(DUCKDB_ENGINE);
685
+ refreshConnection(connection);
686
+ expect(adapter.defaultMetadata.engine).toBe(DUCKDB_ENGINE);
687
+ expect(adapter.defaultCode).toBe('_df = mo.sql(f"""SELECT * FROM """)');
688
+ } finally {
689
+ store.set(dataSourceConnectionsAtom, previousState);
690
+ }
691
+ });
692
+
625
693
  it("should include engine in defaultCode when selected", () => {
626
694
  const engine = "postgres_engine" as ConnectionName;
627
695
  setLatestEngineSelected(engine);
@@ -76,7 +76,22 @@ export interface SQLLanguageAdapterMetadata extends SQLMetadata {
76
76
  }
77
77
 
78
78
  function getLatestEngine(): ConnectionName {
79
- return store.get(dataSourceConnectionsAtom).latestEngineSelected;
79
+ const { latestEngineSelected, connectionsMap } = store.get(
80
+ dataSourceConnectionsAtom,
81
+ );
82
+ if (latestEngineSelected !== null) {
83
+ return latestEngineSelected;
84
+ }
85
+
86
+ // Map insertion order prefers the most recently discovered connection.
87
+ const connections = [...connectionsMap.values()].reverse();
88
+ return (
89
+ connections.find(
90
+ (connection) =>
91
+ !INTERNAL_SQL_ENGINES.has(connection.name) &&
92
+ connection.source !== "iceberg",
93
+ )?.name ?? DUCKDB_ENGINE
94
+ );
80
95
  }
81
96
 
82
97
  /**
@@ -47,7 +47,10 @@ const awarenessLogger = logger.get("awareness").disabled();
47
47
  const AWARENESS_PREFIX = "awareness:";
48
48
 
49
49
  // Utility functions for message handling
50
- function prefixMessage(token: string, message: Uint8Array): Uint8Array {
50
+ function prefixMessage(
51
+ token: string,
52
+ message: Uint8Array,
53
+ ): Uint8Array<ArrayBuffer> {
51
54
  const tokenBytes = new TextEncoder().encode(token);
52
55
  return new Uint8Array([...tokenBytes, ...message]);
53
56
  }
@@ -154,7 +157,7 @@ if (isRtcEnabled()) {
154
157
  doc.subscribeLocalUpdates((update) => {
155
158
  logger.debug("local update, sending to server");
156
159
  const ws = getWs();
157
- ws.send(update);
160
+ ws.send(new Uint8Array(update));
158
161
  });
159
162
 
160
163
  // Handle awareness changes
@@ -106,6 +106,7 @@ describe("data source connections", () => {
106
106
 
107
107
  let newState = addConnection(connections, state);
108
108
  expect(newState.connectionsMap.size).toBe(defaultConnSize + 2);
109
+ newState = { ...newState, latestEngineSelected: connections[0].name };
109
110
 
110
111
  newState = reducer(newState, {
111
112
  type: "removeDataSourceConnection",
@@ -113,6 +114,7 @@ describe("data source connections", () => {
113
114
  });
114
115
  expect(newState.connectionsMap.size).toBe(defaultConnSize + 1);
115
116
  expect(newState.connectionsMap.has("conn2" as ConnectionName)).toBe(true);
117
+ expect(newState.latestEngineSelected).toBeNull();
116
118
  });
117
119
 
118
120
  it("can clear all connections", () => {
@@ -44,7 +44,8 @@ export interface DataSourceConnection extends Omit<
44
44
  export type ConnectionsMap = ReadonlyMap<ConnectionName, DataSourceConnection>;
45
45
 
46
46
  export interface DataSourceState {
47
- latestEngineSelected: ConnectionName;
47
+ // Null permits automatic selection; DuckDB can also be an explicit choice.
48
+ latestEngineSelected: ConnectionName | null;
48
49
  connectionsMap: ConnectionsMap;
49
50
  }
50
51
 
@@ -110,7 +111,7 @@ function tableSchemaPath(sqlTableContext: SQLTableContext): string[] {
110
111
 
111
112
  function initialState(): DataSourceState {
112
113
  return {
113
- latestEngineSelected: DUCKDB_ENGINE,
114
+ latestEngineSelected: null,
114
115
  connectionsMap: initialConnections,
115
116
  };
116
117
  }
@@ -136,6 +137,8 @@ const {
136
137
  // Backend will dedupe by connection name & keep the latest, so we use this as the key
137
138
  const newMap = new Map(connectionsMap);
138
139
  for (const conn of opts.connections) {
140
+ // Refresh insertion order so automatic selection follows discovery recency.
141
+ newMap.delete(conn.name);
139
142
  newMap.set(conn.name, conn);
140
143
  }
141
144
 
@@ -161,16 +164,17 @@ const {
161
164
  }),
162
165
  );
163
166
  return {
164
- // If the latest engine selected is not in the new map, use the default engine
165
- latestEngineSelected: newMap.has(latestEngineSelected)
166
- ? latestEngineSelected
167
- : DUCKDB_ENGINE,
167
+ // Allow automatic selection again when the selected connection disappears.
168
+ latestEngineSelected:
169
+ latestEngineSelected && newMap.has(latestEngineSelected)
170
+ ? latestEngineSelected
171
+ : null,
168
172
  connectionsMap: newMap,
169
173
  };
170
174
  },
171
175
 
172
176
  clearDataSourceConnections: (): DataSourceState => ({
173
- latestEngineSelected: DUCKDB_ENGINE,
177
+ latestEngineSelected: null,
174
178
  connectionsMap: new Map(),
175
179
  }),
176
180
 
@@ -183,9 +187,10 @@ const {
183
187
  const newMap = new Map(connectionsMap);
184
188
  newMap.delete(connectionName);
185
189
  return {
186
- latestEngineSelected: newMap.has(latestEngineSelected)
187
- ? latestEngineSelected
188
- : DUCKDB_ENGINE,
190
+ latestEngineSelected:
191
+ latestEngineSelected && newMap.has(latestEngineSelected)
192
+ ? latestEngineSelected
193
+ : null,
189
194
  connectionsMap: newMap,
190
195
  };
191
196
  },
@@ -19,6 +19,13 @@ import {
19
19
  } from "../parse";
20
20
  import { createMockIslandElement, createMockIslands } from "./test-utils.tsx";
21
21
 
22
+ function islandSnapshotPath(filename: string): string {
23
+ return new URL(
24
+ `../../../../../tests/_islands/snapshots/${filename}`,
25
+ import.meta.url,
26
+ ).pathname.replace(/^\/@fs/, "");
27
+ }
28
+
22
29
  function createPayloadCell(
23
30
  overrides: Partial<{
24
31
  cellId: string;
@@ -47,6 +54,7 @@ function appendPayload(
47
54
  payload: {
48
55
  schemaVersion: number;
49
56
  appId: string;
57
+ dependencies?: unknown;
50
58
  cells: ReturnType<typeof createPayloadCell>[];
51
59
  },
52
60
  ) {
@@ -58,6 +66,33 @@ function appendPayload(
58
66
  }
59
67
 
60
68
  describe("createMarimoFile", () => {
69
+ it("should serialize dependencies as top-level script metadata", () => {
70
+ const file = createMarimoFile({
71
+ dependencies: ['cowsay==6.1; sys_platform == "emscripten"'],
72
+ cells: [{ code: "import cowsay" }],
73
+ });
74
+ expect(file).toBe(
75
+ [
76
+ "# /// script",
77
+ '# dependencies = ["cowsay==6.1; sys_platform == \\"emscripten\\""]',
78
+ "# ///",
79
+ "import marimo",
80
+ "app = marimo.App()",
81
+ "@app.cell",
82
+ "def __():",
83
+ " import cowsay",
84
+ " return",
85
+ ].join("\n"),
86
+ );
87
+ });
88
+
89
+ it("should omit metadata for empty dependencies", () => {
90
+ const cells = [{ code: "import cowsay" }];
91
+ expect(createMarimoFile({ cells, dependencies: [] })).toBe(
92
+ createMarimoFile({ cells }),
93
+ );
94
+ });
95
+
61
96
  it("should return a string", () => {
62
97
  const app = {
63
98
  cells: [
@@ -736,13 +771,7 @@ describe("parseMarimoIslandApps", () => {
736
771
  });
737
772
 
738
773
  it("should parse Python-generated island payload snapshots", () => {
739
- const html = readFileSync(
740
- new URL(
741
- "../../../../../tests/_islands/snapshots/html-payload.txt",
742
- import.meta.url,
743
- ).pathname.replace(/^\/@fs/, ""),
744
- "utf8",
745
- );
774
+ const html = readFileSync(islandSnapshotPath("html-payload.txt"), "utf8");
746
775
  container.innerHTML = html;
747
776
 
748
777
  const result = parseMarimoIslandApps(container);
@@ -775,6 +804,108 @@ describe("parseMarimoIslandApps", () => {
775
804
  expect(islands[2].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1");
776
805
  });
777
806
 
807
+ it("should restore metadata from a Python-generated dependency payload", () => {
808
+ container.innerHTML = readFileSync(
809
+ islandSnapshotPath("body-dependencies.txt"),
810
+ "utf8",
811
+ );
812
+
813
+ const probed = parseMarimoIslandApps(container, { materialize: false });
814
+ const apps = parseMarimoIslandApps(container);
815
+
816
+ expect(probed).toEqual(apps);
817
+ expect(apps).toEqual([
818
+ {
819
+ id: "main",
820
+ payloadBacked: true,
821
+ dependencies: [
822
+ 'cowsay==6.1; sys_platform == "emscripten"',
823
+ "rich[jupyter]>=13",
824
+ "desktop; sys_platform != 'emscripten'",
825
+ "older-python; python_version < '3.13'",
826
+ "newer-python; python_version >= '3.13'",
827
+ ],
828
+ cells: [{ cellId: "Hbol", code: "import cowsay", output: "", idx: 0 }],
829
+ },
830
+ ]);
831
+ // The Python Pyodide test reads this file with the real metadata parser.
832
+ expect(createMarimoFile(apps[0])).toBe(
833
+ readFileSync(islandSnapshotPath("notebook-dependencies.txt"), "utf8"),
834
+ );
835
+ });
836
+
837
+ it("should carry dependencies from payloads into each generated notebook", () => {
838
+ for (const [appId, dependencies] of [
839
+ ["app1", ["cowsay==6.1"]],
840
+ ["app2", ["rich[jupyter]>=13"]],
841
+ ] as const) {
842
+ container.appendChild(
843
+ createMockIslandElement({ appId, cellId: "cell-1" }),
844
+ );
845
+ appendPayload(container, {
846
+ schemaVersion: 1,
847
+ appId,
848
+ dependencies,
849
+ cells: [createPayloadCell()],
850
+ });
851
+ }
852
+
853
+ const apps = parseMarimoIslandApps(container);
854
+ expect(apps.map((app) => [app.id, app.dependencies])).toEqual([
855
+ ["app1", ["cowsay==6.1"]],
856
+ ["app2", ["rich[jupyter]>=13"]],
857
+ ]);
858
+ expect(createMarimoFile(apps[0])).toContain(
859
+ '# /// script\n# dependencies = ["cowsay==6.1"]\n# ///\n',
860
+ );
861
+ });
862
+
863
+ it.each([null, "cowsay", [123], ["cowsay", null]])(
864
+ "should ignore payloads with malformed dependencies: %j",
865
+ (dependencies) => {
866
+ const island = createMockIslandElement({
867
+ appId: "app1",
868
+ cellId: "cell-1",
869
+ code: "import cowsay",
870
+ innerHTML: "<div>dom</div>",
871
+ });
872
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
873
+ container.appendChild(island);
874
+ appendPayload(container, {
875
+ schemaVersion: 1,
876
+ appId: "app1",
877
+ dependencies,
878
+ cells: [createPayloadCell()],
879
+ });
880
+
881
+ expect(parseMarimoIslandApps(container)).toEqual([
882
+ {
883
+ id: "app1",
884
+ cells: [{ code: "import cowsay", output: "<div>dom</div>", idx: 0 }],
885
+ },
886
+ ]);
887
+ },
888
+ );
889
+
890
+ it("should merge dependencies from payloads belonging to the same app", () => {
891
+ for (const [cellId, dependencies] of [
892
+ ["cell-1", ["cowsay"]],
893
+ ["cell-2", ["cowsay", "rich"]],
894
+ ] as const) {
895
+ container.appendChild(createMockIslandElement({ appId: "app1", cellId }));
896
+ appendPayload(container, {
897
+ schemaVersion: 1,
898
+ appId: "app1",
899
+ dependencies,
900
+ cells: [createPayloadCell({ cellId })],
901
+ });
902
+ }
903
+
904
+ expect(
905
+ parseMarimoIslandApps(container).map((app) => app.dependencies),
906
+ ).toEqual([["cowsay", "rich"]]);
907
+ });
908
+
778
909
  it("should fall back to DOM islands for unsupported payload versions", () => {
779
910
  const island = createMockIslandElement({
780
911
  appId: "app1",
@@ -990,6 +1121,7 @@ describe("parseMarimoIslandApps", () => {
990
1121
  outputHtml: "<div>payload only</div>",
991
1122
  }),
992
1123
  ],
1124
+ dependencies: ["cowsay"],
993
1125
  });
994
1126
 
995
1127
  const result = parseMarimoIslandApps(container);
@@ -1076,6 +1208,7 @@ describe("parseMarimoIslandApps", () => {
1076
1208
  reactive: false,
1077
1209
  }),
1078
1210
  ],
1211
+ dependencies: ["cowsay"],
1079
1212
  });
1080
1213
 
1081
1214
  const result = parseMarimoIslandApps(container);
@@ -30,6 +30,8 @@ export interface MarimoIslandApp {
30
30
  * Whether cells came from a supported JSON payload instead of DOM parsing.
31
31
  */
32
32
  payloadBacked?: boolean;
33
+ /** Explicit notebook dependencies to install before starting the app. */
34
+ dependencies?: string[];
33
35
  /**
34
36
  * Cells in the app.
35
37
  */
@@ -62,6 +64,7 @@ interface MarimoIslandCell {
62
64
  interface MarimoIslandPayload {
63
65
  schemaVersion: 1;
64
66
  appId: string;
67
+ dependencies?: string[];
65
68
  cells: MarimoIslandPayloadCell[];
66
69
  }
67
70
 
@@ -235,6 +238,12 @@ function parsePayloadBackedApps({
235
238
  embed?.setAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX, idx.toString());
236
239
  }
237
240
  }
241
+ const app = apps.get(payload.appId);
242
+ if (app && payload.dependencies?.length) {
243
+ app.dependencies = [
244
+ ...new Set([...(app.dependencies ?? []), ...payload.dependencies]),
245
+ ];
246
+ }
238
247
  }
239
248
 
240
249
  // A supported payload is the runtime source for its app. Extra same-app DOM
@@ -371,6 +380,7 @@ export function parseIslandElement(
371
380
 
372
381
  export function createMarimoFile(app: {
373
382
  cells: { code: string; disabled?: boolean }[];
383
+ dependencies?: string[];
374
384
  }): string {
375
385
  const lines = [
376
386
  "import marimo",
@@ -402,6 +412,13 @@ export function createMarimoFile(app: {
402
412
  .join("\n"),
403
413
  ];
404
414
 
415
+ if (app.dependencies?.length) {
416
+ lines.unshift(
417
+ "# /// script",
418
+ `# dependencies = ${JSON.stringify(app.dependencies)}`,
419
+ "# ///",
420
+ );
421
+ }
405
422
  return lines.join("\n");
406
423
  }
407
424
 
@@ -507,6 +524,9 @@ function isMarimoIslandPayload(
507
524
  return (
508
525
  payload.schemaVersion === 1 &&
509
526
  typeof payload.appId === "string" &&
527
+ (payload.dependencies === undefined ||
528
+ (Array.isArray(payload.dependencies) &&
529
+ payload.dependencies.every((dep) => typeof dep === "string"))) &&
510
530
  Array.isArray(payload.cells) &&
511
531
  payload.cells.every(isMarimoIslandPayloadCell)
512
532
  );
@@ -1,10 +1,22 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import { act, renderHook } from "@testing-library/react";
2
+ import {
3
+ act,
4
+ fireEvent,
5
+ render,
6
+ renderHook,
7
+ screen,
8
+ } from "@testing-library/react";
3
9
  import { beforeEach, describe, expect, it, vi } from "vitest";
4
10
  import { useInstallPackages } from "../useInstallPackage";
11
+ import { Toast, ToastProvider, ToastViewport } from "@/components/ui/toast";
5
12
 
6
13
  const toast = vi.fn();
7
14
  const addPackage = vi.fn();
15
+ const restartKernel = vi.fn();
16
+
17
+ vi.mock("@/components/editor/actions/useRestartKernel", () => ({
18
+ useRestartKernel: () => restartKernel,
19
+ }));
8
20
 
9
21
  vi.mock("@/components/ui/use-toast", () => ({
10
22
  toast: (...args: unknown[]) => toast(...args),
@@ -20,6 +32,7 @@ describe("useInstallPackages", () => {
20
32
  beforeEach(() => {
21
33
  toast.mockClear();
22
34
  addPackage.mockClear();
35
+ restartKernel.mockClear();
23
36
  });
24
37
 
25
38
  it("batches all packages into a single install call", async () => {
@@ -109,6 +122,39 @@ describe("useInstallPackages", () => {
109
122
  );
110
123
  });
111
124
 
125
+ it("reports saved changes requiring restart without claiming installation", async () => {
126
+ addPackage.mockResolvedValue({
127
+ success: false,
128
+ error: null,
129
+ restartRequired: true,
130
+ });
131
+ const { result } = renderHook(() => useInstallPackages());
132
+ await act(async () => {
133
+ await result.current.handleInstallPackages(["boltons", "six"]);
134
+ });
135
+ expect(toast).toHaveBeenCalledTimes(1);
136
+ expect(toast).toHaveBeenCalledWith(
137
+ expect.objectContaining({
138
+ title: "Changes saved — restart required",
139
+ description: expect.stringContaining(
140
+ "Restarting clears in-memory variables",
141
+ ),
142
+ duration: Infinity,
143
+ action: expect.anything(),
144
+ }),
145
+ );
146
+ expect(toast.mock.calls[0][0].variant).not.toBe("danger");
147
+ render(
148
+ <ToastProvider>
149
+ <Toast>{toast.mock.calls[0][0].action}</Toast>
150
+ <ToastViewport />
151
+ </ToastProvider>,
152
+ );
153
+ expect(restartKernel).not.toHaveBeenCalled();
154
+ fireEvent.click(screen.getByRole("button", { name: "Restart Kernel" }));
155
+ expect(restartKernel).toHaveBeenCalledTimes(1);
156
+ });
157
+
112
158
  it("calls onSuccess after a successful install", async () => {
113
159
  addPackage.mockResolvedValue({ success: true, error: null });
114
160
  const onSuccess = vi.fn();
@@ -1,8 +1,34 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
+ import { useRestartKernel } from "@/components/editor/actions/useRestartKernel";
3
4
  import { Kbd } from "@/components/ui/kbd";
5
+ import { ToastAction } from "@/components/ui/toast";
4
6
  import { toast } from "@/components/ui/use-toast";
5
7
 
8
+ export const RESTART_REQUIRED_DESCRIPTION =
9
+ "Your dependency changes are saved. Restart the kernel to use the updated environment. Restarting clears in-memory variables.";
10
+
11
+ const RestartKernelAction = () => {
12
+ const restartKernel = useRestartKernel();
13
+ return (
14
+ <ToastAction
15
+ altText="Restart the kernel to use the updated dependencies"
16
+ onClick={restartKernel}
17
+ >
18
+ Restart Kernel
19
+ </ToastAction>
20
+ );
21
+ };
22
+
23
+ export const showPackageRestartToast = () => {
24
+ toast({
25
+ title: "Changes saved — restart required",
26
+ description: RESTART_REQUIRED_DESCRIPTION,
27
+ duration: Infinity,
28
+ action: <RestartKernelAction />,
29
+ });
30
+ };
31
+
6
32
  export const showAddPackageToast = (
7
33
  packageName: string | string[],
8
34
  error?: string | null,
@@ -3,7 +3,10 @@
3
3
  import { useState } from "react";
4
4
  import { Logger } from "@/utils/Logger";
5
5
  import { useRequestClient } from "../network/requests";
6
- import { showAddPackageToast } from "./toast-components";
6
+ import {
7
+ showAddPackageToast,
8
+ showPackageRestartToast,
9
+ } from "./toast-components";
7
10
 
8
11
  export function useInstallPackages(): {
9
12
  handleInstallPackages: (
@@ -30,7 +33,9 @@ export function useInstallPackages(): {
30
33
  // response only carries an aggregate success/error. Report a single
31
34
  // toast covering all requested packages rather than implying a
32
35
  // per-package outcome we don't actually have.
33
- if (response.success) {
36
+ if (response.restartRequired) {
37
+ showPackageRestartToast();
38
+ } else if (response.success) {
34
39
  showAddPackageToast(packages);
35
40
  } else {
36
41
  showAddPackageToast(packages, response.error);
@@ -276,6 +276,17 @@ describe("RuntimeManager", () => {
276
276
  });
277
277
 
278
278
  describe("getTerminalWsURL", () => {
279
+ it("should include dimensions in the terminal handshake", () => {
280
+ const runtime = new RuntimeManager(mockConfig);
281
+ const url = runtime.getTerminalWsURL({ rows: 30, cols: 140 });
282
+
283
+ expect(Object.fromEntries(url.searchParams)).toEqual({
284
+ access_token: "test-token",
285
+ rows: "30",
286
+ cols: "140",
287
+ });
288
+ });
289
+
279
290
  it("should return terminal WebSocket URL", () => {
280
291
  const runtime = new RuntimeManager(mockConfig);
281
292
  const url = runtime.getTerminalWsURL();