@marimo-team/islands 0.25.1-dev7 → 0.25.1

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 (291) hide show
  1. package/dist/{ConnectedDataExplorerComponent-KVhjDMSe.js → ConnectedDataExplorerComponent-C2d9ysUI.js} +8 -9
  2. package/dist/{ErrorBoundary-CMASlTBK.js → ErrorBoundary-1wHWKFoG.js} +1 -1
  3. package/dist/{ImageComparisonComponent-Dlm5aWnH.js → ImageComparisonComponent-Cpfz30OZ.js} +51 -52
  4. package/dist/{abnfDiagram-VCTEODGH-CpN0FRda.js → abnfDiagram-VCTEODGH-AFhOQTt8.js} +3 -3
  5. package/dist/{architectureDiagram-5GKGNRK7-DDyj5SRB.js → architectureDiagram-5GKGNRK7-BngksAAQ.js} +5 -5
  6. package/dist/{blockDiagram-I7D4REHJ-BbXEXJRu.js → blockDiagram-I7D4REHJ-CvBmppdy.js} +9 -9
  7. package/dist/{c4Diagram-7LVT6UL2-DcLsbQmR.js → c4Diagram-7LVT6UL2-EceL4_jH.js} +7 -7
  8. package/dist/{cells-B5-y5EY3.js → cells-Cv93oav_.js} +3 -3
  9. package/dist/{channel-B5XnTarr.js → channel-z7HZXHwv.js} +1 -1
  10. package/dist/{chat-ui-HJZsTl7o.js → chat-ui-fVyVOhYN.js} +6 -6
  11. package/dist/{chunk-4HAMMTFA-D2qv8E0X.js → chunk-4HAMMTFA-BPTTOOC5.js} +5 -5
  12. package/dist/{chunk-75Z2AOVW-5_HsvXwr.js → chunk-75Z2AOVW-C4AOleKf.js} +1 -1
  13. package/dist/{chunk-DU6HZSFF-BUgAHvnM.js → chunk-DU6HZSFF-1TwWR6gh.js} +1 -1
  14. package/dist/{chunk-F27PBJKO-DHmYWZXr.js → chunk-F27PBJKO-DMI1PBe4.js} +1 -1
  15. package/dist/{chunk-GMAD6QVW-Czynz8aA.js → chunk-GMAD6QVW-vStrMz2P.js} +3 -3
  16. package/dist/{chunk-GVQU2GXP-yQEdulRS.js → chunk-GVQU2GXP-2HwWgs4u.js} +2 -2
  17. package/dist/{chunk-IMKFNOWR-BfwTebD0.js → chunk-IMKFNOWR-UOVZuZVn.js} +5 -5
  18. package/dist/{chunk-L3NEJ4N5-DwRWnDDK.js → chunk-L3NEJ4N5-RhC7i0I2.js} +5 -5
  19. package/dist/{chunk-OSK3NFVY-BBKU_Ign.js → chunk-OSK3NFVY-CZV09N-U.js} +6 -6
  20. package/dist/{chunk-P2QGCYS3-C0iGU29N.js → chunk-P2QGCYS3-0TAWai9C.js} +1 -1
  21. package/dist/{chunk-POPQ4Y6H-BCbS3Ozc.js → chunk-POPQ4Y6H-Cc3_56GX.js} +1 -1
  22. package/dist/{chunk-PWAF6VOD-CTFCL0jI.js → chunk-PWAF6VOD-lNxB9k8z.js} +1 -1
  23. package/dist/{chunk-SHT3W25Y-BspJEJ5H.js → chunk-SHT3W25Y-CrEPyWy1.js} +7 -7
  24. package/dist/{chunk-SVP7TREG-DX3rFNTe.js → chunk-SVP7TREG-uIyyySp6.js} +2 -2
  25. package/dist/{chunk-TICWLB2K-fVF7Uujg.js → chunk-TICWLB2K-DdXM3eg6.js} +5 -5
  26. package/dist/classDiagram-ZZMXUADV-BiATbBE4.js +30 -0
  27. package/dist/classDiagram-v2-VYDZK3BY-JnH97GYw.js +30 -0
  28. package/dist/{code-visibility-mzCnOHAV.js → code-visibility-DMcT7AsU.js} +2 -2
  29. package/dist/{common-C8llK7vn.js → common-B58G5YN_.js} +6726 -6430
  30. package/dist/{cynefinDiagram-5FMLGOSQ-CFQrqzSX.js → cynefinDiagram-5FMLGOSQ-zknaAsGy.js} +3 -3
  31. package/dist/{dagre-GXQ25YYZ-xHNAUTyG.js → dagre-GXQ25YYZ-BhMOoMGJ.js} +10 -10
  32. package/dist/{data-grid-overlay-editor-BN-PsDKD.js → data-grid-overlay-editor-DUWqrgYI.js} +1 -1
  33. package/dist/{diagram-S7CK7UJ4-Bt1rPbAx.js → diagram-S7CK7UJ4-V5-Z-EDY.js} +4 -4
  34. package/dist/{diagram-UQ7AKVKN-D1sq5FoZ.js → diagram-UQ7AKVKN-qw8AjDal.js} +3 -3
  35. package/dist/{diagram-VSXAHHWV-BKpmG23x.js → diagram-VSXAHHWV-CR7BJygZ.js} +2 -2
  36. package/dist/{diagram-VX7I27RA-BMwGFVD6.js → diagram-VX7I27RA-DfuqFb1E.js} +5 -5
  37. package/dist/{diagram-Z3DM3KII--KLDR9Pl.js → diagram-Z3DM3KII-DpWwlYZB.js} +3 -3
  38. package/dist/{dist-BaHjhkpZ.js → dist-CcyKTBTF.js} +1 -1
  39. package/dist/{dropdown-menu-CZgjYSAh.js → dropdown-menu-CZy06LAq.js} +12 -12
  40. package/dist/{ebnfDiagram-PWID7BFC-WnG4cvSQ.js → ebnfDiagram-PWID7BFC-C20OnNMZ.js} +3 -3
  41. package/dist/{erDiagram-RLTQ6QDP-DhzKiYHc.js → erDiagram-RLTQ6QDP-DBXLWO9v.js} +12 -12
  42. package/dist/{error-entries-Bkbpx0T0.js → error-entries-DLl0XqoW.js} +1 -1
  43. package/dist/{feedback-button-BPfflWAE.js → feedback-button-BmlXbdJI.js} +4 -4
  44. package/dist/flowDiagram-HODETNUW-DL52nMkt.js +16 -0
  45. package/dist/{formats-C8rLgZT9.js → formats-Cl_67ghI.js} +1 -1
  46. package/dist/{ganttDiagram-EL5Y4UJY-DbzEBLbl.js → ganttDiagram-EL5Y4UJY-cRRaDt88.js} +2 -2
  47. package/dist/{gitGraphDiagram-WWUBYQGX-BMf0iKi1.js → gitGraphDiagram-WWUBYQGX-Pox5k9-Y.js} +2 -2
  48. package/dist/{glide-data-editor-CbZmNC6Q.js → glide-data-editor-DnxrqL3c.js} +5 -5
  49. package/dist/{globals-D7eXYEPA.js → globals-C6IYCw1c.js} +1 -1
  50. package/dist/{html-to-image-BAgJOlSW.js → html-to-image-CmkwfNkf.js} +3 -3
  51. package/dist/{infoDiagram-27XIBGKW-BagtCX_5.js → infoDiagram-27XIBGKW-ntpxMfrq.js} +2 -2
  52. package/dist/{ishikawaDiagram-5VMMS53U-DByDehYy.js → ishikawaDiagram-5VMMS53U-BllIlHE5.js} +3 -3
  53. package/dist/{journeyDiagram-3NMN7TZE-D2LcKDUO.js → journeyDiagram-3NMN7TZE-EPJDPlt0.js} +2 -2
  54. package/dist/{kanban-definition-UXKFOSKX-BxwkbBI_.js → kanban-definition-UXKFOSKX-GYtNMjtS.js} +9 -9
  55. package/dist/{katex-C6D4cX_N.js → katex-BNCmKUol.js} +983 -1120
  56. package/dist/{useNumberFormatter-BfDpa21j.js → label-BslhXqL6.js} +108 -81
  57. package/dist/{loader-D2W4oM-3.js → loader-DEZSzvma.js} +253 -248
  58. package/dist/main.js +122 -113
  59. package/dist/{mermaid-DPNuhemn.js → mermaid-Dnzoxjt1.js} +49 -49
  60. package/dist/{mhchem-DWCF06w9.js → mhchem-BEc7A1or.js} +1 -1
  61. package/dist/{mindmap-definition-YA3MSWOX-Cgvojw3y.js → mindmap-definition-YA3MSWOX-Cth76xgH.js} +11 -11
  62. package/dist/{number-overlay-editor-CJ0KuRNf.js → number-overlay-editor-BO78Sr4W.js} +1 -1
  63. package/dist/{pegDiagram-XKGWAZYB-DahHhYyN.js → pegDiagram-XKGWAZYB-Cu4uOXii.js} +3 -3
  64. package/dist/{pieDiagram-E7YTZNPT-CCtX0oCK.js → pieDiagram-E7YTZNPT-Bh3eDa9s.js} +3 -3
  65. package/dist/{process-output-zDX4jbhd.js → process-output-CYN5E-iO.js} +2 -2
  66. package/dist/{quadrantDiagram-AXDQQJYC-DftINo6g.js → quadrantDiagram-AXDQQJYC--kqzFC3w.js} +1 -1
  67. package/dist/{railroadDiagram-O6MQD6OU-Du5NsPUb.js → railroadDiagram-O6MQD6OU-DG-M6Rnc.js} +3 -3
  68. package/dist/{react-vega-5AcMW8gG.js → react-vega-ewj7q_U5.js} +1 -1
  69. package/dist/{requirementDiagram-BXWQKSXE-0pmmxL6_.js → requirementDiagram-BXWQKSXE-DCwsThh0.js} +11 -11
  70. package/dist/{reveal-component-D3YXogQI.js → reveal-component-C1yOCuj8.js} +4 -4
  71. package/dist/{sankeyDiagram-P5KCCOFB-CDKR5TJH.js → sankeyDiagram-P5KCCOFB-BdzhT0BM.js} +1 -1
  72. package/dist/{sequenceDiagram-WJ2MYXX4-DB-ChWwU.js → sequenceDiagram-WJ2MYXX4-CbXB1_PU.js} +4 -4
  73. package/dist/{spec-CAYwFeV6.js → spec-DQBRQSba.js} +123 -102
  74. package/dist/{stateDiagram-D77RDMKH-orN6AwMx.js → stateDiagram-D77RDMKH-A-Zf3Sb2.js} +13 -13
  75. package/dist/stateDiagram-v2-MP3YSRHH-D9YMnUGx.js +30 -0
  76. package/dist/style.css +1 -1
  77. package/dist/{swimlanes-42K2YHIH-BkSDcqDT.js → swimlanes-42K2YHIH-B_pMf0J4.js} +10 -10
  78. package/dist/swimlanesDiagram-VR7AAH4N-Ctgy-yGP.js +30 -0
  79. package/dist/{timeline-definition-24CTP7MA-BuqJUIRZ.js → timeline-definition-24CTP7MA-DTXFjTTM.js} +3 -3
  80. package/dist/{useDateFormatter-BRTPsUK7.js → useDateFormatter-BXQGu86d.js} +28 -49
  81. package/dist/{vega-component-CNf5gcrm.js → vega-component-tFOzgarw.js} +4 -4
  82. package/dist/{vega-embed-container-CbnTccZi.js → vega-embed-container-sSR5hAsy.js} +2 -2
  83. package/dist/{vega-loader.browser-D95WfUcj.js → vega-loader.browser-DNST6uVf.js} +2 -2
  84. package/dist/{vennDiagram-4TSXK5OY-CTUlJ2PK.js → vennDiagram-4TSXK5OY-BPHjZo0R.js} +3 -3
  85. package/dist/{wardleyDiagram-VM6X3IG4-3evLUb0M.js → wardleyDiagram-VM6X3IG4-6fTLYBuD.js} +3 -3
  86. package/dist/{xychartDiagram-S5SC5T6Z-DL2E3K8-.js → xychartDiagram-S5SC5T6Z-BYjwjrzE.js} +5 -5
  87. package/package.json +1 -2
  88. package/src/__mocks__/common.ts +3 -3
  89. package/src/__tests__/CellStatus.test.tsx +1 -1
  90. package/src/__tests__/setup.ts +7 -7
  91. package/src/components/app-config/ai-config.tsx +2 -0
  92. package/src/components/app-config/optional-features.tsx +1 -1
  93. package/src/components/chat/chat-panel.tsx +19 -8
  94. package/src/components/data-table/TableTopBar.tsx +2 -2
  95. package/src/components/data-table/__tests__/export-actions.test.tsx +662 -0
  96. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +286 -0
  97. package/src/components/data-table/charts/charts.tsx +26 -13
  98. package/src/components/data-table/column-summary/chart-spec-model.tsx +4 -4
  99. package/src/components/data-table/data-table.tsx +1 -1
  100. package/src/components/data-table/export-actions.tsx +642 -176
  101. package/src/components/data-table/schemas.ts +25 -3
  102. package/src/components/dependency-graph/elements.ts +2 -2
  103. package/src/components/editor/__tests__/package-alert.test.tsx +140 -0
  104. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +107 -0
  105. package/src/components/editor/actions/pair-with-agent.tsx +119 -0
  106. package/src/components/editor/actions/useNotebookActions.tsx +2 -1
  107. package/src/components/editor/ai/add-cell-with-ai.tsx +2 -0
  108. package/src/components/editor/ai/staged-cell-submission.ts +2 -2
  109. package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
  110. package/src/components/editor/chrome/components/contribute-snippet-button.tsx +6 -1
  111. package/src/components/editor/connections/database/as-code.ts +44 -44
  112. package/src/components/editor/connections/storage/as-code.ts +3 -3
  113. package/src/components/editor/file-tree/requesting-tree.tsx +16 -13
  114. package/src/components/editor/navigation/clipboard.ts +2 -2
  115. package/src/components/editor/notebook-cell.tsx +2 -2
  116. package/src/components/editor/output/MarimoTracebackOutput.tsx +1 -1
  117. package/src/components/editor/output/VideoOutput.tsx +1 -1
  118. package/src/components/editor/output/ansi-reduce.ts +21 -17
  119. package/src/components/editor/output/console/ConsoleOutput.tsx +3 -3
  120. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +59 -0
  121. package/src/components/editor/output/console/text-rendering.tsx +3 -1
  122. package/src/components/editor/package-alert.tsx +20 -7
  123. package/src/components/home/components.tsx +1 -0
  124. package/src/components/markdown/markdown-renderer.css +1 -1
  125. package/src/components/pages/run-page.tsx +1 -0
  126. package/src/components/slides/__tests__/minimap-actions.test.tsx +7 -7
  127. package/src/components/slides/__tests__/minimap.test.ts +12 -12
  128. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +8 -8
  129. package/src/components/static-html/__tests__/share-modal.test.tsx +154 -0
  130. package/src/components/static-html/__tests__/stage-for-publish.test.ts +111 -0
  131. package/src/components/static-html/share-modal.tsx +114 -144
  132. package/src/components/static-html/stage-for-publish.ts +56 -0
  133. package/src/components/static-html/static-banner.tsx +2 -2
  134. package/src/components/ui/links.tsx +6 -1
  135. package/src/components/ui/typography.tsx +16 -8
  136. package/src/core/ai/context/__tests__/registry.test.ts +31 -28
  137. package/src/core/ai/context/providers/cell-output.ts +8 -8
  138. package/src/core/ai/context/providers/datasource.ts +10 -7
  139. package/src/core/ai/context/providers/error.ts +7 -7
  140. package/src/core/ai/context/providers/file.ts +8 -8
  141. package/src/core/ai/context/providers/tables.ts +7 -7
  142. package/src/core/ai/context/providers/variable.ts +7 -7
  143. package/src/core/ai/context/registry.ts +18 -18
  144. package/src/core/ai/ids/ids.ts +5 -5
  145. package/src/core/ai/model-registry.ts +12 -9
  146. package/src/core/ai/staged-cells.ts +6 -6
  147. package/src/core/ai/tools/base.ts +6 -6
  148. package/src/core/ai/tools/edit-notebook-tool.ts +6 -6
  149. package/src/core/ai/tools/registry.ts +4 -4
  150. package/src/core/ai/tools/run-cells-tool.ts +7 -7
  151. package/src/core/ai/tools/sample-tool.ts +6 -6
  152. package/src/core/cells/__tests__/cells.test.ts +27 -0
  153. package/src/core/cells/cells.ts +2 -1
  154. package/src/core/codemirror/cells/debugger-decorations.ts +13 -7
  155. package/src/core/codemirror/cells/line-timing-decorations.ts +9 -9
  156. package/src/core/codemirror/cells/traceback-decorations.ts +7 -4
  157. package/src/core/codemirror/code-lens/extension.ts +13 -13
  158. package/src/core/codemirror/copilot/__tests__/language-server.test.ts +6 -6
  159. package/src/core/codemirror/copilot/__tests__/transport.test.ts +12 -12
  160. package/src/core/codemirror/copilot/language-server.ts +13 -13
  161. package/src/core/codemirror/copilot/transport.ts +1 -1
  162. package/src/core/codemirror/find-replace/search-highlight.ts +5 -5
  163. package/src/core/codemirror/go-to-definition/underline.ts +3 -3
  164. package/src/core/codemirror/keymaps/vim.ts +3 -3
  165. package/src/core/codemirror/language/languages/markdown.ts +8 -8
  166. package/src/core/codemirror/language/languages/python.ts +7 -7
  167. package/src/core/codemirror/language/languages/sql/completion-builder.ts +5 -5
  168. package/src/core/codemirror/language/languages/sql/completion-store.ts +4 -4
  169. package/src/core/codemirror/language/languages/sql/sql.ts +21 -21
  170. package/src/core/codemirror/lsp/__tests__/transports.test.ts +10 -10
  171. package/src/core/codemirror/lsp/federated-lsp.ts +29 -27
  172. package/src/core/codemirror/lsp/notebook-lsp.ts +21 -21
  173. package/src/core/codemirror/misc/__tests__/dnd.test.ts +10 -10
  174. package/src/core/codemirror/misc/__tests__/paste.test.ts +7 -4
  175. package/src/core/codemirror/reactive-references/extension.ts +3 -3
  176. package/src/core/codemirror/rtc/loro/awareness.ts +12 -12
  177. package/src/core/codemirror/rtc/loro/sync.ts +5 -5
  178. package/src/core/codemirror/vim/cursor-visibility.ts +3 -3
  179. package/src/core/dom/ui-element.ts +5 -5
  180. package/src/core/dom/uiregistry.ts +10 -10
  181. package/src/core/hotkeys/hotkeys.ts +9 -9
  182. package/src/core/islands/__tests__/bridge.test.ts +4 -4
  183. package/src/core/islands/__tests__/test-utils.tsx +4 -4
  184. package/src/core/islands/bridge.ts +85 -82
  185. package/src/core/islands/components/web-components.tsx +7 -7
  186. package/src/core/islands/worker/__tests__/controller.test.ts +1 -1
  187. package/src/core/islands/worker/controller.ts +6 -3
  188. package/src/core/islands/worker-factory.ts +2 -2
  189. package/src/core/kernel/RuntimeState.ts +4 -4
  190. package/src/core/lsp/__tests__/transport.test.ts +19 -19
  191. package/src/core/lsp/transport.ts +5 -5
  192. package/src/core/network/CachingRequestRegistry.ts +2 -2
  193. package/src/core/network/DeferredRequestRegistry.ts +4 -4
  194. package/src/core/network/__tests__/export-asset-url.test.ts +45 -0
  195. package/src/core/network/export-asset-url.ts +19 -0
  196. package/src/core/network/requests-network.ts +2 -7
  197. package/src/core/runtime/runtime.ts +25 -20
  198. package/src/core/static/virtual-file-tracker.ts +5 -5
  199. package/src/core/wasm/__tests__/bridge.test.ts +2 -2
  200. package/src/core/wasm/bridge.ts +132 -133
  201. package/src/core/wasm/router.ts +5 -5
  202. package/src/core/wasm/store.ts +4 -4
  203. package/src/core/wasm/worker/bootstrap.ts +8 -5
  204. package/src/core/wasm/worker/message-buffer.ts +3 -3
  205. package/src/core/websocket/transports/__tests__/ws.test.ts +8 -8
  206. package/src/core/websocket/transports/basic.ts +15 -8
  207. package/src/core/websocket/transports/sse.ts +7 -7
  208. package/src/core/websocket/transports/transport.ts +3 -3
  209. package/src/core/websocket/transports/ws.ts +9 -7
  210. package/src/css/globals.css +18 -21
  211. package/src/css/katex.min.css +260 -241
  212. package/src/hooks/__tests__/useOverflowDetection.test.tsx +5 -5
  213. package/src/hooks/__tests__/useResizeObserver.test.tsx +12 -12
  214. package/src/plugins/core/registerReactComponent.tsx +5 -5
  215. package/src/plugins/core/sidebar-element.tsx +2 -2
  216. package/src/plugins/impl/ButtonPlugin.tsx +3 -3
  217. package/src/plugins/impl/CheckboxPlugin.tsx +3 -3
  218. package/src/plugins/impl/CodeEditorPlugin.tsx +3 -3
  219. package/src/plugins/impl/DatePickerPlugin.tsx +3 -3
  220. package/src/plugins/impl/DateRangePlugin.tsx +3 -3
  221. package/src/plugins/impl/DateTimePickerPlugin.tsx +3 -3
  222. package/src/plugins/impl/DictPlugin.tsx +3 -3
  223. package/src/plugins/impl/DropdownPlugin.tsx +3 -3
  224. package/src/plugins/impl/FileUploadPlugin.tsx +3 -3
  225. package/src/plugins/impl/MatrixPlugin.tsx +4 -4
  226. package/src/plugins/impl/MicrophonePlugin.tsx +3 -3
  227. package/src/plugins/impl/MultiselectPlugin.tsx +3 -3
  228. package/src/plugins/impl/NumberPlugin.tsx +3 -3
  229. package/src/plugins/impl/RadioPlugin.tsx +9 -5
  230. package/src/plugins/impl/RangeSliderPlugin.tsx +3 -3
  231. package/src/plugins/impl/RefreshPlugin.tsx +3 -3
  232. package/src/plugins/impl/SliderPlugin.tsx +3 -3
  233. package/src/plugins/impl/SwitchPlugin.tsx +3 -3
  234. package/src/plugins/impl/TabsPlugin.tsx +3 -3
  235. package/src/plugins/impl/TextAreaPlugin.tsx +3 -3
  236. package/src/plugins/impl/TextInputPlugin.tsx +3 -3
  237. package/src/plugins/impl/__tests__/MatrixPlugin.test.tsx +2 -2
  238. package/src/plugins/impl/anywidget/model.ts +10 -10
  239. package/src/plugins/impl/anywidget/registry.ts +12 -9
  240. package/src/plugins/impl/anywidget/runtime.ts +11 -9
  241. package/src/plugins/impl/anywidget/widget-binding.ts +6 -6
  242. package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +7 -6
  243. package/src/plugins/impl/matplotlib/MatplotlibPlugin.tsx +3 -3
  244. package/src/plugins/impl/matplotlib/__tests__/matplotlib-renderer.test.ts +2 -2
  245. package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +2 -2
  246. package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +10 -10
  247. package/src/plugins/impl/panel/utils.ts +5 -5
  248. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
  249. package/src/plugins/impl/vega/VegaPlugin.tsx +3 -3
  250. package/src/plugins/impl/vega/__tests__/use-vega-container-remeasure.test.ts +7 -7
  251. package/src/plugins/impl/vega/__tests__/utils.test.ts +16 -1
  252. package/src/plugins/impl/vega/__tests__/vega.test.ts +37 -0
  253. package/src/plugins/impl/vega/loader.ts +23 -1
  254. package/src/plugins/impl/vega/utils.ts +5 -4
  255. package/src/plugins/layout/AccordionPlugin.tsx +3 -3
  256. package/src/plugins/layout/CalloutPlugin.tsx +3 -3
  257. package/src/plugins/layout/ImageComparisonPlugin.tsx +5 -3
  258. package/src/plugins/layout/JsonOutputPlugin.tsx +3 -3
  259. package/src/plugins/layout/MimeRenderPlugin.tsx +3 -3
  260. package/src/plugins/layout/NavigationMenuPlugin.tsx +3 -3
  261. package/src/plugins/layout/OutlinePlugin.tsx +3 -3
  262. package/src/plugins/layout/ProgressPlugin.tsx +3 -3
  263. package/src/plugins/layout/RoutesPlugin.tsx +6 -8
  264. package/src/plugins/layout/StatPlugin.tsx +3 -3
  265. package/src/plugins/layout/TexPlugin.tsx +3 -3
  266. package/src/plugins/layout/carousel/CarouselPlugin.tsx +4 -4
  267. package/src/plugins/layout/mermaid/MermaidPlugin.tsx +3 -3
  268. package/src/utils/Deferred.ts +6 -6
  269. package/src/utils/async-capture-tracker.ts +10 -7
  270. package/src/utils/errors.ts +5 -5
  271. package/src/utils/id-tree.tsx +83 -80
  272. package/src/utils/lru.ts +1 -1
  273. package/src/utils/multi-map.ts +14 -12
  274. package/src/utils/paths.ts +6 -6
  275. package/src/utils/pluralize.ts +3 -3
  276. package/src/utils/progress.ts +6 -6
  277. package/src/utils/python-poet/poet.ts +14 -14
  278. package/src/utils/routes.ts +4 -2
  279. package/src/utils/semaphore.ts +6 -6
  280. package/src/utils/storage/storage.ts +6 -6
  281. package/src/utils/storage/typed.ts +16 -12
  282. package/src/utils/time.ts +9 -9
  283. package/src/utils/timed-cache.ts +4 -4
  284. package/src/utils/tracer.ts +9 -6
  285. package/dist/classDiagram-ZZMXUADV-Fe-V14Sc.js +0 -30
  286. package/dist/classDiagram-v2-VYDZK3BY-xTDg7lOs.js +0 -30
  287. package/dist/flowDiagram-HODETNUW-6dMdB8pR.js +0 -16
  288. package/dist/katex-DFBiSucW.js +0 -21840
  289. package/dist/label-BJ49YTvk.js +0 -30
  290. package/dist/stateDiagram-v2-MP3YSRHH-o05_rJN8.js +0 -30
  291. package/dist/swimlanesDiagram-VR7AAH4N-D_nFQfRc.js +0 -30
