@marimo-team/frontend 0.16.1 → 0.16.3

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 (310) hide show
  1. package/dist/assets/{ConnectedDataExplorerComponent-2wVcyvDj.js → ConnectedDataExplorerComponent-Brtw1DxF.js} +1 -1
  2. package/dist/assets/{ImageComparisonComponent-D2j6i0hv.js → ImageComparisonComponent-Dxl-PbZX.js} +1 -1
  3. package/dist/assets/{VegaLite-BckFaf2D.js → VegaLite-BXQF0Cx_.js} +1 -1
  4. package/dist/assets/_baseEach-BjSm9ht3.js +1 -0
  5. package/dist/assets/_baseMap-CV4Ezmtf.js +1 -0
  6. package/dist/assets/_baseUniq-Ci9yZGxz.js +1 -0
  7. package/dist/assets/{_createAggregator-C5CVY-0t.js → _createAggregator-VFK9K2d9.js} +1 -1
  8. package/dist/assets/{agent-panel-RGLNjkYe.js → agent-panel-BoscVLCT.js} +7 -7
  9. package/dist/assets/{any-language-editor-DjuXwGCA.js → any-language-editor-ChaY_VUU.js} +1 -1
  10. package/dist/assets/{architectureDiagram-W76B3OCA-Dyj4ds_R.js → architectureDiagram-W76B3OCA-CueUUFYd.js} +1 -1
  11. package/dist/assets/{between-horizontal-start-Dt2aKpPf.js → between-horizontal-start-DAHqmLYT.js} +1 -1
  12. package/dist/assets/{blockDiagram-QIGZ2CNN-o-i7DDvN.js → blockDiagram-QIGZ2CNN-BYYygyWn.js} +1 -1
  13. package/dist/assets/{c4Diagram-FPNF74CW-DGHEwWrx.js → c4Diagram-FPNF74CW-DAz3xEh1.js} +1 -1
  14. package/dist/assets/channel-6SqQ2U_X.js +1 -0
  15. package/dist/assets/chat-panel-DJkOLrw9.js +3 -0
  16. package/dist/assets/{chunk-4BX2VUAB-BJecb-Ri.js → chunk-4BX2VUAB-8g-RyHdt.js} +1 -1
  17. package/dist/assets/{chunk-55IACEB6-CAATkc4w.js → chunk-55IACEB6-iWZZ8Mt6.js} +1 -1
  18. package/dist/assets/{chunk-FMBD7UC4-DPuNbQ-f.js → chunk-FMBD7UC4-knjss4wk.js} +1 -1
  19. package/dist/assets/{chunk-K7UQS3LO-C8TWVLiH.js → chunk-K7UQS3LO-DVIwPBgZ.js} +1 -1
  20. package/dist/assets/{chunk-QN33PNHL-DiZZ09q4.js → chunk-QN33PNHL-CBU8pN6I.js} +1 -1
  21. package/dist/assets/{chunk-QZHKN3VN-BIUM7usu.js → chunk-QZHKN3VN-5ljElUF4.js} +1 -1
  22. package/dist/assets/{chunk-TVAH2DTR-vGTArPBG.js → chunk-TVAH2DTR-DkIdGINc.js} +1 -1
  23. package/dist/assets/{chunk-TZMSLE5B-D2KRqp_x.js → chunk-TZMSLE5B-CIFOSTqh.js} +1 -1
  24. package/dist/assets/{circle-play-cjeNez0N.js → circle-play-BOdsbq5u.js} +1 -1
  25. package/dist/assets/classDiagram-KNZD7YFC-DVqXcTYf.js +1 -0
  26. package/dist/assets/classDiagram-v2-RKCZMP56-DVqXcTYf.js +1 -0
  27. package/dist/assets/{clear-button-C97JtAez.js → clear-button-GAjXl0CQ.js} +1 -1
  28. package/dist/assets/clone-DSDb0xen.js +1 -0
  29. package/dist/assets/command-palette-BUXkqoLh.js +1 -0
  30. package/dist/assets/{common-Du9rSOwD.js → common-DahoYqdi.js} +1 -1
  31. package/dist/assets/{compile-CZXqyOxa.js → compile-Bg8uJ7vm.js} +1 -1
  32. package/dist/assets/{cose-bilkent-S5V4N54A-CqUN5Y9b.js → cose-bilkent-S5V4N54A-z_0gqD9K.js} +1 -1
  33. package/dist/assets/{dagre-5GWH7T2D-RJqTI9DM.js → dagre-5GWH7T2D-BMt7CNXL.js} +1 -1
  34. package/dist/assets/{data-grid-overlay-editor-DZN0q1LV.js → data-grid-overlay-editor-Ctn4XtXx.js} +1 -1
  35. package/dist/assets/datasources-panel-C7sqRIHs.js +1 -0
  36. package/dist/assets/{dependency-graph-panel-CEog_O7V.js → dependency-graph-panel-DNajptzv.js} +4 -4
  37. package/dist/assets/{diagram-N5W7TBWH-D-l4zZ9d.js → diagram-N5W7TBWH-BzwvLvAy.js} +1 -1
  38. package/dist/assets/{diagram-QEK2KX5R-CCOmBUt-.js → diagram-QEK2KX5R-DRLJ56FS.js} +1 -1
  39. package/dist/assets/{diagram-S2PKOQOG-C_I_9jnZ.js → diagram-S2PKOQOG-Bf8x4KTU.js} +1 -1
  40. package/dist/assets/{documentation-panel-C1BtMZ3M.js → documentation-panel-Dm6Ozl67.js} +1 -1
  41. package/dist/assets/{edit-page-B-oevUZ9.js → edit-page-CGc9EjuG.js} +53 -42
  42. package/dist/assets/{ellipsis-vertical-BEb-J8z6.js → ellipsis-vertical-Bj1YXvZe.js} +1 -1
  43. package/dist/assets/{empty-state-C99UyDE3.js → empty-state-CYev-D31.js} +1 -1
  44. package/dist/assets/{erDiagram-AWTI2OKA-BePOLi5M.js → erDiagram-AWTI2OKA-DmgzgN_I.js} +1 -1
  45. package/dist/assets/{error-panel-Bs34jXFh.js → error-panel-BYG4twCa.js} +1 -1
  46. package/dist/assets/{file-explorer-panel-Ck6UL861.js → file-explorer-panel-BSMiOApi.js} +1 -1
  47. package/dist/assets/{flowDiagram-PVAE7QVJ-BgjFu5l7.js → flowDiagram-PVAE7QVJ-BdRKkajr.js} +1 -1
  48. package/dist/assets/{ganttDiagram-OWAHRB6G-YOPb3XSV.js → ganttDiagram-OWAHRB6G-lfRAMnq_.js} +5 -5
  49. package/dist/assets/{gitGraphDiagram-NY62KEGX-CGhqaDTy.js → gitGraphDiagram-NY62KEGX-CQVTIrHF.js} +1 -1
  50. package/dist/assets/{glide-data-editor-9QUH6iso.js → glide-data-editor-D5A4pou7.js} +4 -4
  51. package/dist/assets/{graph-DQQFGrho.js → graph-CBNo279v.js} +1 -1
  52. package/dist/assets/{home-page-DRKpPCrF.js → home-page-CmdznBJR.js} +2 -2
  53. package/dist/assets/{index-SGLNXrGP.js → index-0dfGh-Gj.js} +1 -1
  54. package/dist/assets/{index-aE43R74q.js → index-BDYVSSzB.js} +1 -1
  55. package/dist/assets/{index-BJNCMUmG.js → index-B_KyDZ94.js} +1 -1
  56. package/dist/assets/{index-BjgnbONl.js → index-Bfy-I_lW.js} +1 -1
  57. package/dist/assets/{index-CUFv_thQ.js → index-Bh98Tp-z.js} +1 -1
  58. package/dist/assets/{index-C2MD0vgD.js → index-BhroIwBL.js} +1 -1
  59. package/dist/assets/{index-DdnKZNxM.js → index-BtQtesaI.js} +1 -1
  60. package/dist/assets/index-C0iXCvyY.css +1 -0
  61. package/dist/assets/index-C1SHFMCp.js +581 -0
  62. package/dist/assets/{index-C_tkBKNO.js → index-C6DWtSls.js} +1 -1
  63. package/dist/assets/{index-Aeo6WiK7.js → index-C71cdkH-.js} +1 -1
  64. package/dist/assets/{index-G5QZppK2.js → index-CT_FTqvK.js} +1 -1
  65. package/dist/assets/{index-B8jXZ12t.js → index-CU5rRr66.js} +1 -1
  66. package/dist/assets/{index-BAbIIxHU.js → index-Cb6duXQm.js} +1 -1
  67. package/dist/assets/{index-BW3k9Gss.js → index-D23e9zQj.js} +1 -1
  68. package/dist/assets/index-DUGecC2Z.js +68 -0
  69. package/dist/assets/{index-CFKO7WXI.js → index-DcGIOAQi.js} +1 -1
  70. package/dist/assets/{index-ClzeQrN7.js → index-PJfa9qXY.js} +1 -1
  71. package/dist/assets/{index-C1ez98sk.js → index-SPslPC2B.js} +1 -1
  72. package/dist/assets/{index-BprjMYH5.js → index-VPQlo4Uz.js} +1 -1
  73. package/dist/assets/{index-CfaDbEdi.js → index-qbTLKWyG.js} +1 -1
  74. package/dist/assets/infoDiagram-STP46IZ2-DBu8p9gd.js +2 -0
  75. package/dist/assets/{isEmpty-D-4c7sMv.js → isEmpty-CnOLuQIv.js} +1 -1
  76. package/dist/assets/{journeyDiagram-BIP6EPQ6-C94u3Mv3.js → journeyDiagram-BIP6EPQ6-6U_vHJBH.js} +1 -1
  77. package/dist/assets/{kanban-definition-6OIFK2YF-BEXYFzz7.js → kanban-definition-6OIFK2YF-DgnR14ys.js} +1 -1
  78. package/dist/assets/{layout-Bz2BJ2ru.js → layout-RHmq4fP9.js} +1 -1
  79. package/dist/assets/{linear-D8s7K76e.js → linear-CLdOVPGV.js} +1 -1
  80. package/dist/assets/links-Dd1icsEk.js +7 -0
  81. package/dist/assets/{logs-panel-DC7wpmPz.js → logs-panel-CjbuhBLx.js} +1 -1
  82. package/dist/assets/{markdown-renderer-DRdSWR9X.js → markdown-renderer-X5YJvAZq.js} +3 -3
  83. package/dist/assets/{mermaid-Y3x4hmD0.js → mermaid-Bl2T5oEC.js} +1 -1
  84. package/dist/assets/{mermaid.core-DzthE35Y.js → mermaid.core-CfukBvGI.js} +4 -4
  85. package/dist/assets/min-BXIes1Za.js +1 -0
  86. package/dist/assets/{mindmap-definition-Q6HEUPPD-DktvuLe1.js → mindmap-definition-Q6HEUPPD-BXCjP4Lu.js} +1 -1
  87. package/dist/assets/{number-overlay-editor-BEfwI1IT.js → number-overlay-editor-BUyqkSes.js} +1 -1
  88. package/dist/assets/{outline-panel-CdsnAy2w.js → outline-panel-BvGcPKdd.js} +1 -1
  89. package/dist/assets/{packages-panel-DiTA-d_D.js → packages-panel-BichDQWG.js} +1 -1
  90. package/dist/assets/{pieDiagram-ADFJNKIX-DQDNQ-de.js → pieDiagram-ADFJNKIX-CMzJFIJM.js} +1 -1
  91. package/dist/assets/{quadrantDiagram-LMRXKWRM-0kgIXc2-.js → quadrantDiagram-LMRXKWRM-CfGssUlO.js} +1 -1
  92. package/dist/assets/{react-plotly-DJqqfM7c.js → react-plotly-DR3hV0HW.js} +1 -1
  93. package/dist/assets/{requirementDiagram-4UW4RH46-B5rb0ypd.js → requirementDiagram-4UW4RH46-CfrFolth.js} +1 -1
  94. package/dist/assets/{run-page-CFmLrv1R.js → run-page-Bqd_4ePD.js} +1 -1
  95. package/dist/assets/{sankeyDiagram-GR3RE2ED-Dom7IlnF.js → sankeyDiagram-GR3RE2ED-D_UttKU0.js} +1 -1
  96. package/dist/assets/{scratchpad-panel-CuHWpHO8.js → scratchpad-panel-D5N15ji1.js} +1 -1
  97. package/dist/assets/secrets-panel-BpbnAO4R.js +1 -0
  98. package/dist/assets/{sequenceDiagram-C3RYC4MD-PNJWXQbw.js → sequenceDiagram-C3RYC4MD-MdfQQApP.js} +1 -1
  99. package/dist/assets/{slides-component-CJgaTRZ0.js → slides-component-C0z7rXmk.js} +1 -1
  100. package/dist/assets/{snippets-panel-B2EC1txM.js → snippets-panel-wlpZ_Wzx.js} +1 -1
  101. package/dist/assets/sortBy-BW_zNHP6.js +1 -0
  102. package/dist/assets/{state-CWict9RU.js → state-CDooX-dk.js} +1 -1
  103. package/dist/assets/{stateDiagram-KXAO66HF-BE58aJnr.js → stateDiagram-KXAO66HF-H7kfw3ot.js} +1 -1
  104. package/dist/assets/stateDiagram-v2-UMBNRL4Z-YMeb9qMR.js +1 -0
  105. package/dist/assets/{storage-DRaR04wR.js → storage-b1QCapTq.js} +6 -6
  106. package/dist/assets/{terminal-BX3Su5q7.js → terminal-CPV44BXz.js} +1 -1
  107. package/dist/assets/{time-hUzZfpNE.js → time-DDy3xv5Y.js} +1 -1
  108. package/dist/assets/{timeline-definition-XQNQX7LJ-CqQP9t51.js → timeline-definition-XQNQX7LJ-J-cPRT2_.js} +1 -1
  109. package/dist/assets/{tracing-B10Q1n-L.js → tracing-3eHHRUiJ.js} +2 -2
  110. package/dist/assets/{tracing-panel-Du8WCnno.js → tracing-panel-BMgy3D7d.js} +2 -2
  111. package/dist/assets/{trash-B81GTiv6.js → trash--tonOuDe.js} +1 -1
  112. package/dist/assets/{tree-6vW2ogkh.js → tree-ouIGEsVg.js} +1 -1
  113. package/dist/assets/{treemap-75Q7IDZK-CdwDwwsz.js → treemap-75Q7IDZK-CzJTJ_3R.js} +20 -20
  114. package/dist/assets/{variable-panel-D5qgJI7k.js → variable-panel-sFTn4Oih.js} +1 -1
  115. package/dist/assets/{vega-component-DJaJWMJM.js → vega-component-BkPkzX9r.js} +1 -1
  116. package/dist/assets/{xychartDiagram-6GGTOJPD-WFtXqaM9.js → xychartDiagram-6GGTOJPD-BZ8WOb_8.js} +1 -1
  117. package/dist/index.html +10 -3
  118. package/package.json +8 -8
  119. package/src/__mocks__/common.ts +5 -3
  120. package/src/__mocks__/notebook.ts +2 -2
  121. package/src/__mocks__/requests.ts +1 -0
  122. package/src/__tests__/main.test.tsx +2 -2
  123. package/src/components/ai/ai-provider-icon.tsx +2 -0
  124. package/src/components/app-config/ai-config.tsx +32 -1
  125. package/src/components/app-config/common.tsx +2 -2
  126. package/src/components/app-config/user-config-form.tsx +26 -0
  127. package/src/components/audio/audio-recorder.tsx +0 -1
  128. package/src/components/chat/acp/blocks.tsx +2 -2
  129. package/src/components/chat/acp/thread.tsx +3 -5
  130. package/src/components/chat/acp/utils.ts +5 -5
  131. package/src/components/chat/chat-panel.tsx +1 -1
  132. package/src/components/data-table/__tests__/columns.test.tsx +38 -0
  133. package/src/components/data-table/__tests__/data-table.test.tsx +2 -2
  134. package/src/components/data-table/cell-hover-template/feature.ts +1 -1
  135. package/src/components/data-table/cell-hover-template/types.ts +1 -1
  136. package/src/components/data-table/charts/__tests__/altair-generator.test.ts +1 -1
  137. package/src/components/data-table/charts/chart-spec/tooltips.ts +3 -3
  138. package/src/components/data-table/charts/components/chart-items.tsx +1 -1
  139. package/src/components/data-table/charts/components/form-fields.tsx +2 -2
  140. package/src/components/data-table/charts/constants.ts +1 -1
  141. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
  142. package/src/components/data-table/column-summary/chart-spec-model.tsx +2 -2
  143. package/src/components/data-table/columns.tsx +22 -3
  144. package/src/components/data-table/data-table.tsx +35 -3
  145. package/src/components/data-table/date-popover.tsx +1 -1
  146. package/src/components/data-table/download-actions.tsx +1 -1
  147. package/src/components/data-table/range-focus/__tests__/utils.test.ts +5 -5
  148. package/src/components/data-table/renderers.tsx +22 -13
  149. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
  150. package/src/components/data-table/schemas.ts +16 -0
  151. package/src/components/data-table/types.ts +4 -3
  152. package/src/components/datasources/column-preview.tsx +9 -6
  153. package/src/components/debugger/debugger-code.tsx +1 -1
  154. package/src/components/dependency-graph/custom-node.tsx +15 -6
  155. package/src/components/dependency-graph/dependency-graph-minimap.tsx +2 -2
  156. package/src/components/dependency-graph/dependency-graph-tree.tsx +2 -2
  157. package/src/components/dependency-graph/dependency-graph.tsx +1 -1
  158. package/src/components/dependency-graph/elements.ts +7 -7
  159. package/src/components/dependency-graph/utils/changes.ts +4 -4
  160. package/src/components/editor/Cell.tsx +7 -1
  161. package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
  162. package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +1 -1
  163. package/src/components/editor/chrome/panels/packages-panel.tsx +1 -1
  164. package/src/components/editor/columns/storage.ts +1 -1
  165. package/src/components/editor/database/__tests__/__snapshots__/as-code.test.ts.snap +36 -0
  166. package/src/components/editor/database/__tests__/as-code.test.ts +30 -7
  167. package/src/components/editor/database/add-database-form.tsx +11 -0
  168. package/src/components/editor/database/as-code.ts +104 -5
  169. package/src/components/editor/database/schemas.ts +36 -18
  170. package/src/components/editor/errors/auto-fix.tsx +12 -2
  171. package/src/components/editor/errors/sql-validation-errors.tsx +40 -0
  172. package/src/components/editor/navigation/clipboard.ts +2 -2
  173. package/src/components/editor/output/ConsoleOutput.tsx +14 -2
  174. package/src/components/editor/output/JsonOutput.tsx +1 -1
  175. package/src/components/editor/output/MarimoErrorOutput.tsx +60 -1
  176. package/src/components/editor/output/MarimoTracebackOutput.tsx +17 -2
  177. package/src/components/editor/renderers/grid-layout/types.ts +2 -2
  178. package/src/components/editor/renderers/plugins.ts +1 -1
  179. package/src/components/editor/renderers/types.ts +1 -1
  180. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +7 -7
  181. package/src/components/forms/form.tsx +5 -5
  182. package/src/components/ui/links.tsx +1 -0
  183. package/src/core/ai/__tests__/model-registry.test.ts +0 -10
  184. package/src/core/ai/context/providers/cell-output.ts +1 -18
  185. package/src/core/ai/context/providers/error.ts +2 -2
  186. package/src/core/ai/ids/ids.ts +1 -0
  187. package/src/core/ai/model-registry.ts +2 -1
  188. package/src/core/cells/cells.ts +5 -5
  189. package/src/core/cells/logs.ts +1 -1
  190. package/src/core/cells/types.ts +1 -1
  191. package/src/core/codemirror/__tests__/format.test.ts +6 -0
  192. package/src/core/codemirror/cells/traceback-decorations.ts +1 -1
  193. package/src/core/codemirror/editing/commands.ts +2 -2
  194. package/src/core/codemirror/find-replace/navigate.ts +1 -1
  195. package/src/core/codemirror/language/__tests__/extension.test.ts +24 -0
  196. package/src/core/codemirror/language/__tests__/sql-validation.test.ts +133 -0
  197. package/src/core/codemirror/language/__tests__/sql.test.ts +764 -79
  198. package/src/core/codemirror/language/languages/markdown.ts +4 -1
  199. package/src/core/codemirror/language/languages/sql/banner-validation-errors.ts +85 -0
  200. package/src/core/codemirror/language/languages/sql/completion-builder.ts +160 -0
  201. package/src/core/codemirror/language/languages/sql/completion-sources.tsx +9 -3
  202. package/src/core/codemirror/language/languages/sql/completion-store.ts +46 -50
  203. package/src/core/codemirror/language/languages/sql/renderers.tsx +485 -0
  204. package/src/core/codemirror/language/languages/sql/sql-mode.ts +20 -0
  205. package/src/core/codemirror/language/languages/sql/sql.ts +218 -4
  206. package/src/core/codemirror/language/languages/sql/utils.ts +4 -1
  207. package/src/core/codemirror/language/panel/panel.tsx +8 -2
  208. package/src/core/codemirror/language/panel/sql.tsx +86 -4
  209. package/src/core/codemirror/language/utils/ast.ts +3 -3
  210. package/src/core/codemirror/lsp/federated-lsp.ts +4 -4
  211. package/src/core/codemirror/lsp/lens.ts +4 -4
  212. package/src/core/codemirror/lsp/notebook-lsp.ts +1 -1
  213. package/src/core/codemirror/lsp/types.ts +1 -1
  214. package/src/core/codemirror/markdown/completions.ts +1 -1
  215. package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
  216. package/src/core/codemirror/rtc/loro/awareness.ts +1 -1
  217. package/src/core/config/config-schema.ts +1 -0
  218. package/src/core/config/feature-flag.tsx +6 -2
  219. package/src/core/datasets/request-registry.ts +24 -1
  220. package/src/core/dom/events.ts +1 -1
  221. package/src/core/dom/outline.ts +2 -2
  222. package/src/core/dom/uiregistry.ts +2 -8
  223. package/src/core/errors/__tests__/errors.test.ts +22 -4
  224. package/src/core/errors/errors.ts +29 -1
  225. package/src/core/errors/state.ts +1 -1
  226. package/src/core/islands/bridge.ts +1 -0
  227. package/src/core/islands/main.ts +3 -2
  228. package/src/core/islands/parse.ts +1 -3
  229. package/src/core/kernel/messages.ts +2 -1
  230. package/src/core/network/CachingRequestRegistry.ts +74 -0
  231. package/src/core/network/DeferredRequestRegistry.ts +3 -1
  232. package/src/core/network/__tests__/CachingRequestRegistry.test.ts +73 -0
  233. package/src/core/network/requests-network.ts +7 -0
  234. package/src/core/network/requests-static.ts +1 -0
  235. package/src/core/network/requests-toasting.ts +1 -0
  236. package/src/core/network/types.ts +3 -1
  237. package/src/core/variables/state.ts +2 -2
  238. package/src/core/wasm/__tests__/state.test.ts +1 -1
  239. package/src/core/wasm/bridge.ts +5 -0
  240. package/src/core/websocket/useMarimoWebSocket.tsx +9 -2
  241. package/src/custom.d.ts +1 -1
  242. package/src/hooks/useCellRenderCount.ts +1 -0
  243. package/src/hooks/useResizeHandle.ts +4 -1
  244. package/src/plugins/core/RenderHTML.tsx +1 -2
  245. package/src/plugins/core/registerReactComponent.tsx +23 -19
  246. package/src/plugins/impl/DataTablePlugin.tsx +18 -6
  247. package/src/plugins/impl/FileUploadPlugin.tsx +1 -1
  248. package/src/plugins/impl/RefreshPlugin.tsx +1 -1
  249. package/src/plugins/impl/SliderPlugin.tsx +4 -0
  250. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +27 -9
  251. package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +58 -2
  252. package/src/plugins/impl/anywidget/__tests__/model.test.ts +3 -4
  253. package/src/plugins/impl/anywidget/model.ts +2 -3
  254. package/src/plugins/impl/data-editor/types.ts +1 -1
  255. package/src/plugins/impl/data-explorer/components/query-form.tsx +1 -1
  256. package/src/plugins/impl/data-frames/DataFramePlugin.tsx +17 -5
  257. package/src/plugins/impl/data-frames/types.ts +1 -1
  258. package/src/plugins/impl/panel/PanelPlugin.tsx +2 -2
  259. package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
  260. package/src/plugins/impl/vega/__tests__/loader.test.ts +2 -2
  261. package/src/plugins/impl/vega/loader.ts +1 -1
  262. package/src/plugins/impl/vega/vega-component.tsx +1 -1
  263. package/src/plugins/impl/vega/vega-loader.ts +2 -2
  264. package/src/plugins/layout/NavigationMenuPlugin.tsx +1 -1
  265. package/src/plugins/layout/RoutesPlugin.tsx +1 -2
  266. package/src/plugins/plugins.ts +2 -2
  267. package/src/stories/dataframe.stories.tsx +2 -0
  268. package/src/utils/Logger.ts +1 -1
  269. package/src/utils/__tests__/data-views.test.ts +30 -68
  270. package/src/utils/__tests__/dom.test.ts +167 -0
  271. package/src/utils/__tests__/id-tree.test.ts +49 -1
  272. package/src/utils/__tests__/storage.test.ts +1 -1
  273. package/src/utils/__tests__/traceback.test.ts +13 -2
  274. package/src/utils/arrays.ts +1 -1
  275. package/src/utils/createReducer.ts +1 -5
  276. package/src/utils/data-views.ts +6 -19
  277. package/src/utils/dom.ts +55 -0
  278. package/src/utils/edit-distance.ts +1 -1
  279. package/src/utils/fileToBase64.ts +1 -1
  280. package/src/utils/id-tree.tsx +20 -18
  281. package/src/utils/json/base64.ts +13 -0
  282. package/src/utils/json/json-parser.ts +2 -2
  283. package/src/utils/lru.ts +4 -0
  284. package/src/utils/mergeRefs.ts +1 -1
  285. package/src/utils/objects.ts +3 -3
  286. package/src/utils/pluralize.ts +1 -1
  287. package/src/utils/routes.ts +2 -2
  288. package/src/utils/sets.ts +1 -1
  289. package/src/utils/traceback.ts +45 -15
  290. package/src/utils/tracer.ts +11 -9
  291. package/dist/assets/_baseEach-CvTX9w0Y.js +0 -1
  292. package/dist/assets/_baseMap-CtlwA90f.js +0 -1
  293. package/dist/assets/_baseUniq-BKktIGQ1.js +0 -1
  294. package/dist/assets/channel-Co6iMgWq.js +0 -1
  295. package/dist/assets/chat-panel-9alr8FS4.js +0 -3
  296. package/dist/assets/classDiagram-KNZD7YFC-BbJ0rY3y.js +0 -1
  297. package/dist/assets/classDiagram-v2-RKCZMP56-BbJ0rY3y.js +0 -1
  298. package/dist/assets/clone-BMP0PsTa.js +0 -1
  299. package/dist/assets/command-palette-B93Pjcky.js +0 -1
  300. package/dist/assets/datasources-panel-v7H3cR0p.js +0 -1
  301. package/dist/assets/index-2252nrk6.js +0 -68
  302. package/dist/assets/index-C7CoaNFb.js +0 -578
  303. package/dist/assets/index-DadI618h.css +0 -1
  304. package/dist/assets/infoDiagram-STP46IZ2-CJLOpSAf.js +0 -2
  305. package/dist/assets/links-BpXlz1GG.js +0 -7
  306. package/dist/assets/min-BBO3-1Hg.js +0 -1
  307. package/dist/assets/secrets-panel-CfHc5YD0.js +0 -1
  308. package/dist/assets/sortBy-DZnlX29-.js +0 -1
  309. package/dist/assets/stateDiagram-v2-UMBNRL4Z-CdThjimL.js +0 -1
  310. package/src/__tests__/lru.test.ts +0 -74
