@marimo-team/islands 0.25.1-dev4 → 0.25.1-dev40

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 (274) hide show
  1. package/dist/{ConnectedDataExplorerComponent-KVhjDMSe.js → ConnectedDataExplorerComponent-CwMXfDQR.js} +3 -3
  2. package/dist/{ErrorBoundary-pV36lYEK.js → ErrorBoundary-CAJO-M56.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-DLSF8a04.js} +4 -4
  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-CgZS2a3W.js → code-visibility-XU9RAJNV.js} +2 -2
  29. package/dist/{common-DnMDPPaW.js → common-C0fbrgB8.js} +13 -13
  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-hHYgD_Sm.js → data-grid-overlay-editor-BnhbJgoq.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/{ebnfDiagram-PWID7BFC-WnG4cvSQ.js → ebnfDiagram-PWID7BFC-C20OnNMZ.js} +3 -3
  40. package/dist/{erDiagram-RLTQ6QDP-DhzKiYHc.js → erDiagram-RLTQ6QDP-DBXLWO9v.js} +12 -12
  41. package/dist/{error-entries-Bkbpx0T0.js → error-entries-DLl0XqoW.js} +1 -1
  42. package/dist/{feedback-button-CvKssdG_.js → feedback-button-B0QSkbSp.js} +4 -4
  43. package/dist/flowDiagram-HODETNUW-DL52nMkt.js +16 -0
  44. package/dist/{formats-C8rLgZT9.js → formats-Cl_67ghI.js} +1 -1
  45. package/dist/{ganttDiagram-EL5Y4UJY-DbzEBLbl.js → ganttDiagram-EL5Y4UJY-cRRaDt88.js} +2 -2
  46. package/dist/{gitGraphDiagram-WWUBYQGX-BMf0iKi1.js → gitGraphDiagram-WWUBYQGX-Pox5k9-Y.js} +2 -2
  47. package/dist/{glide-data-editor-Ohetlgag.js → glide-data-editor-ymIQdwrb.js} +3 -3
  48. package/dist/{globals-CPNNcOJI.js → globals-B0S3-e_D.js} +1 -1
  49. package/dist/{html-to-image-BAgJOlSW.js → html-to-image-CGVgroef.js} +2 -2
  50. package/dist/{infoDiagram-27XIBGKW-BagtCX_5.js → infoDiagram-27XIBGKW-ntpxMfrq.js} +2 -2
  51. package/dist/{ishikawaDiagram-5VMMS53U-DByDehYy.js → ishikawaDiagram-5VMMS53U-BllIlHE5.js} +3 -3
  52. package/dist/{journeyDiagram-3NMN7TZE-D2LcKDUO.js → journeyDiagram-3NMN7TZE-EPJDPlt0.js} +2 -2
  53. package/dist/{kanban-definition-UXKFOSKX-BxwkbBI_.js → kanban-definition-UXKFOSKX-GYtNMjtS.js} +9 -9
  54. package/dist/{katex-C6D4cX_N.js → katex-BNCmKUol.js} +983 -1120
  55. package/dist/{loader-D2W4oM-3.js → loader-DEZSzvma.js} +253 -248
  56. package/dist/main.js +72 -69
  57. package/dist/{mermaid-DPNuhemn.js → mermaid-Dnzoxjt1.js} +49 -49
  58. package/dist/{mhchem-DWCF06w9.js → mhchem-BEc7A1or.js} +1 -1
  59. package/dist/{mindmap-definition-YA3MSWOX-Cgvojw3y.js → mindmap-definition-YA3MSWOX-Cth76xgH.js} +11 -11
  60. package/dist/{number-overlay-editor-CHWg5gGO.js → number-overlay-editor-DB3HJDI1.js} +1 -1
  61. package/dist/{pegDiagram-XKGWAZYB-DahHhYyN.js → pegDiagram-XKGWAZYB-Cu4uOXii.js} +3 -3
  62. package/dist/{pieDiagram-E7YTZNPT-CCtX0oCK.js → pieDiagram-E7YTZNPT-Bh3eDa9s.js} +3 -3
  63. package/dist/{process-output-zDX4jbhd.js → process-output-CGfg-JmZ.js} +2 -2
  64. package/dist/{quadrantDiagram-AXDQQJYC-DftINo6g.js → quadrantDiagram-AXDQQJYC--kqzFC3w.js} +1 -1
  65. package/dist/{railroadDiagram-O6MQD6OU-Du5NsPUb.js → railroadDiagram-O6MQD6OU-DG-M6Rnc.js} +3 -3
  66. package/dist/{react-vega-5AcMW8gG.js → react-vega-ewj7q_U5.js} +1 -1
  67. package/dist/{requirementDiagram-BXWQKSXE-0pmmxL6_.js → requirementDiagram-BXWQKSXE-DCwsThh0.js} +11 -11
  68. package/dist/{reveal-component-BujcZI2B.js → reveal-component-CfTzIkA2.js} +3 -3
  69. package/dist/{sankeyDiagram-P5KCCOFB-CDKR5TJH.js → sankeyDiagram-P5KCCOFB-BdzhT0BM.js} +1 -1
  70. package/dist/{sequenceDiagram-WJ2MYXX4-DB-ChWwU.js → sequenceDiagram-WJ2MYXX4-CbXB1_PU.js} +4 -4
  71. package/dist/{stateDiagram-D77RDMKH-orN6AwMx.js → stateDiagram-D77RDMKH-A-Zf3Sb2.js} +13 -13
  72. package/dist/stateDiagram-v2-MP3YSRHH-D9YMnUGx.js +30 -0
  73. package/dist/style.css +1 -1
  74. package/dist/{swimlanes-42K2YHIH-BkSDcqDT.js → swimlanes-42K2YHIH-B_pMf0J4.js} +10 -10
  75. package/dist/swimlanesDiagram-VR7AAH4N-Ctgy-yGP.js +30 -0
  76. package/dist/{timeline-definition-24CTP7MA-BuqJUIRZ.js → timeline-definition-24CTP7MA-DTXFjTTM.js} +3 -3
  77. package/dist/{vega-component-CNf5gcrm.js → vega-component-tFOzgarw.js} +4 -4
  78. package/dist/{vega-embed-container-CbnTccZi.js → vega-embed-container-sSR5hAsy.js} +2 -2
  79. package/dist/{vega-loader.browser-D95WfUcj.js → vega-loader.browser-DNST6uVf.js} +2 -2
  80. package/dist/{vennDiagram-4TSXK5OY-CTUlJ2PK.js → vennDiagram-4TSXK5OY-BPHjZo0R.js} +3 -3
  81. package/dist/{wardleyDiagram-VM6X3IG4-3evLUb0M.js → wardleyDiagram-VM6X3IG4-6fTLYBuD.js} +3 -3
  82. package/dist/{xychartDiagram-S5SC5T6Z-DL2E3K8-.js → xychartDiagram-S5SC5T6Z-BYjwjrzE.js} +5 -5
  83. package/package.json +1 -2
  84. package/src/__mocks__/common.ts +3 -3
  85. package/src/__tests__/CellStatus.test.tsx +1 -1
  86. package/src/__tests__/setup.ts +7 -7
  87. package/src/components/app-config/ai-config.tsx +2 -0
  88. package/src/components/app-config/optional-features.tsx +1 -1
  89. package/src/components/chat/chat-panel.tsx +19 -8
  90. package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +286 -0
  91. package/src/components/data-table/charts/charts.tsx +26 -13
  92. package/src/components/data-table/column-summary/chart-spec-model.tsx +4 -4
  93. package/src/components/dependency-graph/elements.ts +2 -2
  94. package/src/components/editor/__tests__/package-alert.test.tsx +140 -0
  95. package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +107 -0
  96. package/src/components/editor/actions/pair-with-agent.tsx +119 -0
  97. package/src/components/editor/actions/useNotebookActions.tsx +2 -1
  98. package/src/components/editor/ai/add-cell-with-ai.tsx +2 -0
  99. package/src/components/editor/ai/staged-cell-submission.ts +2 -2
  100. package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
  101. package/src/components/editor/chrome/components/contribute-snippet-button.tsx +6 -1
  102. package/src/components/editor/connections/database/as-code.ts +44 -44
  103. package/src/components/editor/connections/storage/as-code.ts +3 -3
  104. package/src/components/editor/file-tree/requesting-tree.tsx +16 -13
  105. package/src/components/editor/navigation/clipboard.ts +2 -2
  106. package/src/components/editor/notebook-cell.tsx +2 -2
  107. package/src/components/editor/output/MarimoTracebackOutput.tsx +1 -1
  108. package/src/components/editor/output/VideoOutput.tsx +1 -1
  109. package/src/components/editor/output/ansi-reduce.ts +21 -17
  110. package/src/components/editor/output/console/ConsoleOutput.tsx +3 -3
  111. package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +59 -0
  112. package/src/components/editor/output/console/text-rendering.tsx +3 -1
  113. package/src/components/editor/package-alert.tsx +20 -7
  114. package/src/components/home/components.tsx +1 -0
  115. package/src/components/pages/run-page.tsx +1 -0
  116. package/src/components/slides/__tests__/minimap-actions.test.tsx +7 -7
  117. package/src/components/slides/__tests__/minimap.test.ts +12 -12
  118. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +8 -8
  119. package/src/components/static-html/share-modal.tsx +2 -1
  120. package/src/components/static-html/static-banner.tsx +2 -2
  121. package/src/components/ui/links.tsx +6 -1
  122. package/src/components/ui/typography.tsx +16 -8
  123. package/src/core/ai/context/__tests__/registry.test.ts +31 -28
  124. package/src/core/ai/context/providers/cell-output.ts +8 -8
  125. package/src/core/ai/context/providers/datasource.ts +10 -7
  126. package/src/core/ai/context/providers/error.ts +7 -7
  127. package/src/core/ai/context/providers/file.ts +8 -8
  128. package/src/core/ai/context/providers/tables.ts +7 -7
  129. package/src/core/ai/context/providers/variable.ts +7 -7
  130. package/src/core/ai/context/registry.ts +18 -18
  131. package/src/core/ai/ids/ids.ts +5 -5
  132. package/src/core/ai/model-registry.ts +12 -9
  133. package/src/core/ai/staged-cells.ts +6 -6
  134. package/src/core/ai/tools/base.ts +6 -6
  135. package/src/core/ai/tools/edit-notebook-tool.ts +6 -6
  136. package/src/core/ai/tools/registry.ts +4 -4
  137. package/src/core/ai/tools/run-cells-tool.ts +7 -7
  138. package/src/core/ai/tools/sample-tool.ts +6 -6
  139. package/src/core/cells/__tests__/cells.test.ts +27 -0
  140. package/src/core/cells/cells.ts +2 -1
  141. package/src/core/codemirror/cells/debugger-decorations.ts +13 -7
  142. package/src/core/codemirror/cells/line-timing-decorations.ts +9 -9
  143. package/src/core/codemirror/cells/traceback-decorations.ts +7 -4
  144. package/src/core/codemirror/code-lens/extension.ts +13 -13
  145. package/src/core/codemirror/copilot/__tests__/language-server.test.ts +6 -6
  146. package/src/core/codemirror/copilot/__tests__/transport.test.ts +12 -12
  147. package/src/core/codemirror/copilot/language-server.ts +13 -13
  148. package/src/core/codemirror/copilot/transport.ts +1 -1
  149. package/src/core/codemirror/find-replace/search-highlight.ts +5 -5
  150. package/src/core/codemirror/go-to-definition/underline.ts +3 -3
  151. package/src/core/codemirror/keymaps/vim.ts +3 -3
  152. package/src/core/codemirror/language/languages/markdown.ts +8 -8
  153. package/src/core/codemirror/language/languages/python.ts +7 -7
  154. package/src/core/codemirror/language/languages/sql/completion-builder.ts +5 -5
  155. package/src/core/codemirror/language/languages/sql/completion-store.ts +4 -4
  156. package/src/core/codemirror/language/languages/sql/sql.ts +21 -21
  157. package/src/core/codemirror/lsp/__tests__/transports.test.ts +10 -10
  158. package/src/core/codemirror/lsp/federated-lsp.ts +29 -27
  159. package/src/core/codemirror/lsp/notebook-lsp.ts +21 -21
  160. package/src/core/codemirror/misc/__tests__/dnd.test.ts +10 -10
  161. package/src/core/codemirror/misc/__tests__/paste.test.ts +7 -4
  162. package/src/core/codemirror/reactive-references/extension.ts +3 -3
  163. package/src/core/codemirror/rtc/loro/awareness.ts +12 -12
  164. package/src/core/codemirror/rtc/loro/sync.ts +5 -5
  165. package/src/core/codemirror/vim/cursor-visibility.ts +3 -3
  166. package/src/core/dom/ui-element.ts +5 -5
  167. package/src/core/dom/uiregistry.ts +10 -10
  168. package/src/core/hotkeys/hotkeys.ts +9 -9
  169. package/src/core/islands/__tests__/bridge.test.ts +4 -4
  170. package/src/core/islands/__tests__/test-utils.tsx +4 -4
  171. package/src/core/islands/bridge.ts +85 -82
  172. package/src/core/islands/components/web-components.tsx +7 -7
  173. package/src/core/islands/worker/__tests__/controller.test.ts +1 -1
  174. package/src/core/islands/worker/controller.ts +6 -3
  175. package/src/core/islands/worker-factory.ts +2 -2
  176. package/src/core/kernel/RuntimeState.ts +4 -4
  177. package/src/core/lsp/__tests__/transport.test.ts +19 -19
  178. package/src/core/lsp/transport.ts +5 -5
  179. package/src/core/network/CachingRequestRegistry.ts +2 -2
  180. package/src/core/network/DeferredRequestRegistry.ts +4 -4
  181. package/src/core/runtime/runtime.ts +25 -20
  182. package/src/core/static/virtual-file-tracker.ts +5 -5
  183. package/src/core/wasm/__tests__/bridge.test.ts +2 -2
  184. package/src/core/wasm/bridge.ts +130 -126
  185. package/src/core/wasm/router.ts +5 -5
  186. package/src/core/wasm/store.ts +4 -4
  187. package/src/core/wasm/worker/bootstrap.ts +8 -5
  188. package/src/core/wasm/worker/message-buffer.ts +3 -3
  189. package/src/core/websocket/transports/__tests__/ws.test.ts +8 -8
  190. package/src/core/websocket/transports/basic.ts +15 -8
  191. package/src/core/websocket/transports/sse.ts +7 -7
  192. package/src/core/websocket/transports/transport.ts +3 -3
  193. package/src/core/websocket/transports/ws.ts +9 -7
  194. package/src/css/globals.css +18 -21
  195. package/src/css/katex.min.css +260 -241
  196. package/src/hooks/__tests__/useOverflowDetection.test.tsx +5 -5
  197. package/src/hooks/__tests__/useResizeObserver.test.tsx +12 -12
  198. package/src/plugins/core/registerReactComponent.tsx +5 -5
  199. package/src/plugins/core/sidebar-element.tsx +2 -2
  200. package/src/plugins/impl/ButtonPlugin.tsx +3 -3
  201. package/src/plugins/impl/CheckboxPlugin.tsx +3 -3
  202. package/src/plugins/impl/CodeEditorPlugin.tsx +3 -3
  203. package/src/plugins/impl/DatePickerPlugin.tsx +3 -3
  204. package/src/plugins/impl/DateRangePlugin.tsx +3 -3
  205. package/src/plugins/impl/DateTimePickerPlugin.tsx +3 -3
  206. package/src/plugins/impl/DictPlugin.tsx +3 -3
  207. package/src/plugins/impl/DropdownPlugin.tsx +3 -3
  208. package/src/plugins/impl/FileUploadPlugin.tsx +3 -3
  209. package/src/plugins/impl/MatrixPlugin.tsx +4 -4
  210. package/src/plugins/impl/MicrophonePlugin.tsx +3 -3
  211. package/src/plugins/impl/MultiselectPlugin.tsx +3 -3
  212. package/src/plugins/impl/NumberPlugin.tsx +3 -3
  213. package/src/plugins/impl/RadioPlugin.tsx +9 -5
  214. package/src/plugins/impl/RangeSliderPlugin.tsx +3 -3
  215. package/src/plugins/impl/RefreshPlugin.tsx +3 -3
  216. package/src/plugins/impl/SliderPlugin.tsx +3 -3
  217. package/src/plugins/impl/SwitchPlugin.tsx +3 -3
  218. package/src/plugins/impl/TabsPlugin.tsx +3 -3
  219. package/src/plugins/impl/TextAreaPlugin.tsx +3 -3
  220. package/src/plugins/impl/TextInputPlugin.tsx +3 -3
  221. package/src/plugins/impl/__tests__/MatrixPlugin.test.tsx +2 -2
  222. package/src/plugins/impl/anywidget/model.ts +10 -10
  223. package/src/plugins/impl/anywidget/registry.ts +12 -9
  224. package/src/plugins/impl/anywidget/runtime.ts +11 -9
  225. package/src/plugins/impl/anywidget/widget-binding.ts +6 -6
  226. package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +7 -6
  227. package/src/plugins/impl/matplotlib/MatplotlibPlugin.tsx +3 -3
  228. package/src/plugins/impl/matplotlib/__tests__/matplotlib-renderer.test.ts +2 -2
  229. package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +2 -2
  230. package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +10 -10
  231. package/src/plugins/impl/panel/utils.ts +5 -5
  232. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
  233. package/src/plugins/impl/vega/VegaPlugin.tsx +3 -3
  234. package/src/plugins/impl/vega/__tests__/use-vega-container-remeasure.test.ts +7 -7
  235. package/src/plugins/impl/vega/__tests__/utils.test.ts +16 -1
  236. package/src/plugins/impl/vega/__tests__/vega.test.ts +37 -0
  237. package/src/plugins/impl/vega/loader.ts +23 -1
  238. package/src/plugins/impl/vega/utils.ts +5 -4
  239. package/src/plugins/layout/AccordionPlugin.tsx +3 -3
  240. package/src/plugins/layout/CalloutPlugin.tsx +3 -3
  241. package/src/plugins/layout/ImageComparisonPlugin.tsx +5 -3
  242. package/src/plugins/layout/JsonOutputPlugin.tsx +3 -3
  243. package/src/plugins/layout/MimeRenderPlugin.tsx +3 -3
  244. package/src/plugins/layout/NavigationMenuPlugin.tsx +3 -3
  245. package/src/plugins/layout/OutlinePlugin.tsx +3 -3
  246. package/src/plugins/layout/ProgressPlugin.tsx +3 -3
  247. package/src/plugins/layout/RoutesPlugin.tsx +6 -8
  248. package/src/plugins/layout/StatPlugin.tsx +3 -3
  249. package/src/plugins/layout/TexPlugin.tsx +3 -3
  250. package/src/plugins/layout/carousel/CarouselPlugin.tsx +4 -4
  251. package/src/plugins/layout/mermaid/MermaidPlugin.tsx +3 -3
  252. package/src/utils/Deferred.ts +6 -6
  253. package/src/utils/async-capture-tracker.ts +10 -7
  254. package/src/utils/errors.ts +5 -5
  255. package/src/utils/id-tree.tsx +83 -80
  256. package/src/utils/lru.ts +1 -1
  257. package/src/utils/multi-map.ts +14 -12
  258. package/src/utils/paths.ts +6 -6
  259. package/src/utils/pluralize.ts +3 -3
  260. package/src/utils/progress.ts +6 -6
  261. package/src/utils/python-poet/poet.ts +14 -14
  262. package/src/utils/routes.ts +4 -2
  263. package/src/utils/semaphore.ts +6 -6
  264. package/src/utils/storage/storage.ts +6 -6
  265. package/src/utils/storage/typed.ts +16 -12
  266. package/src/utils/time.ts +9 -9
  267. package/src/utils/timed-cache.ts +4 -4
  268. package/src/utils/tracer.ts +9 -6
  269. package/dist/classDiagram-ZZMXUADV-Fe-V14Sc.js +0 -30
  270. package/dist/classDiagram-v2-VYDZK3BY-xTDg7lOs.js +0 -30
  271. package/dist/flowDiagram-HODETNUW-6dMdB8pR.js +0 -16
  272. package/dist/katex-DFBiSucW.js +0 -21840
  273. package/dist/stateDiagram-v2-MP3YSRHH-o05_rJN8.js +0 -30
  274. package/dist/swimlanesDiagram-VR7AAH4N-D_nFQfRc.js +0 -30
