@marimo-team/islands 0.20.5-dev8 → 0.20.5-dev87

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 (250) hide show
  1. package/dist/{Combination-Du-o_hC9.js → Combination-Dk6JxauT.js} +1 -1
  2. package/dist/{ConnectedDataExplorerComponent-DUS-zJoR.js → ConnectedDataExplorerComponent-pQ4sWAoT.js} +11 -11
  3. package/dist/{_baseIsEqual-5cAxzk6f.js → _baseIsEqual-CvgsjYoW.js} +38 -38
  4. package/dist/{_basePickBy-3JVb5wYm.js → _basePickBy-pTDW2_2A.js} +6 -6
  5. package/dist/{_baseUniq-DSSiFuIJ.js → _baseUniq-BUFhl85h.js} +1 -1
  6. package/dist/{any-language-editor-BL9o7y0_.js → any-language-editor-BIj11a2e.js} +19 -19
  7. package/dist/{architecture-7HQA4BMR-BxkNpYRp.js → architecture-7HQA4BMR-BmtmhGMc.js} +2 -2
  8. package/dist/{architectureDiagram-VXUJARFQ-DrJeyFHq.js → architectureDiagram-VXUJARFQ-Df0FNeBR.js} +14 -14
  9. package/dist/assets/__vite-browser-external-Us1ds95c.js +1 -0
  10. package/dist/assets/{worker-DUYMdbtA.js → worker-D10K3OOz.js} +2 -2
  11. package/dist/{blockDiagram-VD42YOAC-BJrP6qKc.js → blockDiagram-VD42YOAC-DszWqlLz.js} +7 -7
  12. package/dist/{button-KYalaJYu.js → button-DQpBib29.js} +24 -11
  13. package/dist/{c4Diagram-YG6GDRKO-Bo4gytQ5.js → c4Diagram-YG6GDRKO-Dyj8LoUX.js} +4 -4
  14. package/dist/{channel-IWLGkaBE.js → channel-CUFaIkTh.js} +1 -1
  15. package/dist/{check-C50jsehH.js → check-DpqPQmzz.js} +1 -1
  16. package/dist/{chunk-4F5CHEZ2-CxKDFd-t.js → chunk-4F5CHEZ2-CRwwZ2ED.js} +1 -1
  17. package/dist/{chunk-ABZYJK2D-CRwanrkd.js → chunk-ABZYJK2D-7QYXAAhe.js} +1 -1
  18. package/dist/{chunk-ATLVNIR6-CMMCMvOK.js → chunk-ATLVNIR6-pmHPAPSd.js} +1 -1
  19. package/dist/{chunk-B2363JML-e_W7KW1D.js → chunk-B2363JML-BuBMltZc.js} +1 -1
  20. package/dist/{chunk-B4BG7PRW-BNsHrGHG.js → chunk-B4BG7PRW-Dbta9cTX.js} +4 -4
  21. package/dist/{chunk-DI55MBZ5-DQeYbfMV.js → chunk-DI55MBZ5-DyKB35wC.js} +4 -4
  22. package/dist/{chunk-EXTU4WIE-CV_DQeaX.js → chunk-EXTU4WIE-BRFl4iNd.js} +1 -1
  23. package/dist/{chunk-FRFDVMJY-C7q09nvl.js → chunk-FRFDVMJY-Bk2LD5Te.js} +1 -1
  24. package/dist/{chunk-JA3XYJ7Z-Cmt--e0q.js → chunk-JA3XYJ7Z-BkrY9SdL.js} +2 -2
  25. package/dist/{chunk-JZLCHNYA-CkyMJnI9.js → chunk-JZLCHNYA-Bk_Lil-q.js} +4 -4
  26. package/dist/{chunk-N4CR4FBY-BJfHtJbD.js → chunk-N4CR4FBY-f5n6meOd.js} +5 -5
  27. package/dist/{chunk-PL6DKKU2-ChKBqnoD.js → chunk-PL6DKKU2-DiFkzMfM.js} +1 -1
  28. package/dist/{chunk-QN33PNHL-WOLIPUAJ.js → chunk-QN33PNHL-CXfJywHv.js} +1 -1
  29. package/dist/{chunk-QXUST7PY-DYuD50pU.js → chunk-QXUST7PY-D7-26sj3.js} +5 -5
  30. package/dist/{chunk-S3R3BYOJ-CsnX6RKs.js → chunk-S3R3BYOJ-BRT9vd1R.js} +3 -3
  31. package/dist/{chunk-SJTYNZTY-j6_1s5om.js → chunk-SJTYNZTY-BvVkbShU.js} +1 -1
  32. package/dist/{chunk-TCCFYFTB-DdLCbCTn.js → chunk-TCCFYFTB-DqxhgXG0.js} +31 -31
  33. package/dist/{chunk-TQ3KTPDO-CGsUIC73.js → chunk-TQ3KTPDO-CPkEruAA.js} +1 -1
  34. package/dist/{chunk-TZMSLE5B-B3eYTGCw.js → chunk-TZMSLE5B-DSfBOnzx.js} +1 -1
  35. package/dist/{chunk-UMXZTB3W--LdAK3Bv.js → chunk-UMXZTB3W-C4ypIY3V.js} +1 -1
  36. package/dist/{classDiagram-v2-WZHVMYZB-UTw37Gg8.js → classDiagram-2ON5EDUG-DphiMW3Y.js} +10 -10
  37. package/dist/{classDiagram-2ON5EDUG-C7C-oefv.js → classDiagram-v2-WZHVMYZB-BH1x5h4a.js} +10 -10
  38. package/dist/{clone-BJrS4PdE.js → clone-CEQ-pda1.js} +1 -1
  39. package/dist/{constants-D1Tbg_6B.js → constants-CytQ_3LM.js} +3 -3
  40. package/dist/{copy-oc-FcZzt.js → copy-BkBF0Xgk.js} +2 -2
  41. package/dist/{dagre-6UL2VRFP-BgsUhJrV.js → dagre-6UL2VRFP-DGEbtmgU.js} +12 -12
  42. package/dist/{dagre-CyZCGfV_.js → dagre-BVnNvbvD.js} +37 -37
  43. package/dist/{diagram-PSM6KHXK-BIUUOfKo.js → diagram-PSM6KHXK-CG_usglE.js} +15 -15
  44. package/dist/{diagram-QEK2KX5R-BFjolZQv.js → diagram-QEK2KX5R-CtGFEwzJ.js} +13 -13
  45. package/dist/{diagram-S2PKOQOG-4jfkWoZw.js → diagram-S2PKOQOG-ClKAGmbv.js} +13 -13
  46. package/dist/dist-B4MxkKHf.js +8 -0
  47. package/dist/{dist-De9X_Des.js → dist-B9EjSb9T.js} +1 -1
  48. package/dist/{dist-IW_ARJ3S.js → dist-BFxYppVR.js} +4 -4
  49. package/dist/{dist-D7ZGWV_9.js → dist-BGZ7TWS9.js} +3 -3
  50. package/dist/{dist-CwtEWuFb.js → dist-BSfYc7vq.js} +2 -2
  51. package/dist/{dist-DMS81OrU.js → dist-BUrWeMEP.js} +1 -1
  52. package/dist/dist-BYghZv6b.js +5 -0
  53. package/dist/dist-Be-uQhz5.js +6 -0
  54. package/dist/{dist-Ch_JuCvc.js → dist-BpMlUdNO.js} +3 -3
  55. package/dist/{dist-C6z8U-ms.js → dist-Bq5eYK43.js} +2 -2
  56. package/dist/{dist-BFL9TlzD.js → dist-Bq9zYwJs.js} +5 -5
  57. package/dist/{dist-7ZF--V_D.js → dist-C4K7pumm.js} +2 -2
  58. package/dist/{dist-Qjf6pcqK.js → dist-CAKwXCWI.js} +2 -2
  59. package/dist/dist-CB_xf0ju.js +5 -0
  60. package/dist/{dist-BwQHkjA9.js → dist-CDHl2i1x.js} +4 -4
  61. package/dist/dist-CK0qFAbF.js +8 -0
  62. package/dist/{dist-C4XMUaob.js → dist-CPlGUbk-.js} +2 -2
  63. package/dist/{dist-BT6_J2eq.js → dist-CSEWGuDq.js} +7 -2
  64. package/dist/dist-CYEk-qrr.js +8 -0
  65. package/dist/{dist-CYo3w-nC.js → dist-Cl5iM8xL.js} +3 -3
  66. package/dist/dist-CmKoWpMk.js +5 -0
  67. package/dist/{dist-I8MQW60_.js → dist-CseYuPtL.js} +2 -2
  68. package/dist/dist-D1nf4IQl.js +5 -0
  69. package/dist/{dist-CsqiXw7J.js → dist-D4gcY469.js} +2 -2
  70. package/dist/{dist-DUxS2paD.js → dist-D5NMgbbv.js} +2 -2
  71. package/dist/{dist-UYm1IE5s.js → dist-DERtJN02.js} +2 -2
  72. package/dist/{dist-CFToYDWO.js → dist-DEj2X26M.js} +2 -2
  73. package/dist/{dist-BuapEdlD.js → dist-DOoqn-VL.js} +70 -67
  74. package/dist/{dist-BLThQiU4.js → dist-DUretbKK.js} +2 -2
  75. package/dist/{dist-DEFZ7dnD.js → dist-D_-CGmlh.js} +2 -2
  76. package/dist/dist-Df3AcKpt.js +6 -0
  77. package/dist/dist-DgaFHt_I.js +5 -0
  78. package/dist/dist-Dk10C3ui.js +5 -0
  79. package/dist/{dist-D0f6Yrrb.js → dist-DodLQWPg.js} +1 -1
  80. package/dist/dist-DtyPVMHR.js +5 -0
  81. package/dist/{dist-Cb3cLT39.js → dist-HoZO6brh.js} +2 -2
  82. package/dist/{dist-Cqpjy6bK.js → dist-RNGn_-uD.js} +1 -1
  83. package/dist/{dist-BBcqvpvP.js → dist-Ux6dL_VB.js} +1 -1
  84. package/dist/{dist-B8Y11RWn.js → dist-WIWVvdBh.js} +2 -2
  85. package/dist/{dist-CB6qhQ8K.js → dist-gc9KgJuA.js} +1 -1
  86. package/dist/{dist-ovDpXuSB.js → dist-i-ud9aCA.js} +1 -1
  87. package/dist/dist-ko7WnHAO.js +5 -0
  88. package/dist/{dist-BTQbjEKU.js → dist-lNe4i1Nm.js} +1 -1
  89. package/dist/dist-of7gLRFK.js +8 -0
  90. package/dist/{erDiagram-Q2GNP2WA-Cq5Bz5lG.js → erDiagram-Q2GNP2WA-DPMseVVp.js} +10 -10
  91. package/dist/{error-banner-D0tXnwl4.js → error-banner-BctofTCP.js} +2 -2
  92. package/dist/{esm-BxMbHo0y.js → esm-BBkPJL8N.js} +29 -27
  93. package/dist/{flowDiagram-NV44I4VS-6WPJVFl7.js → flowDiagram-NV44I4VS-BpAIFwW7.js} +10 -10
  94. package/dist/{ganttDiagram-JELNMOA3-AfDhh9CI.js → ganttDiagram-JELNMOA3-DXYghZ9C.js} +3 -3
  95. package/dist/{gitGraph-G5XIXVHT-C0o6gecv.js → gitGraph-G5XIXVHT-ChHUSAop.js} +2 -2
  96. package/dist/{gitGraphDiagram-V2S2FVAM-BRSwuj0Q.js → gitGraphDiagram-V2S2FVAM-CBL-7g3_.js} +12 -12
  97. package/dist/{glide-data-editor-ByPNTNVG.js → glide-data-editor-DqxJOnJk.js} +63 -63
  98. package/dist/{graphlib-DZnBMcsX.js → graphlib-D18eZCT4.js} +10 -10
  99. package/dist/hasIn-B9AbGLj3.js +86 -0
  100. package/dist/{info-VBDWY6EO-Bzsods6X.js → info-VBDWY6EO-CwyXEo8E.js} +2 -2
  101. package/dist/{infoDiagram-HS3SLOUP-Cmxo6jKx.js → infoDiagram-HS3SLOUP-BXGbfBss.js} +12 -12
  102. package/dist/{isArrayLikeObject-Btu-i6_P.js → isArrayLikeObject-BrYl-ETg.js} +25 -26
  103. package/dist/{isEmpty-CZvUtYFp.js → isEmpty-C-xMag79.js} +2 -2
  104. package/dist/{isString-CBr7TEb7.js → isString-D-vNYDBA.js} +1 -1
  105. package/dist/{isSymbol-BuQsMXhk.js → isSymbol-Dyt2NSnN.js} +1 -1
  106. package/dist/{journeyDiagram-XKPGCS4Q-CKYr8cSR.js → journeyDiagram-XKPGCS4Q-D5BIjS4N.js} +3 -3
  107. package/dist/{kanban-definition-3W4ZIXB7-DVvAZzQD.js → kanban-definition-3W4ZIXB7-DhDkqxFB.js} +7 -7
  108. package/dist/{label-CV0KYhtH.js → label-BLDcDYdI.js} +6 -6
  109. package/dist/{loader-eJCvvApN.js → loader-DsE3MiYo.js} +2 -2
  110. package/dist/main.js +1673 -1163
  111. package/dist/{memoize-P1T1IGb9.js → memoize-Cs8aS5RW.js} +1 -1
  112. package/dist/merge-NuyC7LN7.js +51 -0
  113. package/dist/{mermaid-COOB_abB.js → mermaid-DkdSmFY8.js} +42 -42
  114. package/dist/{mermaid-parser.core-Cd-wu4tE.js → mermaid-parser.core-OkWZ8nr-.js} +8 -8
  115. package/dist/{min-CMDDtXJP.js → min-ECVRnCdn.js} +30 -30
  116. package/dist/{mindmap-definition-VGOIOE7T-1ExmnvYy.js → mindmap-definition-VGOIOE7T-BxQi78Vl.js} +9 -9
  117. package/dist/{now-BxlRp0OQ.js → now-BC2mX0ZT.js} +1 -1
  118. package/dist/{packet-DYOGHKS2-Bf1CvFco.js → packet-DYOGHKS2-C62XQjZh.js} +2 -2
  119. package/dist/{pie-VRWISCQL-LY_wbqji.js → pie-VRWISCQL-nfAKQJw3.js} +2 -2
  120. package/dist/{pieDiagram-ADFJNKIX-CJlIsdsU.js → pieDiagram-ADFJNKIX-DfSJXUHa.js} +13 -13
  121. package/dist/{purify.es-CyOIw8ru.js → purify.es-DGenX2XH.js} +67 -67
  122. package/dist/{quadrantDiagram-AYHSOK5B-BU78RiaH.js → quadrantDiagram-AYHSOK5B-CAcVWXc-.js} +2 -2
  123. package/dist/{radar-ZZBFDIW7-Ro3iXZCk.js → radar-ZZBFDIW7-lopS8_4j.js} +2 -2
  124. package/dist/{range-Dh0_-r8P.js → range-BKaWvVUE.js} +8 -8
  125. package/dist/reduce-CqQo8ppc.js +275 -0
  126. package/dist/{requirementDiagram-UZGBJVZJ-DACHtrFr.js → requirementDiagram-UZGBJVZJ-BU7dwzFM.js} +9 -9
  127. package/dist/{sankeyDiagram-TZEHDZUN-Bzg7_UWs.js → sankeyDiagram-TZEHDZUN-BVJnR4_b.js} +2 -2
  128. package/dist/{sequenceDiagram-WL72ISMW-agybEe9J.js → sequenceDiagram-WL72ISMW-CQcFQTwX.js} +4 -4
  129. package/dist/{slides-component-B0yK5GXP.js → slides-component-DwvL_HJi.js} +2 -2
  130. package/dist/{spec-Dq_reDGM.js → spec-CbYkiXG3.js} +5 -5
  131. package/dist/{stateDiagram-FKZM4ZOC-DehQAt8g.js → stateDiagram-FKZM4ZOC-Dx9AIGDe.js} +12 -12
  132. package/dist/{stateDiagram-v2-4FDKWEC3-8VzeREl9.js → stateDiagram-v2-4FDKWEC3-BIeUs-Ed.js} +10 -10
  133. package/dist/style.css +1 -1
  134. package/dist/{timeline-definition-IT6M3QCI-CdCfdaCF.js → timeline-definition-IT6M3QCI-D8B3p7ID.js} +2 -2
  135. package/dist/{toNumber-By7s5JC_.js → toNumber-CbZ70FdN.js} +2 -2
  136. package/dist/{toString-Ckpb50uw.js → toString-DbIAWQpF.js} +2 -2
  137. package/dist/{tooltip-CL8m4f9y.js → tooltip-SPkubVH3.js} +3 -3
  138. package/dist/{treemap-GDKQZRPO-DRxfDG65.js → treemap-GDKQZRPO-CkR-5ai2.js} +2 -2
  139. package/dist/{types-BwnzGcE4.js → types-0FB-N7AA.js} +519 -408
  140. package/dist/{uniq-cCc07Q8K.js → uniq-H2E5nMLq.js} +1 -1
  141. package/dist/{useAsyncData-B4hMFGnF.js → useAsyncData-D7-oahg5.js} +1 -1
  142. package/dist/{useDeepCompareMemoize-DuPhOXzr.js → useDeepCompareMemoize-DLS-bHHT.js} +5 -5
  143. package/dist/{useIframeCapabilities-CAt6D2EI.js → useIframeCapabilities-DFGZKWkO.js} +1 -1
  144. package/dist/{useTheme-BNYQnvu-.js → useTheme-D0rdoMBF.js} +6 -5
  145. package/dist/{vega-component-DouPy8AI.js → vega-component-D2knjGgv.js} +10 -10
  146. package/dist/{xychartDiagram-PRI3JC2R-rEm_SIsC.js → xychartDiagram-PRI3JC2R-XO8FiQjU.js} +5 -5
  147. package/package.json +9 -9
  148. package/src/__mocks__/common.ts +41 -8
  149. package/src/__mocks__/requests.ts +1 -0
  150. package/src/components/app-config/ai-config.tsx +10 -0
  151. package/src/components/chat/__tests__/useFileState.test.tsx +2 -3
  152. package/src/components/chat/acp/__tests__/context-utils.test.ts +2 -6
  153. package/src/components/datasources/components.tsx +3 -6
  154. package/src/components/datasources/datasources.tsx +8 -21
  155. package/src/components/editor/__tests__/data-attributes.test.tsx +2 -11
  156. package/src/components/editor/actions/types.ts +6 -1
  157. package/src/components/editor/actions/useNotebookActions.tsx +50 -13
  158. package/src/components/editor/cell/cell-context-menu.tsx +2 -6
  159. package/src/components/editor/chrome/types.ts +17 -0
  160. package/src/components/editor/connections/add-connection-dialog.tsx +27 -2
  161. package/src/components/editor/connections/database/__tests__/__snapshots__/as-code.test.ts.snap +105 -6
  162. package/src/components/editor/connections/database/__tests__/as-code.test.ts +101 -8
  163. package/src/components/editor/connections/database/as-code.ts +115 -25
  164. package/src/components/editor/connections/database/schemas.ts +49 -2
  165. package/src/components/editor/connections/storage/as-code.ts +1 -1
  166. package/src/components/editor/controls/command-palette.tsx +7 -0
  167. package/src/components/editor/controls/keyboard-shortcuts.tsx +3 -1
  168. package/src/components/editor/file-tree/__tests__/requesting-tree.test.ts +2 -3
  169. package/src/components/editor/file-tree/file-explorer.tsx +48 -62
  170. package/src/components/editor/file-tree/file-icons.tsx +132 -0
  171. package/src/components/editor/file-tree/file-viewer.tsx +1 -1
  172. package/src/components/editor/file-tree/tree-actions.tsx +107 -0
  173. package/src/components/editor/file-tree/types.ts +2 -96
  174. package/src/components/editor/header/filename-input.tsx +4 -1
  175. package/src/components/editor/navigation/__tests__/clipboard.test.ts +2 -4
  176. package/src/components/editor/output/console/ConsoleOutput.tsx +51 -2
  177. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +97 -16
  178. package/src/components/icons/marimo-icons.tsx +2 -2
  179. package/src/components/pages/home-page.tsx +5 -5
  180. package/src/components/storage/__tests__/storage-snippets.test.ts +253 -0
  181. package/src/components/storage/components.tsx +0 -38
  182. package/src/components/storage/storage-file-viewer.tsx +1 -1
  183. package/src/components/storage/storage-inspector.tsx +66 -51
  184. package/src/components/storage/storage-snippets.ts +67 -0
  185. package/src/components/ui/command.tsx +2 -0
  186. package/src/components/ui/links.tsx +1 -0
  187. package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +206 -0
  188. package/src/core/ai/tools/run-cells-tool.ts +75 -40
  189. package/src/core/cells/__tests__/cells.test.ts +62 -0
  190. package/src/core/cells/__tests__/session.test.ts +2 -7
  191. package/src/core/cells/cells.ts +25 -3
  192. package/src/core/cells/ids.ts +2 -1
  193. package/src/core/codemirror/compat/__tests__/jupyter.test.ts +2 -3
  194. package/src/core/codemirror/keymaps/vim.ts +32 -3
  195. package/src/core/codemirror/markdown/__tests__/commands.test.ts +2 -3
  196. package/src/core/config/__tests__/config-schema.test.ts +6 -2
  197. package/src/core/config/config-schema.ts +1 -0
  198. package/src/core/config/feature-flag.tsx +1 -1
  199. package/src/core/dom/ui-element-constants.ts +15 -0
  200. package/src/core/dom/ui-element.ts +3 -2
  201. package/src/core/export/__tests__/hooks.test.ts +3 -10
  202. package/src/core/hotkeys/__tests__/hotkeys.test.ts +64 -1
  203. package/src/core/hotkeys/hotkeys.ts +29 -3
  204. package/src/core/islands/bridge.ts +1 -0
  205. package/src/core/islands/components/web-components.tsx +2 -1
  206. package/src/core/network/__tests__/requests-network.test.ts +17 -0
  207. package/src/core/network/requests-lazy.ts +1 -0
  208. package/src/core/network/requests-network.ts +9 -0
  209. package/src/core/network/requests-static.ts +1 -0
  210. package/src/core/network/requests-toasting.tsx +1 -0
  211. package/src/core/network/types.ts +1 -0
  212. package/src/core/runtime/__tests__/runtime.test.ts +2 -8
  213. package/src/core/storage/__tests__/state.test.ts +1 -0
  214. package/src/core/wasm/bridge.ts +1 -0
  215. package/src/core/websocket/useMarimoKernelConnection.tsx +2 -0
  216. package/src/plugins/impl/DataTablePlugin.tsx +53 -3
  217. package/src/plugins/impl/FileBrowserPlugin.tsx +8 -5
  218. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +2 -11
  219. package/src/plugins/impl/__tests__/DropdownPlugin.test.tsx +2 -11
  220. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +4 -1
  221. package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +309 -0
  222. package/src/plugins/impl/mpl-interactive/__tests__/mpl-websocket-shim.test.ts +110 -0
  223. package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +57 -0
  224. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +8 -2
  225. package/src/plugins/plugins.ts +2 -0
  226. package/src/utils/__tests__/copy.test.ts +129 -0
  227. package/src/utils/__tests__/download.test.tsx +12 -14
  228. package/src/utils/__tests__/filenames.test.ts +7 -0
  229. package/src/utils/__tests__/smartMatch.test.ts +61 -0
  230. package/src/utils/copy.ts +43 -0
  231. package/src/utils/filenames.ts +3 -0
  232. package/src/utils/smartMatch.ts +62 -0
  233. package/dist/_baseProperty-D1nWkRMz.js +0 -93
  234. package/dist/assets/__vite-browser-external-WSlCcXn_.js +0 -1
  235. package/dist/dist-BAeGo2rp.js +0 -5
  236. package/dist/dist-BqwCMSEa.js +0 -5
  237. package/dist/dist-Bum8FwTO.js +0 -6
  238. package/dist/dist-C0YiOwt_.js +0 -5
  239. package/dist/dist-C2uPv4iU.js +0 -5
  240. package/dist/dist-C5hOLsJN.js +0 -8
  241. package/dist/dist-C9NIAKMs.js +0 -8
  242. package/dist/dist-CCrzTtvk.js +0 -5
  243. package/dist/dist-CFS9i1rS.js +0 -8
  244. package/dist/dist-CyHZuhPH.js +0 -5
  245. package/dist/dist-CzcjWdIk.js +0 -6
  246. package/dist/dist-DaYyUSNC.js +0 -5
  247. package/dist/dist-DpDcJYNh.js +0 -8
  248. package/dist/dist-U_BfxcPn.js +0 -5
  249. package/dist/merge-CGQkMGzr.js +0 -51
  250. package/dist/reduce-BXFHs7IQ.js +0 -268