@@ -24,7 +24,7 @@ import ReactDOM, { type Root } from "react-dom/client";
24
24
  import useEvent from "react-use-event-hook";
25
25
  import type { ZodSchema } from "zod";
26
26
  import { notebookAtom } from "@/core/cells/cells.ts";
27
- import { findCellId } from "@/core/cells/ids.ts";
27
+ import { HTMLCellId } from "@/core/cells/ids.ts";
28
28
  import { isUninstantiated } from "@/core/cells/utils";
29
29
  import { createInputEvent, MarimoValueUpdateEvent } from "@/core/dom/events";
30
30
  import { getUIElementObjectId } from "@/core/dom/ui-element";
@@ -182,24 +182,28 @@ function PluginSlotInternal<T>(
182
182
  const objectId = getUIElementObjectId(hostElement);
183
183
  invariant(objectId, "Object ID should exist");
184
184
 
185
- const cellId = findCellId(hostElement);
186
- invariant(cellId, "Cell ID should exist");
187
-
188
- const notebookState = store.get(notebookAtom);
189
- const cellRuntime = notebookState.cellRuntime[cellId];
190
- const cellData = notebookState.cellData[cellId];
191
-
192
- const cellNotInitialized = isUninstantiated({
193
- executionTime:
194
- cellRuntime.runElapsedTimeMs ?? cellData.lastExecutionTime,
195
- status: cellRuntime.status,
196
- errored: cellRuntime.errored,
197
- interrupted: cellRuntime.interrupted,
198
- stopped: cellRuntime.stopped,
199
- });
200
-
201
- if (cellNotInitialized) {
202
- throw new CellNotInitializedError();
185
+ const htmlId = HTMLCellId.findElementThroughShadowDOMs(hostElement)?.id;
186
+ const cellId = htmlId ? HTMLCellId.parse(htmlId) : null;
187
+ if (cellId) {
188
+ // If the cell is not initialized, throw an error
189
+ const notebookState = store.get(notebookAtom);
190
+ const cellRuntime = notebookState.cellRuntime[cellId];
191
+ const cellData = notebookState.cellData[cellId];
192
+
193
+ const cellNotInitialized = isUninstantiated({
194
+ executionTime:
195
+ cellRuntime.runElapsedTimeMs ?? cellData.lastExecutionTime,
196
+ status: cellRuntime.status,
197
+ errored: cellRuntime.errored,
198
+ interrupted: cellRuntime.interrupted,
199
+ stopped: cellRuntime.stopped,
200
+ });
201
+
202
+ if (cellNotInitialized) {
203
+ throw new CellNotInitializedError();
204
+ }
205
+ } else {
206
+ Logger.warn(`Cell ID ${cellId} cannot be found`);
203
207
  }
204
208
 
205
209
  const response = await FUNCTIONS_REGISTRY.request({
@@ -36,6 +36,10 @@ import {
36
36
  import { usePanelOwnership } from "@/components/data-table/hooks/use-panel-ownership";
37
37
  import { LoadingTable } from "@/components/data-table/loading-table";
38
38
  import { RowViewerPanel } from "@/components/data-table/row-viewer-panel/row-viewer";
39
+ import {
40
+ type DownloadAsArgs,
41
+ DownloadAsSchema,
42
+ } from "@/components/data-table/schemas";
39
43
  import {
40
44
  type BinValues,
41
45
  type ColumnHeaderStats,
@@ -108,7 +112,7 @@ export type CalculateTopKRows = (req: {
108
112
  column: string;
109
113
  k: number;
110
114
  }) => Promise<{
111
- data: Array<[unknown, number]>;
115
+ data: [unknown, number][];
112
116
  }>;
113
117
 
114
118
  export type PreviewColumn = (opts: { column: string }) => Promise<{
@@ -168,6 +172,7 @@ interface Data<T> {
168
172
  totalRows: number | TooManyRows;
169
173
  pagination: boolean;
170
174
  pageSize: number;
175
+ maxHeight?: number;
171
176
  selection: DataTableSelection;
172
177
  showDownload: boolean;
173
178
  showFilters: boolean;
@@ -182,6 +187,7 @@ interface Data<T> {
182
187
  freezeColumnsRight?: string[];
183
188
  textJustifyColumns?: Record<string, "left" | "center" | "right">;
184
189
  wrappedColumns?: string[];
190
+ headerTooltip?: Record<string, string>;
185
191
  totalColumns: number;
186
192
  maxColumns: number | "all";
187
193
  hasStableRowId: boolean;
@@ -190,7 +196,7 @@ interface Data<T> {
190
196
 
191
197
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
192
198
  type DataTableFunctions = {
193
- download_as: (req: { format: "csv" | "json" | "parquet" }) => Promise<string>;
199
+ download_as: DownloadAsArgs;
194
200
  get_column_summaries: <T>(
195
201
  opts: ColumnSummariesArgs,
196
202
  ) => Promise<ColumnSummaries<T>>;
@@ -215,7 +221,7 @@ type DataTableFunctions = {
215
221
  preview_column?: PreviewColumn;
216
222
  };
217
223
 
218
- type S = Array<number | string | { rowId: string; columnName?: string }>;
224
+ type S = (number | string | { rowId: string; columnName?: string })[];
219
225
 
220
226
  export const DataTablePlugin = createPlugin<S>("marimo-table")
221
227
  .withData(
@@ -249,10 +255,12 @@ export const DataTablePlugin = createPlugin<S>("marimo-table")
249
255
  .record(z.enum(["left", "center", "right"]))
250
256
  .optional(),
251
257
  wrappedColumns: z.array(z.string()).optional(),
258
+ headerTooltip: z.record(z.string()).optional(),
252
259
  fieldTypes: columnToFieldTypesSchema.nullish(),
253
260
  totalColumns: z.number(),
254
261
  maxColumns: z.union([z.number(), z.literal("all")]).default("all"),
255
262
  hasStableRowId: z.boolean().default(false),
263
+ maxHeight: z.number().optional(),
256
264
  cellStyles: z.record(z.record(z.object({}).passthrough())).optional(),
257
265
  hoverTemplate: z.string().optional(),
258
266
  // Whether to load the data lazily.
@@ -263,9 +271,7 @@ export const DataTablePlugin = createPlugin<S>("marimo-table")
263
271
  }),
264
272
  )
265
273
  .withFunctions<DataTableFunctions>({
266
- download_as: rpc
267
- .input(z.object({ format: z.enum(["csv", "json", "parquet"]) }))
268
- .output(z.string()),
274
+ download_as: DownloadAsSchema,
269
275
  get_column_summaries: rpc
270
276
  .input(z.object({ precompute: z.boolean() }))
271
277
  .output(
@@ -649,6 +655,7 @@ export const LoadingDataTableComponent = memo(
649
655
  toggleDisplayHeader={toggleDisplayHeader}
650
656
  getRow={getRow}
651
657
  cellId={cellId}
658
+ maxHeight={props.maxHeight}
652
659
  />
653
660
  );
654
661
 
@@ -706,6 +713,7 @@ const DataTableComponent = ({
706
713
  freezeColumnsRight,
707
714
  textJustifyColumns,
708
715
  wrappedColumns,
716
+ headerTooltip,
709
717
  totalColumns,
710
718
  get_row_ids,
711
719
  cellStyles,
@@ -715,6 +723,7 @@ const DataTableComponent = ({
715
723
  preview_column,
716
724
  getRow,
717
725
  cellId,
726
+ maxHeight,
718
727
  }: DataTableProps<unknown> &
719
728
  DataTableSearchProps & {
720
729
  data: unknown[];
@@ -779,6 +788,7 @@ const DataTableComponent = ({
779
788
  fieldTypes: memoizedClampedFieldTypes,
780
789
  textJustifyColumns: memoizedTextJustifyColumns,
781
790
  wrappedColumns: memoizedWrappedColumns,
791
+ headerTooltip: headerTooltip,
782
792
  // Only show data types if they are explicitly set
783
793
  showDataTypes: showDataTypes,
784
794
  calculateTopKRows: calculate_top_k_rows,
@@ -791,6 +801,7 @@ const DataTableComponent = ({
791
801
  memoizedClampedFieldTypes,
792
802
  memoizedTextJustifyColumns,
793
803
  memoizedWrappedColumns,
804
+ headerTooltip,
794
805
  calculate_top_k_rows,
795
806
  ],
796
807
  );
@@ -894,6 +905,7 @@ const DataTableComponent = ({
894
905
  data={data}
895
906
  columns={columns}
896
907
  className={className}
908
+ maxHeight={maxHeight}
897
909
  sorting={sorting}
898
910
  totalRows={totalRows}
899
911
  totalColumns={totalColumns}
@@ -31,7 +31,7 @@ interface Data {
31
31
  max_size: number;
32
32
  }
33
33
 
34
- type T = Array<[string, string]>;
34
+ type T = [string, string][];
35
35
 
36
36
  export class FileUploadPlugin implements IPlugin<T, Data> {
37
37
  tagName = "marimo-file";
@@ -20,7 +20,7 @@ interface Data {
20
20
  * It may also be a human-readable string like "1m" or "1h" or "3h 30m".
21
21
  * These will be converted to seconds.
22
22
  */
23
- options: Array<string | number>;
23
+ options: (string | number)[];
24
24
  /**
25
25
  * The initial value.
26
26
  */
@@ -147,6 +147,10 @@ const SliderComponent = ({
147
147
  <NumberField
148
148
  value={valueMap(internalValue)}
149
149
  onChange={(nextValue) => {
150
+ // If nextValue is null/undefined/NaN (input cleared), set to start
151
+ if (nextValue == null || Number.isNaN(nextValue)) {
152
+ nextValue = Number(start);
153
+ }
150
154
  setInternalValue(nextValue);
151
155
  if (!debounce) {
152
156
  setValue(nextValue);
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
 
4
4
  import type { AnyWidget, Experimental } from "@anywidget/types";
5
- import { isEqual } from "lodash-es";
5
+ import { get, isEqual, set } from "lodash-es";
6
6
  import { useEffect, useMemo, useRef } from "react";
7
7
  import { z } from "zod";
8
8
  import { MarimoIncomingMessageEvent } from "@/core/dom/events";
@@ -16,7 +16,11 @@ import {
16
16
  import { createPlugin } from "@/plugins/core/builder";
17
17
  import { rpc } from "@/plugins/core/rpc";
18
18
  import type { IPluginProps } from "@/plugins/types";
19
- import { updateBufferPaths } from "@/utils/data-views";
19
+ import {
20
+ type Base64String,
21
+ byteStringToBinary,
22
+ typedAtob,
23
+ } from "@/utils/json/base64";
20
24
  import { Logger } from "@/utils/Logger";
21
25
  import { ErrorBanner } from "../common/error-banner";
22
26
  import { MODEL_MANAGER, Model } from "./model";
@@ -25,7 +29,7 @@ interface Data {
25
29
  jsUrl: string;
26
30
  jsHash: string;
27
31
  css?: string | null;
28
- bufferPaths?: Array<Array<string | number>> | null;
32
+ bufferPaths?: (string | number)[][] | null;
29
33
  initialValue: T;
30
34
  }
31
35
 
@@ -59,6 +63,11 @@ type Props = IPluginProps<T, Data, PluginFunctions>;
59
63
 
60
64
  const AnyWidgetSlot = (props: Props) => {
61
65
  const { css, jsUrl, jsHash, bufferPaths } = props.data;
66
+
67
+ const valueWithBuffers = useMemo(() => {
68
+ return resolveInitialValue(props.value, bufferPaths ?? []);
69
+ }, [props.value, bufferPaths]);
70
+
62
71
  // JS is an ESM file with a render function on it
63
72
  // export function render({ model, el }) {
64
73
  // ...
@@ -85,10 +94,6 @@ const AnyWidgetSlot = (props: Props) => {
85
94
  }
86
95
  }, [hasError, jsUrl]);
87
96
 
88
- const valueWithBuffer = useMemo(() => {
89
- return updateBufferPaths(props.value, bufferPaths);
90
- }, [props.value, bufferPaths]);
91
-
92
97
  // Mount the CSS
93
98
  useEffect(() => {
94
99
  const shadowRoot = props.host.shadowRoot;
@@ -157,7 +162,7 @@ const AnyWidgetSlot = (props: Props) => {
157
162
  key={key}
158
163
  {...props}
159
164
  widget={module.default}
160
- value={valueWithBuffer}
165
+ value={valueWithBuffers}
161
166
  />
162
167
  );
163
168
  };
@@ -174,7 +179,7 @@ async function runAnyWidgetModule(
174
179
  el: HTMLElement,
175
180
  ): Promise<() => void> {
176
181
  const experimental: Experimental = {
177
- invoke: async (name, msg, options) => {
182
+ invoke: async (_name, _msg, _options) => {
178
183
  const message =
179
184
  "anywidget.invoke not supported in marimo. Please file an issue at https://github.com/marimo-team/marimo/issues";
180
185
  Logger.warn(message);
@@ -284,3 +289,16 @@ export const visibleForTesting = {
284
289
  isAnyWidgetModule,
285
290
  getDirtyFields,
286
291
  };
292
+
293
+ export function resolveInitialValue(
294
+ raw: Record<string, any>,
295
+ bufferPaths: readonly (readonly (string | number)[])[],
296
+ ) {
297
+ const out = structuredClone(raw);
298
+ for (const bufferPath of bufferPaths) {
299
+ const base64String: Base64String = get(raw, bufferPath);
300
+ const bytes = byteStringToBinary(typedAtob(base64String));
301
+ set(out, bufferPath, new DataView(bytes.buffer));
302
+ }
303
+ return out;
304
+ }
@@ -5,7 +5,11 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
5
5
  import { TestUtils } from "@/__tests__/test-helpers";
6
6
  import type { UIElementId } from "@/core/cells/ids";
7
7
  import { MarimoIncomingMessageEvent } from "@/core/dom/events";
8
- import { getDirtyFields, visibleForTesting } from "../AnyWidgetPlugin";
8
+ import {
9
+ getDirtyFields,
10
+ resolveInitialValue,
11
+ visibleForTesting,
12
+ } from "../AnyWidgetPlugin";
9
13
  import { Model } from "../model";
10
14
 
11
15
  const { LoadedSlot } = visibleForTesting;
@@ -129,7 +133,7 @@ describe("LoadedSlot", () => {
129
133
  method: "update",
130
134
  state: { count: 10 },
131
135
  },
132
- buffers: undefined,
136
+ buffers: [],
133
137
  },
134
138
  bubbles: false,
135
139
  composed: true,
@@ -179,3 +183,55 @@ describe("LoadedSlot", () => {
179
183
  });
180
184
  });
181
185
  });
186
+
187
+ describe("resolveInitialValue", () => {
188
+ it("should convert base64 strings to DataView at specified paths", () => {
189
+ const result = resolveInitialValue(
190
+ {
191
+ a: 10,
192
+ b: "aGVsbG8=", // "hello" in base64
193
+ c: [1, "d29ybGQ="], // "world" in base64
194
+ d: {
195
+ foo: "bWFyaW1vCg==", // "marimo" in base64
196
+ baz: 20,
197
+ },
198
+ },
199
+ [["b"], ["c", 1], ["d", "foo"]],
200
+ );
201
+
202
+ expect(result).toMatchInlineSnapshot(`
203
+ {
204
+ "a": 10,
205
+ "b": DataView [
206
+ 104,
207
+ 101,
208
+ 108,
209
+ 108,
210
+ 111,
211
+ ],
212
+ "c": [
213
+ 1,
214
+ DataView [
215
+ 119,
216
+ 111,
217
+ 114,
218
+ 108,
219
+ 100,
220
+ ],
221
+ ],
222
+ "d": {
223
+ "baz": 20,
224
+ "foo": DataView [
225
+ 109,
226
+ 97,
227
+ 114,
228
+ 105,
229
+ 109,
230
+ 111,
231
+ 10,
232
+ ],
233
+ },
234
+ }
235
+ `);
236
+ });
237
+ });
@@ -9,7 +9,6 @@ import {
9
9
  vi,
10
10
  } from "vitest";
11
11
  import { TestUtils } from "@/__tests__/test-helpers";
12
- import type { Base64String } from "@/utils/json/base64";
13
12
  import {
14
13
  type AnyWidgetMessage,
15
14
  handleWidgetMessage,
@@ -246,7 +245,7 @@ describe("Model", () => {
246
245
  content,
247
246
  });
248
247
 
249
- expect(callback).toHaveBeenCalledWith(content, undefined);
248
+ expect(callback).toHaveBeenCalledWith(content, []);
250
249
  });
251
250
 
252
251
  it("should handle custom messages with buffers", () => {
@@ -286,7 +285,7 @@ describe("ModelManager", () => {
286
285
  }: {
287
286
  modelId: string;
288
287
  message: AnyWidgetMessage;
289
- buffers: Base64String[];
288
+ buffers: readonly DataView[];
290
289
  }) => {
291
290
  return handleWidgetMessage({
292
291
  modelId,
@@ -353,7 +352,7 @@ describe("ModelManager", () => {
353
352
  message: { method: "custom", content: { count: 1 } },
354
353
  buffers: [],
355
354
  });
356
- expect(callback).toHaveBeenCalledWith({ count: 1 }, undefined);
355
+ expect(callback).toHaveBeenCalledWith({ count: 1 }, []);
357
356
  });
358
357
 
359
358
  it("should handle close messages", async () => {
@@ -10,7 +10,6 @@ import { assertNever } from "@/utils/assertNever";
10
10
  import { Deferred } from "@/utils/Deferred";
11
11
  import { updateBufferPaths } from "@/utils/data-views";
12
12
  import { throwNotImplemented } from "@/utils/functions";
13
- import type { Base64String } from "@/utils/json/base64";
14
13
  import { Logger } from "@/utils/Logger";
15
14
 
16
15
  export type EventHandler = (...args: any[]) => void;
@@ -171,7 +170,7 @@ export class Model<T extends Record<string, any>> implements AnyModel<T> {
171
170
  * When receiving a message from the backend.
172
171
  * We want to notify all listeners with `msg:custom`
173
172
  */
174
- receiveCustomMessage(message: any, buffers?: DataView[]): void {
173
+ receiveCustomMessage(message: any, buffers: readonly DataView[] = []): void {
175
174
  const response = AnyWidgetMessageSchema.safeParse(message);
176
175
  if (response.success) {
177
176
  const data = response.data;
@@ -260,7 +259,7 @@ export async function handleWidgetMessage({
260
259
  }: {
261
260
  modelId: string;
262
261
  msg: AnyWidgetMessage;
263
- buffers: Base64String[];
262
+ buffers: readonly DataView[];
264
263
  modelManager: ModelManager;
265
264
  }): Promise<void> {
266
265
  if (msg.method === "echo_update") {
@@ -30,7 +30,7 @@ export interface ColumnEdit {
30
30
  }
31
31
 
32
32
  export interface Edits {
33
- edits: Array<PositionalEdit | RowEdit | ColumnEdit>;
33
+ edits: (PositionalEdit | RowEdit | ColumnEdit)[];
34
34
  }
35
35
 
36
36
  export type ModifiedGridColumn = GridColumn & {
@@ -238,7 +238,7 @@ const FieldOptions = ({
238
238
  return null;
239
239
  }
240
240
 
241
- let options: Array<[string, FieldFunction[]]> = [];
241
+ let options: [string, FieldFunction[]][] = [];
242
242
 
243
243
  if (field.type === ExpandedType.QUANTITATIVE) {
244
244
  options = [["", QUANTITATIVE_FUNCTIONS]];
@@ -4,6 +4,10 @@ import { isEqual } from "lodash-es";
4
4
  import { Code2Icon, DatabaseIcon, FunctionSquareIcon } from "lucide-react";
5
5
  import { type JSX, memo, useEffect, useRef, useState } from "react";
6
6
  import { z } from "zod";
7
+ import {
8
+ type DownloadAsArgs,
9
+ DownloadAsSchema,
10
+ } from "@/components/data-table/schemas";
7
11
  import type { FieldTypesWithExternalType } from "@/components/data-table/types";
8
12
  import { ReadonlyCode } from "@/components/editor/code/readonly-python-code";
9
13
  import { Spinner } from "@/components/icons/spinner";
@@ -38,6 +42,7 @@ interface Data {
38
42
  label?: string | null;
39
43
  columns: ColumnDataTypes;
40
44
  pageSize: number;
45
+ showDownload: boolean;
41
46
  }
42
47
 
43
48
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
@@ -67,6 +72,7 @@ type PluginFunctions = {
67
72
  data: TableData<T>;
68
73
  total_rows: number;
69
74
  }>;
75
+ download_as: DownloadAsArgs;
70
76
  };
71
77
 
72
78
  // Value is selection, but it is not currently exposed to the user
@@ -77,13 +83,14 @@ export const DataFramePlugin = createPlugin<S>("marimo-dataframe")
77
83
  z.object({
78
84
  label: z.string().nullish(),
79
85
  pageSize: z.number().default(5),
86
+ showDownload: z.boolean().default(true),
80
87
  columns: z
81
88
  .array(z.tuple([z.string().or(z.number()), z.string(), z.string()]))
82
89
  .transform((value) => {
83
90
  const map = new Map<ColumnId, string>();
84
- value.forEach(([key, dataType]) =>
85
- map.set(key as ColumnId, dataType as DataType),
86
- );
91
+ value.forEach(([key, dataType]) => {
92
+ map.set(key as ColumnId, dataType as DataType);
93
+ });
87
94
  return map;
88
95
  }),
89
96
  }),
@@ -124,6 +131,7 @@ export const DataFramePlugin = createPlugin<S>("marimo-dataframe")
124
131
  total_rows: z.number(),
125
132
  }),
126
133
  ),
134
+ download_as: DownloadAsSchema,
127
135
  })
128
136
  .renderer((props) => (
129
137
  <TableProviders>
@@ -141,6 +149,8 @@ interface DataTableProps extends Data, PluginFunctions {
141
149
  value: S;
142
150
  setValue: (value: S) => void;
143
151
  host: HTMLElement;
152
+ showDownload: boolean;
153
+ download_as: DownloadAsArgs;
144
154
  }
145
155
 
146
156
  const EMPTY: Transformations = {
@@ -151,11 +161,13 @@ export const DataFrameComponent = memo(
151
161
  ({
152
162
  columns,
153
163
  pageSize,
164
+ showDownload,
154
165
  value,
155
166
  setValue,
156
167
  get_dataframe,
157
168
  get_column_values,
158
169
  search,
170
+ download_as,
159
171
  host,
160
172
  }: DataTableProps): JSX.Element => {
161
173
  const { data, error, isPending } = useAsyncData(
@@ -270,8 +282,8 @@ export const DataFrameComponent = memo(
270
282
  pagination={true}
271
283
  fieldTypes={field_types}
272
284
  rowHeaders={row_headers || Arrays.EMPTY}
273
- showDownload={false}
274
- download_as={Functions.THROW}
285
+ showDownload={showDownload}
286
+ download_as={download_as}
275
287
  enableSearch={false}
276
288
  showFilters={false}
277
289
  search={search}
@@ -15,7 +15,7 @@ export type NumPyType = string;
15
15
  *
16
16
  * We cannot use a js map, since maps don't preserve keys as ints (e.g. "1" and 1 are the same key)
17
17
  */
18
- export type RawColumnDataTypes = Array<[ColumnId, [DataType, NumPyType]]>;
18
+ export type RawColumnDataTypes = [ColumnId, [DataType, NumPyType]][];
19
19
  /**
20
20
  * Map of column Id and their data types
21
21
  * ES6 maps preserve keys as ints (e.g. "1" and 1 are different keys)
@@ -50,9 +50,9 @@ declare global {
50
50
  consume: (data: ArrayBuffer | string) => void;
51
51
  message: {
52
52
  content: {
53
- events?: Array<{
53
+ events?: {
54
54
  model?: { id?: string };
55
- }>;
55
+ }[];
56
56
  [key: string]: unknown;
57
57
  };
58
58
  buffers: ArrayBuffer[];
@@ -27,7 +27,7 @@ type AxisDatum = unknown;
27
27
 
28
28
  type T =
29
29
  | {
30
- points?: Array<Record<AxisName, AxisDatum>> | Plotly.PlotDatum[];
30
+ points?: Record<AxisName, AxisDatum>[] | Plotly.PlotDatum[];
31
31
  indices?: number[];
32
32
  range?: {
33
33
  x?: number[];
@@ -85,7 +85,7 @@ function initialLayout(figure: Figure): Partial<Plotly.Layout> {
85
85
  };
86
86
  }
87
87
 
88
- const SUNBURST_DATA_KEYS: Array<keyof Plotly.SunburstPlotDatum> = [
88
+ const SUNBURST_DATA_KEYS: (keyof Plotly.SunburstPlotDatum)[] = [
89
89
  "color",
90
90
  "curveNumber",
91
91
  "entry",
@@ -279,7 +279,7 @@ PlotlyComponent.displayName = "PlotlyComponent";
279
279
  */
280
280
  function extractPoints(
281
281
  points: Plotly.PlotDatum[],
282
- ): Array<Record<AxisName, AxisDatum>> {
282
+ ): Record<AxisName, AxisDatum>[] {
283
283
  if (!points) {
284
284
  return [];
285
285
  }
@@ -59,10 +59,10 @@ describe("DATE_MIDDLEWARE", () => {
59
59
  const csv = "Date,Value\n2024-13-45,100\n2024-02-30,200";
60
60
 
61
61
  // When parsing the CSV
62
- const data = parseCsvData(csv, false) as Array<{
62
+ const data = parseCsvData(csv, false) as {
63
63
  Date: string;
64
64
  Value: number;
65
- }>;
65
+ }[];
66
66
 
67
67
  // Then invalid dates should remain as strings
68
68
  expect(typeof data[0].Date).toBe("string");
@@ -41,7 +41,7 @@ const BIG_INT_MIDDLEWARE: Middleware = () => {
41
41
  return result;
42
42
  }
43
43
 
44
- const parsedInt = Number.parseInt(v);
44
+ const parsedInt = Number.parseInt(v, 10);
45
45
  if (isNumber(parsedInt)) {
46
46
  const needsBigInt = Math.abs(parsedInt) > Number.MAX_SAFE_INTEGER;
47
47
  if (!needsBigInt) {
@@ -157,7 +157,7 @@ const LoadedVegaComponent = ({
157
157
  });
158
158
 
159
159
  const renderHelpContent = () => {
160
- const hints: Array<[string, string]> = [];
160
+ const hints: [string, string][] = [];
161
161
  if (ParamNames.hasPoint(names)) {
162
162
  hints.push([
163
163
  "Point selection",
@@ -7,7 +7,7 @@ import type { DataType } from "./vega-loader";
7
7
  // Re-export the vega-loader functions to add TypeScript types
8
8
 
9
9
  export function read<T = object>(
10
- data: string | Record<string, unknown> | Array<Record<string, unknown>>,
10
+ data: string | Record<string, unknown> | Record<string, unknown>[],
11
11
  format:
12
12
  | DataFormat
13
13
  | {
@@ -27,7 +27,7 @@ export interface Loader {
27
27
  load(
28
28
  uri: string,
29
29
  options?: unknown,
30
- ): Promise<string | Record<string, unknown> | Array<Record<string, unknown>>>;
30
+ ): Promise<string | Record<string, unknown> | Record<string, unknown>[]>;
31
31
  sanitize(uri: string, options?: unknown): Promise<{ href: string }>;
32
32
  http(uri: string, options?: unknown): Promise<string>;
33
33
  file(filename: string): Promise<string>;
@@ -35,7 +35,7 @@ interface Data {
35
35
  /**
36
36
  * The labels for each item; raw HTML.
37
37
  */
38
- items: Array<MenuItem | MenuItemGroup>;
38
+ items: (MenuItem | MenuItemGroup)[];
39
39
 
40
40
  /**
41
41
  * The orientation of the menu.
@@ -69,13 +69,12 @@ const RoutesComponent = ({
69
69
  }, [handleFindMatch]);
70
70
 
71
71
  if (!matched) {
72
- // eslint-disable-next-line react/jsx-no-useless-fragment
72
+ // biome-ignore lint/complexity/noUselessFragments: this is intentional
73
73
  return <></>;
74
74
  }
75
75
 
76
76
  const matchedIndex = routes.indexOf(matched);
77
77
  const child = React.Children.toArray(children)[matchedIndex];
78
78
 
79
- // eslint-disable-next-line react/jsx-no-useless-fragment
80
79
  return <>{child}</>;
81
80
  };