@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.
- package/dist/assets/{ConnectedDataExplorerComponent-2wVcyvDj.js → ConnectedDataExplorerComponent-Brtw1DxF.js} +1 -1
- package/dist/assets/{ImageComparisonComponent-D2j6i0hv.js → ImageComparisonComponent-Dxl-PbZX.js} +1 -1
- package/dist/assets/{VegaLite-BckFaf2D.js → VegaLite-BXQF0Cx_.js} +1 -1
- package/dist/assets/_baseEach-BjSm9ht3.js +1 -0
- package/dist/assets/_baseMap-CV4Ezmtf.js +1 -0
- package/dist/assets/_baseUniq-Ci9yZGxz.js +1 -0
- package/dist/assets/{_createAggregator-C5CVY-0t.js → _createAggregator-VFK9K2d9.js} +1 -1
- package/dist/assets/{agent-panel-RGLNjkYe.js → agent-panel-BoscVLCT.js} +7 -7
- package/dist/assets/{any-language-editor-DjuXwGCA.js → any-language-editor-ChaY_VUU.js} +1 -1
- package/dist/assets/{architectureDiagram-W76B3OCA-Dyj4ds_R.js → architectureDiagram-W76B3OCA-CueUUFYd.js} +1 -1
- package/dist/assets/{between-horizontal-start-Dt2aKpPf.js → between-horizontal-start-DAHqmLYT.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-o-i7DDvN.js → blockDiagram-QIGZ2CNN-BYYygyWn.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-DGHEwWrx.js → c4Diagram-FPNF74CW-DAz3xEh1.js} +1 -1
- package/dist/assets/channel-6SqQ2U_X.js +1 -0
- package/dist/assets/chat-panel-DJkOLrw9.js +3 -0
- package/dist/assets/{chunk-4BX2VUAB-BJecb-Ri.js → chunk-4BX2VUAB-8g-RyHdt.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CAATkc4w.js → chunk-55IACEB6-iWZZ8Mt6.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-DPuNbQ-f.js → chunk-FMBD7UC4-knjss4wk.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-C8TWVLiH.js → chunk-K7UQS3LO-DVIwPBgZ.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-DiZZ09q4.js → chunk-QN33PNHL-CBU8pN6I.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-BIUM7usu.js → chunk-QZHKN3VN-5ljElUF4.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-vGTArPBG.js → chunk-TVAH2DTR-DkIdGINc.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-D2KRqp_x.js → chunk-TZMSLE5B-CIFOSTqh.js} +1 -1
- package/dist/assets/{circle-play-cjeNez0N.js → circle-play-BOdsbq5u.js} +1 -1
- package/dist/assets/classDiagram-KNZD7YFC-DVqXcTYf.js +1 -0
- package/dist/assets/classDiagram-v2-RKCZMP56-DVqXcTYf.js +1 -0
- package/dist/assets/{clear-button-C97JtAez.js → clear-button-GAjXl0CQ.js} +1 -1
- package/dist/assets/clone-DSDb0xen.js +1 -0
- package/dist/assets/command-palette-BUXkqoLh.js +1 -0
- package/dist/assets/{common-Du9rSOwD.js → common-DahoYqdi.js} +1 -1
- package/dist/assets/{compile-CZXqyOxa.js → compile-Bg8uJ7vm.js} +1 -1
- package/dist/assets/{cose-bilkent-S5V4N54A-CqUN5Y9b.js → cose-bilkent-S5V4N54A-z_0gqD9K.js} +1 -1
- package/dist/assets/{dagre-5GWH7T2D-RJqTI9DM.js → dagre-5GWH7T2D-BMt7CNXL.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-DZN0q1LV.js → data-grid-overlay-editor-Ctn4XtXx.js} +1 -1
- package/dist/assets/datasources-panel-C7sqRIHs.js +1 -0
- package/dist/assets/{dependency-graph-panel-CEog_O7V.js → dependency-graph-panel-DNajptzv.js} +4 -4
- package/dist/assets/{diagram-N5W7TBWH-D-l4zZ9d.js → diagram-N5W7TBWH-BzwvLvAy.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-CCOmBUt-.js → diagram-QEK2KX5R-DRLJ56FS.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-C_I_9jnZ.js → diagram-S2PKOQOG-Bf8x4KTU.js} +1 -1
- package/dist/assets/{documentation-panel-C1BtMZ3M.js → documentation-panel-Dm6Ozl67.js} +1 -1
- package/dist/assets/{edit-page-B-oevUZ9.js → edit-page-CGc9EjuG.js} +53 -42
- package/dist/assets/{ellipsis-vertical-BEb-J8z6.js → ellipsis-vertical-Bj1YXvZe.js} +1 -1
- package/dist/assets/{empty-state-C99UyDE3.js → empty-state-CYev-D31.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-BePOLi5M.js → erDiagram-AWTI2OKA-DmgzgN_I.js} +1 -1
- package/dist/assets/{error-panel-Bs34jXFh.js → error-panel-BYG4twCa.js} +1 -1
- package/dist/assets/{file-explorer-panel-Ck6UL861.js → file-explorer-panel-BSMiOApi.js} +1 -1
- package/dist/assets/{flowDiagram-PVAE7QVJ-BgjFu5l7.js → flowDiagram-PVAE7QVJ-BdRKkajr.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-YOPb3XSV.js → ganttDiagram-OWAHRB6G-lfRAMnq_.js} +5 -5
- package/dist/assets/{gitGraphDiagram-NY62KEGX-CGhqaDTy.js → gitGraphDiagram-NY62KEGX-CQVTIrHF.js} +1 -1
- package/dist/assets/{glide-data-editor-9QUH6iso.js → glide-data-editor-D5A4pou7.js} +4 -4
- package/dist/assets/{graph-DQQFGrho.js → graph-CBNo279v.js} +1 -1
- package/dist/assets/{home-page-DRKpPCrF.js → home-page-CmdznBJR.js} +2 -2
- package/dist/assets/{index-SGLNXrGP.js → index-0dfGh-Gj.js} +1 -1
- package/dist/assets/{index-aE43R74q.js → index-BDYVSSzB.js} +1 -1
- package/dist/assets/{index-BJNCMUmG.js → index-B_KyDZ94.js} +1 -1
- package/dist/assets/{index-BjgnbONl.js → index-Bfy-I_lW.js} +1 -1
- package/dist/assets/{index-CUFv_thQ.js → index-Bh98Tp-z.js} +1 -1
- package/dist/assets/{index-C2MD0vgD.js → index-BhroIwBL.js} +1 -1
- package/dist/assets/{index-DdnKZNxM.js → index-BtQtesaI.js} +1 -1
- package/dist/assets/index-C0iXCvyY.css +1 -0
- package/dist/assets/index-C1SHFMCp.js +581 -0
- package/dist/assets/{index-C_tkBKNO.js → index-C6DWtSls.js} +1 -1
- package/dist/assets/{index-Aeo6WiK7.js → index-C71cdkH-.js} +1 -1
- package/dist/assets/{index-G5QZppK2.js → index-CT_FTqvK.js} +1 -1
- package/dist/assets/{index-B8jXZ12t.js → index-CU5rRr66.js} +1 -1
- package/dist/assets/{index-BAbIIxHU.js → index-Cb6duXQm.js} +1 -1
- package/dist/assets/{index-BW3k9Gss.js → index-D23e9zQj.js} +1 -1
- package/dist/assets/index-DUGecC2Z.js +68 -0
- package/dist/assets/{index-CFKO7WXI.js → index-DcGIOAQi.js} +1 -1
- package/dist/assets/{index-ClzeQrN7.js → index-PJfa9qXY.js} +1 -1
- package/dist/assets/{index-C1ez98sk.js → index-SPslPC2B.js} +1 -1
- package/dist/assets/{index-BprjMYH5.js → index-VPQlo4Uz.js} +1 -1
- package/dist/assets/{index-CfaDbEdi.js → index-qbTLKWyG.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-DBu8p9gd.js +2 -0
- package/dist/assets/{isEmpty-D-4c7sMv.js → isEmpty-CnOLuQIv.js} +1 -1
- package/dist/assets/{journeyDiagram-BIP6EPQ6-C94u3Mv3.js → journeyDiagram-BIP6EPQ6-6U_vHJBH.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-BEXYFzz7.js → kanban-definition-6OIFK2YF-DgnR14ys.js} +1 -1
- package/dist/assets/{layout-Bz2BJ2ru.js → layout-RHmq4fP9.js} +1 -1
- package/dist/assets/{linear-D8s7K76e.js → linear-CLdOVPGV.js} +1 -1
- package/dist/assets/links-Dd1icsEk.js +7 -0
- package/dist/assets/{logs-panel-DC7wpmPz.js → logs-panel-CjbuhBLx.js} +1 -1
- package/dist/assets/{markdown-renderer-DRdSWR9X.js → markdown-renderer-X5YJvAZq.js} +3 -3
- package/dist/assets/{mermaid-Y3x4hmD0.js → mermaid-Bl2T5oEC.js} +1 -1
- package/dist/assets/{mermaid.core-DzthE35Y.js → mermaid.core-CfukBvGI.js} +4 -4
- package/dist/assets/min-BXIes1Za.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-DktvuLe1.js → mindmap-definition-Q6HEUPPD-BXCjP4Lu.js} +1 -1
- package/dist/assets/{number-overlay-editor-BEfwI1IT.js → number-overlay-editor-BUyqkSes.js} +1 -1
- package/dist/assets/{outline-panel-CdsnAy2w.js → outline-panel-BvGcPKdd.js} +1 -1
- package/dist/assets/{packages-panel-DiTA-d_D.js → packages-panel-BichDQWG.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-DQDNQ-de.js → pieDiagram-ADFJNKIX-CMzJFIJM.js} +1 -1
- package/dist/assets/{quadrantDiagram-LMRXKWRM-0kgIXc2-.js → quadrantDiagram-LMRXKWRM-CfGssUlO.js} +1 -1
- package/dist/assets/{react-plotly-DJqqfM7c.js → react-plotly-DR3hV0HW.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-B5rb0ypd.js → requirementDiagram-4UW4RH46-CfrFolth.js} +1 -1
- package/dist/assets/{run-page-CFmLrv1R.js → run-page-Bqd_4ePD.js} +1 -1
- package/dist/assets/{sankeyDiagram-GR3RE2ED-Dom7IlnF.js → sankeyDiagram-GR3RE2ED-D_UttKU0.js} +1 -1
- package/dist/assets/{scratchpad-panel-CuHWpHO8.js → scratchpad-panel-D5N15ji1.js} +1 -1
- package/dist/assets/secrets-panel-BpbnAO4R.js +1 -0
- package/dist/assets/{sequenceDiagram-C3RYC4MD-PNJWXQbw.js → sequenceDiagram-C3RYC4MD-MdfQQApP.js} +1 -1
- package/dist/assets/{slides-component-CJgaTRZ0.js → slides-component-C0z7rXmk.js} +1 -1
- package/dist/assets/{snippets-panel-B2EC1txM.js → snippets-panel-wlpZ_Wzx.js} +1 -1
- package/dist/assets/sortBy-BW_zNHP6.js +1 -0
- package/dist/assets/{state-CWict9RU.js → state-CDooX-dk.js} +1 -1
- package/dist/assets/{stateDiagram-KXAO66HF-BE58aJnr.js → stateDiagram-KXAO66HF-H7kfw3ot.js} +1 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-YMeb9qMR.js +1 -0
- package/dist/assets/{storage-DRaR04wR.js → storage-b1QCapTq.js} +6 -6
- package/dist/assets/{terminal-BX3Su5q7.js → terminal-CPV44BXz.js} +1 -1
- package/dist/assets/{time-hUzZfpNE.js → time-DDy3xv5Y.js} +1 -1
- package/dist/assets/{timeline-definition-XQNQX7LJ-CqQP9t51.js → timeline-definition-XQNQX7LJ-J-cPRT2_.js} +1 -1
- package/dist/assets/{tracing-B10Q1n-L.js → tracing-3eHHRUiJ.js} +2 -2
- package/dist/assets/{tracing-panel-Du8WCnno.js → tracing-panel-BMgy3D7d.js} +2 -2
- package/dist/assets/{trash-B81GTiv6.js → trash--tonOuDe.js} +1 -1
- package/dist/assets/{tree-6vW2ogkh.js → tree-ouIGEsVg.js} +1 -1
- package/dist/assets/{treemap-75Q7IDZK-CdwDwwsz.js → treemap-75Q7IDZK-CzJTJ_3R.js} +20 -20
- package/dist/assets/{variable-panel-D5qgJI7k.js → variable-panel-sFTn4Oih.js} +1 -1
- package/dist/assets/{vega-component-DJaJWMJM.js → vega-component-BkPkzX9r.js} +1 -1
- package/dist/assets/{xychartDiagram-6GGTOJPD-WFtXqaM9.js → xychartDiagram-6GGTOJPD-BZ8WOb_8.js} +1 -1
- package/dist/index.html +10 -3
- package/package.json +8 -8
- package/src/__mocks__/common.ts +5 -3
- package/src/__mocks__/notebook.ts +2 -2
- package/src/__mocks__/requests.ts +1 -0
- package/src/__tests__/main.test.tsx +2 -2
- package/src/components/ai/ai-provider-icon.tsx +2 -0
- package/src/components/app-config/ai-config.tsx +32 -1
- package/src/components/app-config/common.tsx +2 -2
- package/src/components/app-config/user-config-form.tsx +26 -0
- package/src/components/audio/audio-recorder.tsx +0 -1
- package/src/components/chat/acp/blocks.tsx +2 -2
- package/src/components/chat/acp/thread.tsx +3 -5
- package/src/components/chat/acp/utils.ts +5 -5
- package/src/components/chat/chat-panel.tsx +1 -1
- package/src/components/data-table/__tests__/columns.test.tsx +38 -0
- package/src/components/data-table/__tests__/data-table.test.tsx +2 -2
- package/src/components/data-table/cell-hover-template/feature.ts +1 -1
- package/src/components/data-table/cell-hover-template/types.ts +1 -1
- package/src/components/data-table/charts/__tests__/altair-generator.test.ts +1 -1
- package/src/components/data-table/charts/chart-spec/tooltips.ts +3 -3
- package/src/components/data-table/charts/components/chart-items.tsx +1 -1
- package/src/components/data-table/charts/components/form-fields.tsx +2 -2
- package/src/components/data-table/charts/constants.ts +1 -1
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/column-summary/chart-spec-model.tsx +2 -2
- package/src/components/data-table/columns.tsx +22 -3
- package/src/components/data-table/data-table.tsx +35 -3
- package/src/components/data-table/date-popover.tsx +1 -1
- package/src/components/data-table/download-actions.tsx +1 -1
- package/src/components/data-table/range-focus/__tests__/utils.test.ts +5 -5
- package/src/components/data-table/renderers.tsx +22 -13
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
- package/src/components/data-table/schemas.ts +16 -0
- package/src/components/data-table/types.ts +4 -3
- package/src/components/datasources/column-preview.tsx +9 -6
- package/src/components/debugger/debugger-code.tsx +1 -1
- package/src/components/dependency-graph/custom-node.tsx +15 -6
- package/src/components/dependency-graph/dependency-graph-minimap.tsx +2 -2
- package/src/components/dependency-graph/dependency-graph-tree.tsx +2 -2
- package/src/components/dependency-graph/dependency-graph.tsx +1 -1
- package/src/components/dependency-graph/elements.ts +7 -7
- package/src/components/dependency-graph/utils/changes.ts +4 -4
- package/src/components/editor/Cell.tsx +7 -1
- package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
- package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +1 -1
- package/src/components/editor/chrome/panels/packages-panel.tsx +1 -1
- package/src/components/editor/columns/storage.ts +1 -1
- package/src/components/editor/database/__tests__/__snapshots__/as-code.test.ts.snap +36 -0
- package/src/components/editor/database/__tests__/as-code.test.ts +30 -7
- package/src/components/editor/database/add-database-form.tsx +11 -0
- package/src/components/editor/database/as-code.ts +104 -5
- package/src/components/editor/database/schemas.ts +36 -18
- package/src/components/editor/errors/auto-fix.tsx +12 -2
- package/src/components/editor/errors/sql-validation-errors.tsx +40 -0
- package/src/components/editor/navigation/clipboard.ts +2 -2
- package/src/components/editor/output/ConsoleOutput.tsx +14 -2
- package/src/components/editor/output/JsonOutput.tsx +1 -1
- package/src/components/editor/output/MarimoErrorOutput.tsx +60 -1
- package/src/components/editor/output/MarimoTracebackOutput.tsx +17 -2
- package/src/components/editor/renderers/grid-layout/types.ts +2 -2
- package/src/components/editor/renderers/plugins.ts +1 -1
- package/src/components/editor/renderers/types.ts +1 -1
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +7 -7
- package/src/components/forms/form.tsx +5 -5
- package/src/components/ui/links.tsx +1 -0
- package/src/core/ai/__tests__/model-registry.test.ts +0 -10
- package/src/core/ai/context/providers/cell-output.ts +1 -18
- package/src/core/ai/context/providers/error.ts +2 -2
- package/src/core/ai/ids/ids.ts +1 -0
- package/src/core/ai/model-registry.ts +2 -1
- package/src/core/cells/cells.ts +5 -5
- package/src/core/cells/logs.ts +1 -1
- package/src/core/cells/types.ts +1 -1
- package/src/core/codemirror/__tests__/format.test.ts +6 -0
- package/src/core/codemirror/cells/traceback-decorations.ts +1 -1
- package/src/core/codemirror/editing/commands.ts +2 -2
- package/src/core/codemirror/find-replace/navigate.ts +1 -1
- package/src/core/codemirror/language/__tests__/extension.test.ts +24 -0
- package/src/core/codemirror/language/__tests__/sql-validation.test.ts +133 -0
- package/src/core/codemirror/language/__tests__/sql.test.ts +764 -79
- package/src/core/codemirror/language/languages/markdown.ts +4 -1
- package/src/core/codemirror/language/languages/sql/banner-validation-errors.ts +85 -0
- package/src/core/codemirror/language/languages/sql/completion-builder.ts +160 -0
- package/src/core/codemirror/language/languages/sql/completion-sources.tsx +9 -3
- package/src/core/codemirror/language/languages/sql/completion-store.ts +46 -50
- package/src/core/codemirror/language/languages/sql/renderers.tsx +485 -0
- package/src/core/codemirror/language/languages/sql/sql-mode.ts +20 -0
- package/src/core/codemirror/language/languages/sql/sql.ts +218 -4
- package/src/core/codemirror/language/languages/sql/utils.ts +4 -1
- package/src/core/codemirror/language/panel/panel.tsx +8 -2
- package/src/core/codemirror/language/panel/sql.tsx +86 -4
- package/src/core/codemirror/language/utils/ast.ts +3 -3
- package/src/core/codemirror/lsp/federated-lsp.ts +4 -4
- package/src/core/codemirror/lsp/lens.ts +4 -4
- package/src/core/codemirror/lsp/notebook-lsp.ts +1 -1
- package/src/core/codemirror/lsp/types.ts +1 -1
- package/src/core/codemirror/markdown/completions.ts +1 -1
- package/src/core/codemirror/reactive-references/analyzer.ts +2 -2
- package/src/core/codemirror/rtc/loro/awareness.ts +1 -1
- package/src/core/config/config-schema.ts +1 -0
- package/src/core/config/feature-flag.tsx +6 -2
- package/src/core/datasets/request-registry.ts +24 -1
- package/src/core/dom/events.ts +1 -1
- package/src/core/dom/outline.ts +2 -2
- package/src/core/dom/uiregistry.ts +2 -8
- package/src/core/errors/__tests__/errors.test.ts +22 -4
- package/src/core/errors/errors.ts +29 -1
- package/src/core/errors/state.ts +1 -1
- package/src/core/islands/bridge.ts +1 -0
- package/src/core/islands/main.ts +3 -2
- package/src/core/islands/parse.ts +1 -3
- package/src/core/kernel/messages.ts +2 -1
- package/src/core/network/CachingRequestRegistry.ts +74 -0
- package/src/core/network/DeferredRequestRegistry.ts +3 -1
- package/src/core/network/__tests__/CachingRequestRegistry.test.ts +73 -0
- package/src/core/network/requests-network.ts +7 -0
- package/src/core/network/requests-static.ts +1 -0
- package/src/core/network/requests-toasting.ts +1 -0
- package/src/core/network/types.ts +3 -1
- package/src/core/variables/state.ts +2 -2
- package/src/core/wasm/__tests__/state.test.ts +1 -1
- package/src/core/wasm/bridge.ts +5 -0
- package/src/core/websocket/useMarimoWebSocket.tsx +9 -2
- package/src/custom.d.ts +1 -1
- package/src/hooks/useCellRenderCount.ts +1 -0
- package/src/hooks/useResizeHandle.ts +4 -1
- package/src/plugins/core/RenderHTML.tsx +1 -2
- package/src/plugins/core/registerReactComponent.tsx +23 -19
- package/src/plugins/impl/DataTablePlugin.tsx +18 -6
- package/src/plugins/impl/FileUploadPlugin.tsx +1 -1
- package/src/plugins/impl/RefreshPlugin.tsx +1 -1
- package/src/plugins/impl/SliderPlugin.tsx +4 -0
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +27 -9
- package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +58 -2
- package/src/plugins/impl/anywidget/__tests__/model.test.ts +3 -4
- package/src/plugins/impl/anywidget/model.ts +2 -3
- package/src/plugins/impl/data-editor/types.ts +1 -1
- package/src/plugins/impl/data-explorer/components/query-form.tsx +1 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +17 -5
- package/src/plugins/impl/data-frames/types.ts +1 -1
- package/src/plugins/impl/panel/PanelPlugin.tsx +2 -2
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
- package/src/plugins/impl/vega/__tests__/loader.test.ts +2 -2
- package/src/plugins/impl/vega/loader.ts +1 -1
- package/src/plugins/impl/vega/vega-component.tsx +1 -1
- package/src/plugins/impl/vega/vega-loader.ts +2 -2
- package/src/plugins/layout/NavigationMenuPlugin.tsx +1 -1
- package/src/plugins/layout/RoutesPlugin.tsx +1 -2
- package/src/plugins/plugins.ts +2 -2
- package/src/stories/dataframe.stories.tsx +2 -0
- package/src/utils/Logger.ts +1 -1
- package/src/utils/__tests__/data-views.test.ts +30 -68
- package/src/utils/__tests__/dom.test.ts +167 -0
- package/src/utils/__tests__/id-tree.test.ts +49 -1
- package/src/utils/__tests__/storage.test.ts +1 -1
- package/src/utils/__tests__/traceback.test.ts +13 -2
- package/src/utils/arrays.ts +1 -1
- package/src/utils/createReducer.ts +1 -5
- package/src/utils/data-views.ts +6 -19
- package/src/utils/dom.ts +55 -0
- package/src/utils/edit-distance.ts +1 -1
- package/src/utils/fileToBase64.ts +1 -1
- package/src/utils/id-tree.tsx +20 -18
- package/src/utils/json/base64.ts +13 -0
- package/src/utils/json/json-parser.ts +2 -2
- package/src/utils/lru.ts +4 -0
- package/src/utils/mergeRefs.ts +1 -1
- package/src/utils/objects.ts +3 -3
- package/src/utils/pluralize.ts +1 -1
- package/src/utils/routes.ts +2 -2
- package/src/utils/sets.ts +1 -1
- package/src/utils/traceback.ts +45 -15
- package/src/utils/tracer.ts +11 -9
- package/dist/assets/_baseEach-CvTX9w0Y.js +0 -1
- package/dist/assets/_baseMap-CtlwA90f.js +0 -1
- package/dist/assets/_baseUniq-BKktIGQ1.js +0 -1
- package/dist/assets/channel-Co6iMgWq.js +0 -1
- package/dist/assets/chat-panel-9alr8FS4.js +0 -3
- package/dist/assets/classDiagram-KNZD7YFC-BbJ0rY3y.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-BbJ0rY3y.js +0 -1
- package/dist/assets/clone-BMP0PsTa.js +0 -1
- package/dist/assets/command-palette-B93Pjcky.js +0 -1
- package/dist/assets/datasources-panel-v7H3cR0p.js +0 -1
- package/dist/assets/index-2252nrk6.js +0 -68
- package/dist/assets/index-C7CoaNFb.js +0 -578
- package/dist/assets/index-DadI618h.css +0 -1
- package/dist/assets/infoDiagram-STP46IZ2-CJLOpSAf.js +0 -2
- package/dist/assets/links-BpXlz1GG.js +0 -7
- package/dist/assets/min-BBO3-1Hg.js +0 -1
- package/dist/assets/secrets-panel-CfHc5YD0.js +0 -1
- package/dist/assets/sortBy-DZnlX29-.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-CdThjimL.js +0 -1
- 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 {
|
|
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
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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:
|
|
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:
|
|
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 =
|
|
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:
|
|
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}
|
|
@@ -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 {
|
|
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?:
|
|
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={
|
|
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 (
|
|
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 {
|
|
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:
|
|
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,
|
|
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:
|
|
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 },
|
|
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
|
|
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:
|
|
262
|
+
buffers: readonly DataView[];
|
|
264
263
|
modelManager: ModelManager;
|
|
265
264
|
}): Promise<void> {
|
|
266
265
|
if (msg.method === "echo_update") {
|
|
@@ -238,7 +238,7 @@ const FieldOptions = ({
|
|
|
238
238
|
return null;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
let options:
|
|
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={
|
|
274
|
-
download_as={
|
|
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 =
|
|
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)
|
|
@@ -27,7 +27,7 @@ type AxisDatum = unknown;
|
|
|
27
27
|
|
|
28
28
|
type T =
|
|
29
29
|
| {
|
|
30
|
-
points?:
|
|
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:
|
|
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
|
-
):
|
|
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
|
|
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) {
|
|
@@ -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> |
|
|
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> |
|
|
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>;
|
|
@@ -69,13 +69,12 @@ const RoutesComponent = ({
|
|
|
69
69
|
}, [handleFindMatch]);
|
|
70
70
|
|
|
71
71
|
if (!matched) {
|
|
72
|
-
//
|
|
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
|
};
|