@@ -1,105 +1,11 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import {
3
- DatabaseIcon,
4
- FileAudioIcon,
5
- FileCodeIcon,
6
- FileIcon,
7
- FileImageIcon,
8
- FileJsonIcon,
9
- FileTextIcon,
10
- FileVideo2Icon,
11
- FolderArchiveIcon,
12
- FolderIcon,
13
- type LucideIcon,
14
- } from "lucide-react";
15
2
 
16
- /* Copyright 2026 Marimo. All rights reserved. */
17
- export type FileType =
18
- | "directory"
19
- | "python"
20
- | "code"
21
- | "json"
22
- | "text"
23
- | "image"
24
- | "audio"
25
- | "video"
26
- | "data"
27
- | "pdf"
28
- | "zip"
29
- | "unknown";
30
-
31
- export function guessFileType(name: string): FileType {
32
- const ext = name.split(".").pop();
33
- if (ext === undefined) {
34
- return "unknown";
35
- }
36
- switch (ext.toLowerCase()) {
37
- case "py":
38
- return "python";
39
- case "txt":
40
- case "md":
41
- case "qmd":
42
- return "text";
43
- case "png":
44
- case "jpg":
45
- case "jpeg":
46
- case "gif":
47
- return "image";
48
- case "csv":
49
- return "data";
50
- case "json":
51
- return "json";
52
- // Non-exhaustive list of code file extensions
53
- case "js":
54
- case "ts":
55
- case "tsx":
56
- case "html":
57
- case "css":
58
- case "toml":
59
- case "yaml":
60
- case "yml":
61
- case "wasm":
62
- return "code";
63
- case "mp3":
64
- case "m4a":
65
- case "m4v":
66
- case "ogg":
67
- case "wav":
68
- return "audio";
69
- case "mp4":
70
- case "webm":
71
- case "mkv":
72
- return "video";
73
- case "pdf":
74
- return "pdf";
75
- case "zip":
76
- case "tar":
77
- case "gz":
78
- return "zip";
79
- default:
80
- return "unknown";
81
- }
82
- }
83
-
84
- export const FILE_TYPE_ICONS: Record<FileType, LucideIcon> = {
85
- directory: FolderIcon,
86
- python: FileCodeIcon,
87
- json: FileJsonIcon,
88
- code: FileCodeIcon,
89
- text: FileTextIcon,
90
- image: FileImageIcon,
91
- audio: FileAudioIcon,
92
- video: FileVideo2Icon,
93
- pdf: FileCodeIcon,
94
- zip: FolderArchiveIcon,
95
- data: DatabaseIcon,
96
- unknown: FileIcon,
97
- };
3
+ import type { FileIconType } from "@/components/editor/file-tree/file-icons";
98
4
 