@@ -0,0 +1,286 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render, waitFor } from "@testing-library/react";
4
+ import { createStore, Provider } from "jotai";
5
+ import { Tooltip } from "radix-ui";
6
+ import type { ComponentProps } from "react";
7
+ import { beforeAll, describe, expect, it, vi } from "vitest";
8
+ import { SetupMocks } from "@/__mocks__/common";
9
+ import { cellId } from "@/__tests__/branded";
10
+ import { LazyVegaEmbed } from "@/components/charts/lazy";
11
+ import { vegaLoader } from "@/plugins/impl/vega/loader";
12
+ import { ChartPanel, TablePanel, type TablePanelProps } from "../charts";
13
+ import { getChartTabName, tabsStorageAtom } from "../storage";
14
+ import { ChartType, NONE_VALUE } from "../types";
15
+
16
+ vi.mock("@/components/charts/lazy", () => ({
17
+ LazyVegaEmbed: vi.fn(() => null),
18
+ }));
19
+
20
+ beforeAll(() => {
21
+ SetupMocks.resizeObserver();
22
+ });
23
+
24
+ describe("ChartPanel", () => {
25
+ it.each([undefined, null, []] as const)(
26
+ "infers the full CSV through TablePanel without backend metadata (%s)",
27
+ async (fieldTypes) => {
28
+ vi.spyOn(vegaLoader, "load").mockResolvedValue(
29
+ "value,index\n,0\n2.5,1\n",
30
+ );
31
+ const store = createStore();
32
+ const id = cellId("csv-inference");
33
+ const tabName = getChartTabName(0, ChartType.BAR);
34
+ store.set(
35
+ tabsStorageAtom,
36
+ new Map([
37
+ [
38
+ id,
39
+ [
40
+ {
41
+ tabName,
42
+ chartType: ChartType.BAR,
43
+ config: {
44
+ general: {
45
+ xColumn: { field: "value", type: "number" },
46
+ yColumn: {
47
+ field: "index",
48
+ type: "integer",
49
+ aggregate: NONE_VALUE,
50
+ },
51
+ },
52
+ },
53
+ },
54
+ ],
55
+ ],
56
+ ]),
57
+ );
58
+ const sample = [{ value: null }];
59
+ const SampleTable = (_props: { data: typeof sample }) => null;
60
+ const props: TablePanelProps = {
61
+ cellId: id,
62
+ data: sample,
63
+ dataTable: <SampleTable data={sample} />,
64
+ totalRows: 2,
65
+ columns: 1,
66
+ displayHeader: true,
67
+ fieldTypes: fieldTypes == null ? fieldTypes : [...fieldTypes],
68
+ rowHeaders: [["index", ["integer", "int64"]]],
69
+ getDataUrl: vi
70
+ .fn()
71
+ .mockResolvedValue({ data_url: "chart.csv", format: "csv" }),
72
+ };
73
+ const { getByRole } = render(
74
+ <Provider store={store}>
75
+ <Tooltip.Provider>
76
+ <TablePanel {...props} />
77
+ </Tooltip.Provider>
78
+ </Provider>,
79
+ );
80
+ fireEvent.click(getByRole("tab", { name: tabName }));
81
+ await waitFor(() => {
82
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
83
+ expect.objectContaining({
84
+ data: {
85
+ values: [
86
+ { value: null, index: 0 },
87
+ { value: 2.5, index: 1 },
88
+ ],
89
+ },
90
+ }),
91
+ );
92
+ });
93
+ },
94
+ );
95
+
96
+ it("reloads CSV only when column types change, not their array identity", async () => {
97
+ vi.spyOn(vegaLoader, "load").mockResolvedValue("value\n001\n");
98
+ const getDataUrl = vi.fn().mockResolvedValue({
99
+ data_url: "chart.csv",
100
+ format: "csv",
101
+ });
102
+ const props: ComponentProps<typeof ChartPanel> = {
103
+ tableData: [{ value: "001" }],
104
+ chartConfig: {
105
+ general: {
106
+ xColumn: { field: "value", type: "string" },
107
+ yColumn: { field: "value", type: "integer", aggregate: NONE_VALUE },
108
+ },
109
+ },
110
+ chartType: ChartType.BAR,
111
+ saveChart: vi.fn(),
112
+ saveChartType: vi.fn(),
113
+ getDataUrl,
114
+ isLargeDataset: false,
115
+ };
116
+ const panel = (
117
+ fieldTypes: ComponentProps<typeof ChartPanel>["fieldTypes"],
118
+ ) => (
119
+ <Tooltip.Provider>
120
+ <ChartPanel {...props} fieldTypes={fieldTypes} />
121
+ </Tooltip.Provider>
122
+ );
123
+ const expectValues = async (value: string | number) => {
124
+ await waitFor(() => {
125
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
126
+ expect.objectContaining({ data: { values: [{ value }] } }),
127
+ );
128
+ });
129
+ };
130
+
131
+ const { rerender } = render(panel([["value", ["string", "object"]]]));
132
+ await expectValues("001");
133
+ expect(getDataUrl).toHaveBeenCalledTimes(1);
134
+
135
+ rerender(panel([["value", ["string", "object"]]]));
136
+ await expectValues("001");
137
+ expect(getDataUrl).toHaveBeenCalledTimes(1);
138
+
139
+ rerender(panel([["value", ["integer", "int64"]]]));
140
+ await expectValues(1);
141
+ expect(getDataUrl).toHaveBeenCalledTimes(2);
142
+ });
143
+
144
+ it("uses column types to parse numeric CSV values without coercing text", async () => {
145
+ vi.spyOn(vegaLoader, "load").mockResolvedValue(
146
+ "a.b,n,label,day,timestamp,active,duration\ninf,1,inf,2024-01-01,2024-01-01T12:00:00Z,True,1 days\n-inf,2,001,2024-01-02,2024-01-02T12:00:00Z,False,2 days\n2.5,3,2024-01-03,2024-01-03,2024-01-03T12:00:00Z,True,3 days\n,4,,,,,\n",
147
+ );
148
+
149
+ render(
150
+ <Tooltip.Provider>
151
+ <ChartPanel
152
+ tableData={[{ "a.b": 1, n: 1 }]}
153
+ chartConfig={{
154
+ general: {
155
+ xColumn: { field: "a.b", type: "number" },
156
+ yColumn: { field: "n", type: "integer", aggregate: NONE_VALUE },
157
+ },
158
+ }}
159
+ chartType={ChartType.BAR}
160
+ saveChart={vi.fn()}
161
+ saveChartType={vi.fn()}
162
+ getDataUrl={vi.fn().mockResolvedValue({
163
+ data_url: "chart.csv",
164
+ format: "csv",
165
+ })}
166
+ fieldTypes={[
167
+ ["a.b", ["number", "float64"]],
168
+ ["n", ["integer", "int64"]],
169
+ ["label", ["string", "object"]],
170
+ ["day", ["date", "date"]],
171
+ ["timestamp", ["datetime", "datetime64[ns]"]],
172
+ ["active", ["boolean", "bool"]],
173
+ ["duration", ["unknown", "timedelta64[ns]"]],
174
+ ]}
175
+ isLargeDataset={false}
176
+ />
177
+ </Tooltip.Provider>,
178
+ );
179
+
180
+ await waitFor(() => {
181
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
182
+ expect.objectContaining({
183
+ data: {
184
+ values: [
185
+ {
186
+ "a.b": Infinity,
187
+ n: 1,
188
+ label: "inf",
189
+ day: new Date("2024-01-01"),
190
+ timestamp: new Date("2024-01-01T12:00:00Z"),
191
+ active: true,
192
+ duration: "1 days",
193
+ },
194
+ {
195
+ "a.b": -Infinity,
196
+ n: 2,
197
+ label: "001",
198
+ day: new Date("2024-01-02"),
199
+ timestamp: new Date("2024-01-02T12:00:00Z"),
200
+ active: false,
201
+ duration: "2 days",
202
+ },
203
+ {
204
+ "a.b": 2.5,
205
+ n: 3,
206
+ label: "2024-01-03",
207
+ day: new Date("2024-01-03"),
208
+ timestamp: new Date("2024-01-03T12:00:00Z"),
209
+ active: true,
210
+ duration: "3 days",
211
+ },
212
+ {
213
+ "a.b": null,
214
+ n: 4,
215
+ label: null,
216
+ day: "",
217
+ timestamp: "",
218
+ active: null,
219
+ duration: "",
220
+ },
221
+ ],
222
+ },
223
+ }),
224
+ );
225
+ });
226
+ });
227
+
228
+ it.each([true, false])(
229
+ "keeps dotted CSV columns aligned with the chart encodings (schema: %s)",
230
+ async (hasSchema) => {
231
+ vi.spyOn(vegaLoader, "load").mockResolvedValue("a.b,n\n1,1\n2,2\n3,3\n");
232
+
233
+ render(
234
+ <Tooltip.Provider>
235
+ <ChartPanel
236
+ tableData={[{ "a.b": 1, n: 1 }]}
237
+ chartConfig={{
238
+ general: {
239
+ xColumn: { field: "a.b", type: "number" },
240
+ yColumn: {
241
+ field: "n",
242
+ type: "number",
243
+ aggregate: NONE_VALUE,
244
+ },
245
+ },
246
+ }}
247
+ chartType={ChartType.BAR}
248
+ saveChart={vi.fn()}
249
+ saveChartType={vi.fn()}
250
+ getDataUrl={vi.fn().mockResolvedValue({
251
+ data_url: "chart.csv",
252
+ format: "csv",
253
+ })}
254
+ fieldTypes={
255
+ hasSchema
256
+ ? [
257
+ ["a.b", ["number", "float64"]],
258
+ ["n", ["integer", "int64"]],
259
+ ]
260
+ : undefined
261
+ }
262
+ isLargeDataset={false}
263
+ />
264
+ </Tooltip.Provider>,
265
+ );
266
+
267
+ await waitFor(() => {
268
+ expect(vi.mocked(LazyVegaEmbed).mock.lastCall?.[0].spec).toEqual(
269
+ expect.objectContaining({
270
+ data: {
271
+ values: [
272
+ { "a.b": 1, n: 1 },
273
+ { "a.b": 2, n: 2 },
274
+ { "a.b": 3, n: 3 },
275
+ ],
276
+ },
277
+ encoding: expect.objectContaining({
278
+ x: expect.objectContaining({ field: "a\\.b" }),
279
+ y: expect.objectContaining({ field: "n" }),
280
+ }),
281
+ }),
282
+ );
283
+ });
284
+ },
285
+ );
286
+ });
@@ -23,9 +23,11 @@ import { Form } from "@/components/ui/form";
23
23
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
24
24
  import type { CellId } from "@/core/cells/ids";