@@ -1,15 +1,15 @@
1
- import "./chunk-75Z2AOVW-5_HsvXwr.js";
1
+ import "./chunk-75Z2AOVW-C4AOleKf.js";
2
2
  import { n as e } from "./src-CA_m4ONl.js";
3
3
  import { n as t } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
4
- import "./chunk-DU6HZSFF-BUgAHvnM.js";
5
- import "./chunk-P2QGCYS3-C0iGU29N.js";
6
- import "./chunk-PWAF6VOD-CTFCL0jI.js";
7
- import "./chunk-GMAD6QVW-Czynz8aA.js";
8
- import "./chunk-4HAMMTFA-D2qv8E0X.js";
9
- import "./chunk-GVQU2GXP-yQEdulRS.js";
10
- import "./chunk-L3NEJ4N5-DwRWnDDK.js";
11
- import { o as n } from "./chunk-OSK3NFVY-BBKU_Ign.js";
12
- import { c as r } from "./mermaid-DPNuhemn.js";
4
+ import "./chunk-DU6HZSFF-1TwWR6gh.js";
5
+ import "./chunk-P2QGCYS3-0TAWai9C.js";
6
+ import "./chunk-PWAF6VOD-lNxB9k8z.js";
7
+ import "./chunk-GMAD6QVW-vStrMz2P.js";
8
+ import "./chunk-4HAMMTFA-BPTTOOC5.js";
9
+ import "./chunk-GVQU2GXP-2HwWgs4u.js";
10
+ import "./chunk-L3NEJ4N5-RhC7i0I2.js";
11
+ import { o as n } from "./chunk-OSK3NFVY-CZV09N-U.js";
12
+ import { c as r } from "./mermaid-Dnzoxjt1.js";
13
13
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/swimlanes-42K2YHIH.mjs
14
14
  var i = 5, a = 1e-5, o = 1e-6;