99
5
  const TAB = " ";
100
6
 
101
7
  export const PYTHON_CODE_FOR_FILE_TYPE: Record<
102
- FileType,
8
+ FileIconType,
103
9
  (path: string) => string
104
10
  > = {
105
11
  directory: (path) => `os.listdir("${path}")`,
@@ -3,6 +3,10 @@
3
3
  import { PopoverAnchor } from "@radix-ui/react-popover";
4
4
  import { FilePenIcon } from "lucide-react";
5
5
  import { type JSX, useEffect, useRef, useState } from "react";
6
+ import {
7
+ FILE_ICON as FILE_TYPE_ICONS,
8
+ guessFileIconType as guessFileType,
9
+ } from "@/components/editor/file-tree/file-icons";
6
10
  import type { FileInfo } from "@/core/network/types";
7
11
  import { useAsyncData } from "@/hooks/useAsyncData";
8
12
  import { Paths } from "@/utils/paths";
@@ -15,7 +19,6 @@ import {
15
19
  CommandList,
16
20
  } from "../../ui/command";
17
21
  import { Popover, PopoverContent } from "../../ui/popover";
18
- import { FILE_TYPE_ICONS, guessFileType } from "../file-tree/types";
19
22
 
20
23
  import "./filename-input.css";
21
24
  import { getFeatureFlag } from "@/core/config/feature-flag";
@@ -3,15 +3,13 @@
3
3
 
4
4
  import { act, renderHook } from "@testing-library/react";
5
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
6
- import { asMock, Mocks, SetupMocks } from "@/__mocks__/common";
6
+ import { asMock, MockModules, Mocks, SetupMocks } from "@/__mocks__/common";
7
7
  import type { CellActions, NotebookState } from "@/core/cells/cells";
8
8
  import type { CellId } from "@/core/cells/ids";
9
9
  import { useCellClipboard } from "../clipboard";
10
10
 
11
11
  // Mock dependencies
12
- vi.mock("@/components/ui/use-toast", () => ({
13
- toast: vi.fn(),
14
- }));
12
+ vi.mock("@/components/ui/use-toast", () => MockModules.toast());
15
13
 
16
14
  vi.mock("@/core/cells/cells", () => ({
17
15
  getNotebook: vi.fn(),
@@ -6,7 +6,7 @@ import {
6
6
  ChevronsUpDownIcon,
7
7
  WrapTextIcon,
8
8
  } from "lucide-react";
9
- import React, { useLayoutEffect } from "react";
9
+ import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
10
10
  import { ToggleButton } from "react-aria-components";
11
11
  import { DebuggerControls } from "@/components/debugger/debugger-code";
12
12
  import { CopyClipboardIcon } from "@/components/icons/copy-icon";
@@ -33,6 +33,52 @@ import { useWrapText } from "../useWrapText";
33
33
  import { processOutput } from "./process-output";
34
34
  import { RenderTextWithLinks } from "./text-rendering";
35
35
 
36
+ /**
37
+ * Delay in ms before clearing console outputs.
38
+ * This prevents flickering when a cell re-runs and outputs are briefly cleared
39
+ * before new outputs arrive (e.g., plt.show() with a slider).
40
+ */
41
+ export const CONSOLE_CLEAR_DEBOUNCE_MS = 200;
42
+
43
+ /**
44
+ * Debounces the clearing of console outputs.
45
+ * - Non-empty updates are applied immediately.
46
+ * - Transitions to empty are delayed by CONSOLE_CLEAR_DEBOUNCE_MS,
47
+ * giving new outputs a chance to arrive and replace the old ones
48
+ * without a visible flicker.
49
+ */
50
+ function useDebouncedConsoleOutputs<T>(outputs: T[]): T[] {
51
+ const [debouncedOutputs, setDebouncedOutputs] = useState(outputs);
52
+ const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
53
+
54
+ // Non-empty outputs: apply immediately and cancel any pending clear
55
+ if (outputs.length > 0 && debouncedOutputs !== outputs) {
56
+ if (timerRef.current !== null) {
57
+ clearTimeout(timerRef.current);
58
+ timerRef.current = null;
59
+ }
60
+ setDebouncedOutputs(outputs);
61
+ }
62
+
63
+ // Empty outputs: delay the clear so new outputs can arrive first
64
+ useEffect(() => {
65
+ if (outputs.length === 0 && timerRef.current === null) {
66
+ timerRef.current = setTimeout(() => {
67
+ timerRef.current = null;
68
+ setDebouncedOutputs([]);
69
+ }, CONSOLE_CLEAR_DEBOUNCE_MS);
70
+ }
71
+ return () => {
72
+ if (timerRef.current !== null) {
73
+ clearTimeout(timerRef.current);
74
+ timerRef.current = null;
75
+ }
76
+ };
77
+ }, [outputs]);
78
+
79
+ return debouncedOutputs;
80
+ }
81
+
36
82
  interface Props {
37
83
  cellId: CellId;
38
84
  cellName: string;
@@ -63,7 +109,7 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
63
109
  setValue: setStdinValue,
64
110
  });
65
111
  const {
66
- consoleOutputs,
112
+ consoleOutputs: rawConsoleOutputs,
67
113
  stale,
68
114
  cellName,
69
115
  cellId,
@@ -73,6 +119,9 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
73
119
  className,
74
120
  } = props;
75
121
 
122
+ // Debounce clearing to prevent flickering when cells re-run
123
+ const consoleOutputs = useDebouncedConsoleOutputs(rawConsoleOutputs);
124
+
76
125
  /* The debugger UI needs some work. For now just use the regular
77
126
  /* console output. */
78
127
  /* if (debuggerActive) {
@@ -1,25 +1,15 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { fireEvent, render, screen } from "@testing-library/react";
4
- import { describe, expect, it, vi } from "vitest";
3
+ import { act, fireEvent, render, screen } from "@testing-library/react";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { SetupMocks } from "@/__mocks__/common";
5
6
  import { TooltipProvider } from "@/components/ui/tooltip";
6
7
  import type { CellId } from "@/core/cells/ids";
7
8
  import type { WithResponse } from "@/core/cells/types";
8
9
  import type { OutputMessage } from "@/core/kernel/messages";
9
- import { ConsoleOutput } from "../ConsoleOutput";
10
-
11
- // Mock ResizeObserver for tests
12
- global.ResizeObserver = class ResizeObserver {
13
- observe() {
14
- // noop
15
- }
16
- unobserve() {
17
- // noop
18
- }
19
- disconnect() {
20
- // noop
21
- }
22
- };
10
+ import { CONSOLE_CLEAR_DEBOUNCE_MS, ConsoleOutput } from "../ConsoleOutput";
11
+
12
+ SetupMocks.resizeObserver();
23
13
 
24
14
  const renderWithProvider = (ui: React.ReactElement) => {
25
15
  return render(<TooltipProvider>{ui}</TooltipProvider>);
@@ -203,3 +193,94 @@ describe("ConsoleOutput pdb history", () => {
203
193
  expect(input).toHaveValue("");
204
194
  });
205
195
  });
196
+
197
+ describe("ConsoleOutput debounced clearing", () => {
198
+ beforeEach(() => {
199
+ vi.useFakeTimers();
200
+ });
201
+
202
+ afterEach(() => {
203
+ vi.useRealTimers();
204
+ });
205
+
206
+ const createOutput = (
207
+ data: string,
208
+ channel = "stdout",
209
+ ): WithResponse<OutputMessage> => ({
210
+ channel: channel as "stdout" | "stderr",
211
+ mimetype: "text/plain",
212
+ data,
213
+ timestamp: 0,
214
+ response: undefined,
215
+ });
216
+
217
+ const defaultProps = {
218
+ cellId: "cell-1" as CellId,
219
+ cellName: "test_cell",
220
+ consoleOutputs: [] as WithResponse<OutputMessage>[],
221
+ stale: false,
222
+ debuggerActive: false,
223
+ onSubmitDebugger: vi.fn(),
224
+ };
225
+
226
+ it("should keep old outputs visible when cleared, then show new outputs immediately", () => {
227
+ const outputs1 = [createOutput("hello world")];
228
+
229
+ const { rerender } = renderWithProvider(
230
+ <ConsoleOutput {...defaultProps} consoleOutputs={outputs1} />,
231
+ );
232
+
233
+ // Old output is visible
234
+ expect(screen.getByText("hello world")).toBeInTheDocument();
235
+
236
+ // Clear outputs (simulates cell re-run)
237
+ rerender(
238
+ <TooltipProvider>
239
+ <ConsoleOutput {...defaultProps} consoleOutputs={[]} />
240
+ </TooltipProvider>,
241
+ );
242
+
243
+ // Old output should still be visible during debounce period
244
+ expect(screen.getByText("hello world")).toBeInTheDocument();
245
+
246
+ // New outputs arrive before debounce fires
247
+ const outputs2 = [createOutput("new output")];
248
+ rerender(
249
+ <TooltipProvider>
250
+ <ConsoleOutput {...defaultProps} consoleOutputs={outputs2} />
251
+ </TooltipProvider>,
252
+ );
253
+
254
+ // New output should be shown immediately
255
+ expect(screen.getByText("new output")).toBeInTheDocument();
256
+ expect(screen.queryByText("hello world")).not.toBeInTheDocument();
257
+ });
258
+
259
+ it("should clear outputs after debounce period if no new outputs arrive", () => {
260
+ const outputs1 = [createOutput("old output")];
261
+
262
+ const { rerender } = renderWithProvider(
263
+ <ConsoleOutput {...defaultProps} consoleOutputs={outputs1} />,
264
+ );
265
+
266
+ expect(screen.getByText("old output")).toBeInTheDocument();
267
+
268
+ // Clear outputs
269
+ rerender(
270
+ <TooltipProvider>
271
+ <ConsoleOutput {...defaultProps} consoleOutputs={[]} />
272
+ </TooltipProvider>,
273
+ );
274
+
275
+ // Still visible during debounce
276
+ expect(screen.getByText("old output")).toBeInTheDocument();
277
+
278
+ // Advance past debounce period
279
+ act(() => {
280
+ vi.advanceTimersByTime(CONSOLE_CLEAR_DEBOUNCE_MS + 1);
281
+ });
282
+
283
+ // Now the output should be cleared
284
+ expect(screen.queryByText("old output")).not.toBeInTheDocument();
285
+ });
286
+ });
@@ -81,9 +81,9 @@ export const MarimoIcon = ({
81
81
  width={width ?? size}
82
82
  height={height ?? size}
83
83
  viewBox={viewBox}
84
+ aria-hidden={true}
84
85
  {...props}
85
86
  >
86
- <title>marimo icon</title>
87
87
  <MarimoCirclePaths
88
88
  fill={fill}
89
89
  stroke={stroke ?? "currentColor"}
@@ -119,9 +119,9 @@ const MarimoMultiIcon = ({
119
119
  width={width ?? size}
120
120
  height={height ?? size}
121
121
  viewBox={viewBox}
122
+ aria-hidden={true}
122
123
  {...props}
123
124
  >
124
- <title>marimo multi icon</title>
125
125
  <defs>
126
126
  <mask id={maskId}>
127
127
  <rect width="100%" height="100%" fill="white" />
@@ -23,6 +23,11 @@ import {
23
23
  } from "react-arborist";
24
24
  import { useLocale } from "react-aria";
25
25
  import { MarkdownIcon } from "@/components/editor/cell/code/icons";
26
+ import {
27
+ FILE_ICON as FILE_TYPE_ICONS,
28
+ type FileIconType as FileType,
29
+ guessFileIconType as guessFileType,
30
+ } from "@/components/editor/file-tree/file-icons";
26
31
  import { useImperativeModal } from "@/components/modal/ImperativeModal";
27
32
  import { AlertDialogDestructiveAction } from "@/components/ui/alert-dialog";
28
33
  import { Button } from "@/components/ui/button";
@@ -47,11 +52,6 @@ import { newNotebookURL } from "@/utils/urls";
47
52
  import { ConfigButton } from "../app-config/app-config-button";
48
53
  import { ErrorBoundary } from "../editor/boundary/ErrorBoundary";
49
54
  import { ShutdownButton } from "../editor/controls/shutdown-button";
50
- import {
51
- FILE_TYPE_ICONS,
52
- type FileType,
53
- guessFileType,
54
- } from "../editor/file-tree/types";
55
55
  import {
56
56
  Header,
57
57
  OpenTutorialDropDown,
@@ -0,0 +1,253 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { describe, expect, it } from "vitest";
3
+ import {
4
+ STORAGE_SNIPPETS,
5
+ type StorageSnippetContext,
6
+ } from "../storage-snippets";
7
+
8
+ const readSnippet = STORAGE_SNIPPETS.find((s) => s.id === "read-file")!;
9
+ const downloadSnippet = STORAGE_SNIPPETS.find((s) => s.id === "download-file")!;
10
+
11
+ function makeCtx(
12
+ overrides: Partial<StorageSnippetContext> = {},
13
+ ): StorageSnippetContext {
14
+ return {
15
+ variableName: "store",
16
+ protocol: "s3",
17
+ entry: {
18
+ path: "data/file.csv",
19
+ kind: "object",
20
+ size: 1024,
21
+ lastModified: null,
22
+ },
23
+ backendType: "obstore",
24
+ ...overrides,
25
+ };
26
+ }
27
+
28
+ describe("read-file snippet", () => {
29
+ it("obstore backend", () => {
30
+ expect(readSnippet.getCode(makeCtx())).toMatchInlineSnapshot(`
31
+ "_data = store.get("data/file.csv").bytes()
32
+ _data"
33
+ `);
34
+ });
35
+
36
+ it("fsspec backend", () => {
37
+ expect(
38
+ readSnippet.getCode(
39
+ makeCtx({ backendType: "fsspec", variableName: "fs" }),
40
+ ),
41
+ ).toMatchInlineSnapshot(`
42
+ "_data = fs.cat_file("data/file.csv")
43
+ _data"
44
+ `);
45
+ });
46
+
47
+ it("returns null for directories", () => {
48
+ expect(
49
+ readSnippet.getCode(
50
+ makeCtx({
51
+ entry: {
52
+ path: "data/",
53
+ kind: "directory",
54
+ size: 0,
55
+ lastModified: null,
56
+ },
57
+ }),
58
+ ),
59
+ ).toBeNull();
60
+ });
61
+
62
+ it("escapes double quotes in paths", () => {
63
+ expect(
64
+ readSnippet.getCode(
65
+ makeCtx({
66
+ entry: {
67
+ path: 'data/"file".csv',
68
+ kind: "object",
69
+ size: 100,
70
+ lastModified: null,
71
+ },
72
+ }),
73
+ ),
74
+ ).toMatchInlineSnapshot(`
75
+ "_data = store.get("data/\\"file\\".csv").bytes()
76
+ _data"
77
+ `);
78
+ });
79
+
80
+ it("escapes backslashes in paths", () => {
81
+ expect(
82
+ readSnippet.getCode(
83
+ makeCtx({
84
+ entry: {
85
+ path: "data\\file.csv",
86
+ kind: "object",
87
+ size: 100,
88
+ lastModified: null,
89
+ },
90
+ }),
91
+ ),
92
+ ).toMatchInlineSnapshot(`
93
+ "_data = store.get("data\\\\file.csv").bytes()
94
+ _data"
95
+ `);
96
+ });
97
+
98
+ it("escapes newlines and tabs in paths", () => {
99
+ expect(
100
+ readSnippet.getCode(
101
+ makeCtx({
102
+ entry: {
103
+ path: "data/file\nname\there.csv",
104
+ kind: "object",
105
+ size: 100,
106
+ lastModified: null,
107
+ },
108
+ }),
109
+ ),
110
+ ).toMatchInlineSnapshot(`
111
+ "_data = store.get("data/file\\nname\\there.csv").bytes()
112
+ _data"
113
+ `);
114
+ });
115
+
116
+ it("escapes control characters in paths", () => {
117
+ expect(
118
+ readSnippet.getCode(
119
+ makeCtx({
120
+ entry: {
121
+ path: "data/\u0000\u001F.csv",
122
+ kind: "object",
123
+ size: 100,
124
+ lastModified: null,
125
+ },
126
+ }),
127
+ ),
128
+ ).toMatchInlineSnapshot(`
129
+ "_data = store.get("data/\\u0000\\u001f.csv").bytes()
130
+ _data"
131
+ `);
132
+ });
133
+ });
134
+
135
+ describe("download-file snippet", () => {
136
+ it("obstore s3 backend", () => {
137
+ expect(downloadSnippet.getCode(makeCtx())).toMatchInlineSnapshot(`
138
+ "from datetime import timedelta
139
+ from obstore import sign
140
+
141
+ signed_url = sign(
142
+ store, "GET", "data/file.csv",
143
+ expires_in=timedelta(hours=1),
144
+ )
145
+ signed_url"
146
+ `);
147
+ });
148
+
149
+ it("obstore gcs backend", () => {
150
+ expect(
151
+ downloadSnippet.getCode(makeCtx({ protocol: "gcs" })),
152
+ ).toMatchInlineSnapshot(`
153
+ "from datetime import timedelta
154
+ from obstore import sign
155
+
156
+ signed_url = sign(
157
+ store, "GET", "data/file.csv",
158
+ expires_in=timedelta(hours=1),
159
+ )
160
+ signed_url"
161
+ `);
162
+ });
163
+
164
+ it("obstore cloudflare backend", () => {
165
+ expect(
166
+ downloadSnippet.getCode(makeCtx({ protocol: "cloudflare" })),
167
+ ).toMatchInlineSnapshot(`
168
+ "from datetime import timedelta
169
+ from obstore import sign
170
+
171
+ signed_url = sign(
172
+ store, "GET", "data/file.csv",
173
+ expires_in=timedelta(hours=1),
174
+ )
175
+ signed_url"
176
+ `);
177
+ });
178
+
179
+ it("returns null for http obstore (not signable)", () => {
180
+ expect(downloadSnippet.getCode(makeCtx({ protocol: "http" }))).toBeNull();
181
+ });
182
+
183
+ it("returns null for file obstore (not signable)", () => {
184
+ expect(downloadSnippet.getCode(makeCtx({ protocol: "file" }))).toBeNull();
185
+ });
186
+
187
+ it("returns null for in-memory obstore (not signable)", () => {
188
+ expect(
189
+ downloadSnippet.getCode(makeCtx({ protocol: "in-memory" })),
190
+ ).toBeNull();
191
+ });
192
+
193
+ it("fsspec backend", () => {
194
+ expect(
195
+ downloadSnippet.getCode(
196
+ makeCtx({ backendType: "fsspec", variableName: "fs" }),
197
+ ),
198
+ ).toMatchInlineSnapshot(`"fs.get("data/file.csv", "file.csv")"`);
199
+ });
200
+
201
+ it("fsspec backend with nested path", () => {
202
+ expect(
203
+ downloadSnippet.getCode(
204
+ makeCtx({
205
+ backendType: "fsspec",
206
+ variableName: "fs",
207
+ entry: {
208
+ path: "nested/dir/report.parquet",
209
+ kind: "file",
210
+ size: 500,
211
+ lastModified: null,
212
+ },
213
+ }),
214
+ ),
215
+ ).toMatchInlineSnapshot(
216
+ `"fs.get("nested/dir/report.parquet", "report.parquet")"`,
217
+ );
218
+ });
219
+
220
+ it("returns null for directories", () => {
221
+ expect(
222
+ downloadSnippet.getCode(
223
+ makeCtx({
224
+ entry: {
225
+ path: "data/",
226
+ kind: "directory",
227
+ size: 0,
228
+ lastModified: null,
229
+ },
230
+ }),
231
+ ),
232
+ ).toBeNull();
233
+ });
234
+ });
235
+
236
+ describe("all snippets return null for directories", () => {
237
+ for (const snippet of STORAGE_SNIPPETS) {
238
+ it(`${snippet.id} returns null for directory entries`, () => {
239
+ expect(
240
+ snippet.getCode(
241
+ makeCtx({
242
+ entry: {
243
+ path: "some-dir/",
244
+ kind: "directory",
245
+ size: 0,
246
+ lastModified: null,
247
+ },
248
+ }),
249
+ ),
250
+ ).toBeNull();
251
+ });
252
+ }
253
+ });