25
25
  import { useAsyncData } from "@/hooks/useAsyncData";
26
+ import { useDeepCompareMemoize } from "@/hooks/useDeepCompareMemoize";
26
27
  import { useDebouncedCallback } from "@/hooks/useDebounce";
27
28
  import type { GetDataUrl } from "@/plugins/impl/DataTablePlugin";
28
29
  import { vegaLoadData } from "@/plugins/impl/vega/loader";
30
+ import { getVegaFieldTypes } from "@/plugins/impl/vega/utils";
29
31
  import { useTheme } from "@/theme/useTheme";
30
32
  import { uniqueBy } from "@/utils/arrays";
31
33
  import { inferFieldTypes } from "../columns";
@@ -284,6 +286,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
284
286
  saveChart={saveChart}
285
287
  saveChartType={saveChartType}
286
288
  getDataUrl={getDataUrl}
289
+ hasSchema={Boolean(fieldTypes?.length)}
287
290
  fieldTypes={mergeIndexFields(
288
291
  fieldTypes ?? inferFieldTypes(dataTable.props.data),
289
292
  rowHeaders,
@@ -307,6 +310,7 @@ export const ChartPanel: React.FC<{
307
310
  saveChartType: (chartType: ChartType) => void;
308
311
  getDataUrl?: GetDataUrl;
309
312
  fieldTypes?: FieldTypesWithExternalType | null;
313
+ hasSchema?: boolean;
310
314
  isLargeDataset: boolean;
311
315
  }> = ({
312
316
  tableData,
@@ -316,6 +320,7 @@ export const ChartPanel: React.FC<{
316
320
  saveChartType,
317
321
  getDataUrl,
318
322
  fieldTypes,
323
+ hasSchema = Boolean(fieldTypes?.length),
319
324
  isLargeDataset,
320
325
  }) => {
321
326
  const { theme } = useTheme();
@@ -331,6 +336,8 @@ export const ChartPanel: React.FC<{
331
336
  const [renderLargeCharts, setRenderLargeCharts] = useState(!isLargeDataset);
332
337
 
333
338
  const { ref: chartContainerRef } = useResizeObserver();
339
+ // Sample-inferred types are useful for controls, but not full CSV parsing.
340
+ const csvFieldTypes = useDeepCompareMemoize(hasSchema ? fieldTypes : null);
334
341
 
335
342
  const { data, isPending, error } = useAsyncData(async () => {
336
343
  if (!getDataUrl || tableData.length === 0 || !renderLargeCharts) {
@@ -342,20 +349,26 @@ export const ChartPanel: React.FC<{
342
349
  return response.data_url;
343
350
  }
344
351
 
345
- const chartData = await vegaLoadData(
346
- response.data_url,
347
- response.format === "arrow"
348
- ? { type: "arrow" }
349
- : response.format === "json"
350
- ? { type: "json" }
351
- : { type: "csv", parse: "auto" },
352
- {
353
- replacePeriod: true,
354
- },
355
- );
356
- return chartData;
352
+ let format: Parameters<typeof vegaLoadData>[1];
353
+ if (response.format === "arrow") {
354
+ format = { type: "arrow" };
355
+ } else if (response.format === "json") {
356
+ format = { type: "json" };
357
+ } else {
358
+ format = {
359
+ type: "csv",
360
+ parse: getVegaFieldTypes(
361
+ csvFieldTypes &&
362
+ Object.fromEntries(
363
+ csvFieldTypes.map(([name, [type]]) => [name, type]),
364
+ ),
365
+ { parseDates: true },
366
+ ),
367
+ };
368
+ }
369
+ return vegaLoadData(response.data_url, format);
357
370
  // Re-run when the data table changes
358
- }, [tableData, renderLargeCharts]);
371
+ }, [tableData, renderLargeCharts, csvFieldTypes]);
359
372
 
360
373
  const formValues = form.watch();
361
374
 
@@ -137,14 +137,14 @@ export class ColumnChartSpecModel<T> {
137
137
  private legacySourceName: "data_0" | "source_0";
138
138
 
139
139
  private readonly fieldTypes: FieldTypes;
140
- readonly stats: Record<ColumnName, Partial<ColumnHeaderStats>>;
141
- readonly binValues: Record<ColumnName, BinValues>;
142
- readonly valueCounts: Record<ColumnName, ValueCounts>;
140
+ public readonly stats: Record<ColumnName, Partial<ColumnHeaderStats>>;
141
+ public readonly binValues: Record<ColumnName, BinValues>;
142
+ public readonly valueCounts: Record<ColumnName, ValueCounts>;
143
143
  private readonly opts: {
144
144
  includeCharts: boolean;
145
145
  };
146
146
 
147
- constructor(
147
+ public constructor(
148
148
  data: T[] | string,
149
149
  fieldTypes: FieldTypes,
150
150
  stats: Record<ColumnName, Partial<ColumnHeaderStats>>,
@@ -86,7 +86,7 @@ interface DataTableProps<TData> extends Partial<ExportActionProps> {
86
86
  // Pagination
87
87
  totalRows: number | TooManyRows;
88
88
  // JSON-serialized size of the currently-rendered data. Forwarded to
89
- // ExportMenu so hosts can size-gate the Export button via downloadSizeLimitAtom.
89
+ // ExportActions so hosts can size-gate the Export button via downloadSizeLimitAtom.
90
90
  sizeBytes?: number | null;
91
91
  sizeBytesIsLoading?: boolean;
92
92
  totalColumns: number;