15
15
  function s(e) {
@@ -0,0 +1,30 @@
1
+ import "./chunk-75Z2AOVW-C4AOleKf.js";
2
+ import "./src-CA_m4ONl.js";
3
+ import { n as e } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
4
+ import "./chunk-DU6HZSFF-1TwWR6gh.js";
5
+ import "./chunk-P2QGCYS3-0TAWai9C.js";
6
+ import "./chunk-PWAF6VOD-lNxB9k8z.js";
7
+ import "./chunk-GMAD6QVW-vStrMz2P.js";
8
+ import "./chunk-4HAMMTFA-BPTTOOC5.js";
9
+ import "./chunk-GVQU2GXP-2HwWgs4u.js";
10
+ import "./chunk-L3NEJ4N5-RhC7i0I2.js";
11
+ import "./chunk-OSK3NFVY-CZV09N-U.js";
12
+ import "./mermaid-Dnzoxjt1.js";
13
+ import "./chunk-F27PBJKO-DMI1PBe4.js";
14
+ import "./chunk-XXDRQBXY-Dnl5VBqG.js";
15
+ import "./chunk-POPQ4Y6H-Cc3_56GX.js";
16
+ import { r as t, t as n } from "./chunk-SHT3W25Y-CrEPyWy1.js";
17
+ //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/swimlanesDiagram-VR7AAH4N.mjs
18
+ var r = n({
19
+ defaultLayout: "swimlane",
20
+ styles: /* @__PURE__ */ e((e) => `${t(e)}
21
+ .swimlane.cluster rect {
22
+ stroke: ${e.clusterBorder} !important;
23
+ }
24
+ [data-look="neo"].cluster rect {
25
+ filter: none;
26
+ }
27
+ `, "getStyles")
28
+ });
29
+ //#endregion
30
+ export { r as diagram };
@@ -1,9 +1,9 @@
1
1
  import { t as e } from "./arc-7ra3iNdN.js";
2
- import { p as t } from "./chunk-75Z2AOVW-5_HsvXwr.js";
2
+ import { p as t } from "./chunk-75Z2AOVW-C4AOleKf.js";
3
3
  import { n, t as r } from "./src-CA_m4ONl.js";
4
4
  import { n as i, t as a } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
5
- import { $ as o, J as s, a as c, b as l, et as u, nt as d, o as f, x as p } from "./chunk-DU6HZSFF-BUgAHvnM.js";
6
- import { p as m } from "./mermaid-DPNuhemn.js";
5
+ import { $ as o, J as s, a as c, b as l, et as u, nt as d, o as f, x as p } from "./chunk-DU6HZSFF-1TwWR6gh.js";
6
+ import { p as m } from "./mermaid-Dnzoxjt1.js";
7
7
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/timeline-definition-24CTP7MA.mjs
8
8
  var h = (function() {
9
9
  var e = /* @__PURE__ */ i(function(e, t, n, r) {
@@ -11,10 +11,10 @@ import { A as p, n as ee } from "./useTheme-DzXmYZ5V.js";
11
11
  import { c as m } from "./arrays-CN1djC4k.js";
12
12
  import { t as te } from "./objects-CzUgoMIF.js";
13
13
  import { t as h } from "./useAsyncData-BD6AStMt.js";
14
- import { a as ne, i as re, n as ie, t as g } from "./formats-C8rLgZT9.js";
15
- import { M as ae, n as oe } from "./vega-loader.browser-D95WfUcj.js";
16
- import { t as se } from "./react-vega-5AcMW8gG.js";
17
- import { a as ce, n as _ } from "./loader-D2W4oM-3.js";
14
+ import { a as ne, i as re, n as ie, t as g } from "./formats-Cl_67ghI.js";
15
+ import { M as ae, n as oe } from "./vega-loader.browser-DNST6uVf.js";
16
+ import { t as se } from "./react-vega-ewj7q_U5.js";
17
+ import { a as ce, n as _ } from "./loader-DEZSzvma.js";
18
18
  import { t as le } from "./useDeepCompareMemoize-D_HNdyvI.js";
19
19
  import { t as ue } from "./semaphore-89jsoHtS.js";
20
20
  import { t as de } from "./use-vega-container-remeasure-4DwJbPWu.js";
@@ -2,8 +2,8 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-ofJbxM4x.js";
3
3
  import { t as n } from "./compiler-runtime-Cj8ZWiNS.js";
4
4
  import { t as r } from "./jsx-runtime-DgDPJV9S.js";
5
- import { M as i } from "./vega-loader.browser-D95WfUcj.js";
6
- import { n as a } from "./react-vega-5AcMW8gG.js";
5
+ import { M as i } from "./vega-loader.browser-DNST6uVf.js";
6
+ import { n as a } from "./react-vega-ewj7q_U5.js";
7
7
  import { t as o } from "./use-vega-container-remeasure-4DwJbPWu.js";
8
8
  //#region src/components/charts/vega-embed-container.tsx
9
9
  var s = n(), c = /* @__PURE__ */ e(t(), 1), l = r();
@@ -237,8 +237,8 @@ function Ye(e) {
237
237
  if ("spec" in e) return Ye(e.spec);
238
238
  }
239
239
  }
240
- function Xe(t) {
241
- return !t || Object.keys(t).length === 0 ? "auto" : e.mapValues(t, (e) => e === "geometry" || e === "date" || e === "time" ? "string" : e === "datetime" ? "date" : e);
240
+ function Xe(t, { parseDates: n = !1 } = {}) {
241
+ return !t || Object.keys(t).length === 0 ? "auto" : e.mapValues(t, (e) => e === "geometry" ? "string" : e === "date" ? n ? "date" : "string" : e === "time" ? "string" : e === "datetime" ? "date" : e);
242
242
  }
243
243
  //#endregion
244
244
  //#region ../node_modules/.pnpm/d3-dsv@3.0.1/node_modules/d3-dsv/src/dsv.js
@@ -1,9 +1,9 @@
1
- import { i as e } from "./chunk-75Z2AOVW-5_HsvXwr.js";
1
+ import { i as e } from "./chunk-75Z2AOVW-C4AOleKf.js";
2
2
  import { t } from "./src-CA_m4ONl.js";
3
3
  import { n } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
4
- import { $ as r, H as i, K as a, U as o, a as s, b as c, c as l, et as u, f as d, nt as f, tt as p, v as m, w as h, y as g } from "./chunk-DU6HZSFF-BUgAHvnM.js";
4
+ import { $ as r, H as i, K as a, U as o, a as s, b as c, c as l, et as u, f as d, nt as f, tt as p, v as m, w as h, y as g } from "./chunk-DU6HZSFF-1TwWR6gh.js";
5
5
  import { t as _ } from "./rough.esm-CtV9AnV1.js";
6
- import { p as v } from "./mermaid-DPNuhemn.js";
6
+ import { p as v } from "./mermaid-Dnzoxjt1.js";
7
7
  //#region ../node_modules/.pnpm/khroma@2.1.0/node_modules/khroma/dist/methods/transparentize.js
8
8
  var y = (e, t) => p(e, "a", -t), b = 1e-10;
9
9
  function x(e, t) {
@@ -1,8 +1,8 @@
1
- import { i as e } from "./chunk-75Z2AOVW-5_HsvXwr.js";
1
+ import { i as e } from "./chunk-75Z2AOVW-C4AOleKf.js";
2
2
  import { n as t } from "./src-CA_m4ONl.js";
3
3
  import { n } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
4
- import { D as r, H as i, K as a, U as o, a as s, b as c, c as l, v as u, w as d, x as f, y as p } from "./chunk-DU6HZSFF-BUgAHvnM.js";
5
- import { p as m } from "./mermaid-DPNuhemn.js";
4
+ import { D as r, H as i, K as a, U as o, a as s, b as c, c as l, v as u, w as d, x as f, y as p } from "./chunk-DU6HZSFF-1TwWR6gh.js";
5
+ import { p as m } from "./mermaid-Dnzoxjt1.js";
6
6
  import { n as h } from "./mermaid-parser.core-DxuSfYwJ.js";
7
7
  import { t as g } from "./chunk-JWPE2WC7-DJvv1t8U.js";
8
8
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/wardleyDiagram-VM6X3IG4.mjs
@@ -2,14 +2,14 @@ import { t as e } from "./linear-Cnaq3Tfb.js";
2
2
  import { n as t } from "./ordinal-c7efuCSS.js";
3
3
  import { t as n } from "./range-BAIvbVHp.js";
4
4
  import { q as r } from "./cubic-OaEBhQPK.js";
5
- import { i } from "./chunk-75Z2AOVW-5_HsvXwr.js";
5
+ import { i } from "./chunk-75Z2AOVW-C4AOleKf.js";
6
6
  import { n as a } from "./init-Ix4LXMlt.js";
7
7
  import { n as o } from "./src-CA_m4ONl.js";
8
8
  import { n as s } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
9
- import { D as c, H as l, K as u, U as d, a as f, b as p, c as m, f as h, v as g, w as _, y as v, z as y } from "./chunk-DU6HZSFF-BUgAHvnM.js";
10
- import "./chunk-PWAF6VOD-CTFCL0jI.js";
11
- import { t as b } from "./chunk-GMAD6QVW-Czynz8aA.js";
12
- import { p as x } from "./mermaid-DPNuhemn.js";
9
+ import { D as c, H as l, K as u, U as d, a as f, b as p, c as m, f as h, v as g, w as _, y as v, z as y } from "./chunk-DU6HZSFF-1TwWR6gh.js";
10
+ import "./chunk-PWAF6VOD-lNxB9k8z.js";
11
+ import { t as b } from "./chunk-GMAD6QVW-vStrMz2P.js";
12
+ import { p as x } from "./mermaid-Dnzoxjt1.js";
13
13
  //#region ../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/band.js
14
14
  function S() {
15
15
  var e = t().unknown(void 0), r = e.domain, i = e.range, o = 0, s = 1, c, l, u = !1, d = 0, f = 0, p = .5;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.1-dev4",
3
+ "version": "0.25.1-dev40",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -198,7 +198,6 @@
198
198
  "@testing-library/jest-dom": "^7.0.1",
199
199
  "@testing-library/react": "^16.3.2",
200
200
  "@types/dompurify": "^3.2.0",
201
- "@types/katex": "^0.16.8",
202
201
  "@types/lodash-es": "^4.17.12",
203
202
  "@types/node": "^24.13.3",
204
203
  "@types/plotly.js": "^2.35.16",
@@ -101,9 +101,9 @@ export const SetupMocks = {
101
101
  const unobserve = vi.fn();
102
102
  const disconnect = vi.fn();
103
103
  global.ResizeObserver = class MockResizeObserver {
104
- observe = observe;
105
- unobserve = unobserve;
106
- disconnect = disconnect;
104
+ public observe = observe;
105
+ public unobserve = unobserve;
106
+ public disconnect = disconnect;
107
107
  } as unknown as typeof ResizeObserver;
108
108
  return { observe, unobserve, disconnect };
109
109
  },
@@ -57,7 +57,7 @@ describe("CellStatusComponent", () => {
57
57
 
58
58
  beforeEach(() => {
59
59
  global.Date = class extends Date {
60
- static override now() {
60
+ public static override now() {
61
61
  return mockDate.getTime();
62
62
  }
63
63
  } as typeof Date;
@@ -9,29 +9,29 @@ import "blob-polyfill";
9
9
  // if we need to test ResizeObserver functionality
10
10
  // we can use a library like "resize-observer-polyfill"
11
11
  globalThis.ResizeObserver ??= class {
12
- observe(_target: Element) {
12
+ public observe(_target: Element) {
13
13
  /* noop */
14
14
  }
15
- unobserve(_target: Element) {
15
+ public unobserve(_target: Element) {
16
16
  /* noop */
17
17
  }
18
- disconnect() {
18
+ public disconnect() {
19
19
  /* noop */
20
20
  }
21
21
  } as never;
22
22
 
23
23
  // mock implementation because jsdom doesn't support IntersectionObserver
24
24
  globalThis.IntersectionObserver ??= class {
25
- observe(_target: Element) {
25
+ public observe(_target: Element) {
26
26
  /* noop */
27
27
  }
28
- unobserve(_target: Element) {
28
+ public unobserve(_target: Element) {
29
29
  /* noop */
30
30
  }
31
- disconnect() {
31
+ public disconnect() {
32
32
  /* noop */
33
33
  }
34
- takeRecords() {
34
+ public takeRecords() {
35
35
  return [];
36
36
  }
37
37
  } as never;
@@ -59,6 +59,7 @@ import {
59
59
  listModelsForAiSettings,
60
60
  } from "../ai/ai-utils";
61
61
  import { getTagColour } from "../ai/display-helpers";
62
+ import { PairWithAgentBanner } from "../editor/actions/pair-with-agent";
62
63
  import {
63
64
  Accordion,
64
65
  AccordionContent,
@@ -2005,6 +2006,7 @@ export const AiConfig: React.FC<AiConfigProps> = ({
2005
2006
  {aiEnabled !== false && (
2006
2007
  <>
2007
2008
  <TabsContent value="ai-providers">
2009
+ <PairWithAgentBanner className="mb-4" />
2008
2010
  <AiProvidersConfig
2009
2011
  form={form}
2010
2012
  config={config}
@@ -107,7 +107,7 @@ const OPTIONAL_DEPENDENCIES: OptionalFeature[] = [
107
107
  },
108
108
  {
109
109
  id: "lens",
110
- packagesRequired: [{ name: "marimo-lens", minVersion: "0.2.0" }],
110
+ packagesRequired: [{ name: "marimo-lens", minVersion: "0.2.3" }],
111
111
  additionalPackageInstalls: [],
112
112
  description: "Select outputs for agents",
113
113
  },
@@ -64,6 +64,10 @@ import { cn } from "@/utils/cn";
64
64
  import { Logger } from "@/utils/Logger";
65
65
  import { AIModelDropdown } from "../ai/ai-model-dropdown";
66
66
  import { useOpenSettingsToTab } from "../app-config/state";
67
+ import {
68
+ PairWithAgentBanner,
69
+ PairWithAgentButton,
70
+ } from "../editor/actions/pair-with-agent";
67
71
  import { PairWithAgentModal } from "../editor/actions/pair-with-agent-modal";
68
72
  import { PromptInput } from "../editor/ai/add-cell-with-ai";
69
73
  import {
@@ -163,6 +167,9 @@ const ChatHeader: React.FC<ChatHeaderProps> = ({
163
167
  </Button>
164
168
  </Tooltip>
165
169
  <div className="flex items-center gap-2">
170
+ <Tooltip content="Connect your agent">
171
+ <PairWithAgentButton className="mr-1" label="Connect" />
172
+ </Tooltip>
166
173
  <MCPStatusIndicator />
167
174
  <Tooltip content="AI Settings">
168
175
  <Button
@@ -493,7 +500,7 @@ const PairWithAgentCallout: React.FC<{
493
500
  onClick={onPairWithAgent}
494
501
  >
495
502
  <SparklesIcon className="h-3.5 w-3.5 shrink-0" />
496
- <span>Work on this notebook with your own agent</span>
503
+ <span>Connect your own agent to this notebook</span>
497
504
  <ArrowRightIcon className="h-3 w-3 shrink-0" />
498
505
  </Button>
499
506
  );
@@ -509,13 +516,17 @@ const ChatPanel = () => {
509
516
  title="Chat with AI"
510
517
  description="No AI provider configured or Chat model not selected"
511
518
  action={
512
- <Button
513
- variant="outline"
514
- size="sm"
515
- onClick={() => handleClick("ai", "ai-providers")}
516
- >
517
- Edit AI settings
518
- </Button>
519
+ <div className="flex flex-col gap-3">
520
+ <Button
521
+ variant="outline"
522
+ size="sm"
523
+ className="self-start"
524
+ onClick={() => handleClick("ai", "ai-providers")}
525
+ >
526
+ Edit AI settings
527
+ </Button>
528
+ <PairWithAgentBanner />
529
+ </div>
519
530
  }
520
531
  icon={<BotMessageSquareIcon />}
521
532
  />
@@ -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
+ });