@marimo-team/frontend 0.16.2 → 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-B5cPvWoQ.js → ConnectedDataExplorerComponent-Brtw1DxF.js} +1 -1
- package/dist/assets/{ImageComparisonComponent-CqR26LSv.js → ImageComparisonComponent-Dxl-PbZX.js} +1 -1
- package/dist/assets/{VegaLite-DvQDATwI.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-ZcHkHPNJ.js → _createAggregator-VFK9K2d9.js} +1 -1
- package/dist/assets/{agent-panel-B91RoLct.js → agent-panel-BoscVLCT.js} +7 -7
- package/dist/assets/{any-language-editor-CxfHcm5h.js → any-language-editor-ChaY_VUU.js} +1 -1
- package/dist/assets/{architectureDiagram-W76B3OCA-BQsvK8uR.js → architectureDiagram-W76B3OCA-CueUUFYd.js} +1 -1
- package/dist/assets/{between-horizontal-start-BmYToIaM.js → between-horizontal-start-DAHqmLYT.js} +1 -1
- package/dist/assets/{blockDiagram-QIGZ2CNN-r3HgCj4w.js → blockDiagram-QIGZ2CNN-BYYygyWn.js} +1 -1
- package/dist/assets/{c4Diagram-FPNF74CW-BJbPNt41.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-Dv4MZ9Hj.js → chunk-4BX2VUAB-8g-RyHdt.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CM4AHquB.js → chunk-55IACEB6-iWZZ8Mt6.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-C_Zz0ENB.js → chunk-FMBD7UC4-knjss4wk.js} +1 -1
- package/dist/assets/{chunk-K7UQS3LO-DYSmiXYq.js → chunk-K7UQS3LO-DVIwPBgZ.js} +1 -1
- package/dist/assets/{chunk-QN33PNHL-QM4OPuQP.js → chunk-QN33PNHL-CBU8pN6I.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-CfAsGyeB.js → chunk-QZHKN3VN-5ljElUF4.js} +1 -1
- package/dist/assets/{chunk-TVAH2DTR-6j_Cpjsi.js → chunk-TVAH2DTR-DkIdGINc.js} +1 -1
- package/dist/assets/{chunk-TZMSLE5B-BHslFJQE.js → chunk-TZMSLE5B-CIFOSTqh.js} +1 -1
- package/dist/assets/{circle-play-CK3UZRYQ.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-C4fDVSv8.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-D-lbuUwz.js → common-DahoYqdi.js} +1 -1
- package/dist/assets/{compile-DVQe1Mzk.js → compile-Bg8uJ7vm.js} +1 -1
- package/dist/assets/{cose-bilkent-S5V4N54A-D-IS7WC8.js → cose-bilkent-S5V4N54A-z_0gqD9K.js} +1 -1
- package/dist/assets/{dagre-5GWH7T2D-lYu-tEWT.js → dagre-5GWH7T2D-BMt7CNXL.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-C5peOCit.js → data-grid-overlay-editor-Ctn4XtXx.js} +1 -1
- package/dist/assets/{datasources-panel-D3NA20uZ.js → datasources-panel-C7sqRIHs.js} +1 -1
- package/dist/assets/{dependency-graph-panel-BGVYOfkV.js → dependency-graph-panel-DNajptzv.js} +4 -4
- package/dist/assets/{diagram-N5W7TBWH-BnvIuYUp.js → diagram-N5W7TBWH-BzwvLvAy.js} +1 -1
- package/dist/assets/{diagram-QEK2KX5R-DemedRK3.js → diagram-QEK2KX5R-DRLJ56FS.js} +1 -1
- package/dist/assets/{diagram-S2PKOQOG-iiY7AuyH.js → diagram-S2PKOQOG-Bf8x4KTU.js} +1 -1
- package/dist/assets/{documentation-panel-C3dSwOSQ.js → documentation-panel-Dm6Ozl67.js} +1 -1
- package/dist/assets/edit-page-CGc9EjuG.js +140 -0
- package/dist/assets/{ellipsis-vertical-CazJl8M7.js → ellipsis-vertical-Bj1YXvZe.js} +1 -1
- package/dist/assets/{empty-state-DW308mFO.js → empty-state-CYev-D31.js} +1 -1
- package/dist/assets/{erDiagram-AWTI2OKA-6wQ8Ugg0.js → erDiagram-AWTI2OKA-DmgzgN_I.js} +1 -1
- package/dist/assets/{error-panel-D1VnJ1yP.js → error-panel-BYG4twCa.js} +1 -1
- package/dist/assets/{file-explorer-panel-0oVd4t-D.js → file-explorer-panel-BSMiOApi.js} +1 -1
- package/dist/assets/{flowDiagram-PVAE7QVJ-C55IUWjm.js → flowDiagram-PVAE7QVJ-BdRKkajr.js} +1 -1
- package/dist/assets/{ganttDiagram-OWAHRB6G-DmqCM6ME.js → ganttDiagram-OWAHRB6G-lfRAMnq_.js} +5 -5
- package/dist/assets/{gitGraphDiagram-NY62KEGX-DBvhAeM_.js → gitGraphDiagram-NY62KEGX-CQVTIrHF.js} +1 -1
- package/dist/assets/{glide-data-editor-CHNuHidQ.js → glide-data-editor-D5A4pou7.js} +11 -11
- package/dist/assets/{graph-CG6BgUWQ.js → graph-CBNo279v.js} +1 -1
- package/dist/assets/{home-page-dgivXuSR.js → home-page-CmdznBJR.js} +3 -3
- package/dist/assets/{index-BTGpssVX.js → index-0dfGh-Gj.js} +1 -1
- package/dist/assets/{index-C7dtgr9A.js → index-BDYVSSzB.js} +1 -1
- package/dist/assets/{index-C02SqeRj.js → index-B_KyDZ94.js} +1 -1
- package/dist/assets/{index-mkubqy9-.js → index-Bfy-I_lW.js} +1 -1
- package/dist/assets/{index-BelfnXwL.js → index-Bh98Tp-z.js} +1 -1
- package/dist/assets/{index-CAQvMTzM.js → index-BhroIwBL.js} +1 -1
- package/dist/assets/{index-BneyUujp.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-Csd6QrCV.js → index-C6DWtSls.js} +1 -1
- package/dist/assets/{index-BYVZlBF8.js → index-C71cdkH-.js} +1 -1
- package/dist/assets/{index-z4krxQ4j.js → index-CT_FTqvK.js} +1 -1
- package/dist/assets/{index-Db36XTG_.js → index-CU5rRr66.js} +1 -1
- package/dist/assets/{index-CtPksxf0.js → index-Cb6duXQm.js} +1 -1
- package/dist/assets/{index-DAZ-9ri2.js → index-D23e9zQj.js} +1 -1
- package/dist/assets/index-DUGecC2Z.js +68 -0
- package/dist/assets/{index-M_pBKDSe.js → index-DcGIOAQi.js} +1 -1
- package/dist/assets/{index-DONRrmA2.js → index-PJfa9qXY.js} +1 -1
- package/dist/assets/{index-sbO9UaUU.js → index-SPslPC2B.js} +1 -1
- package/dist/assets/{index-DdIhdEVw.js → index-VPQlo4Uz.js} +1 -1
- package/dist/assets/{index-_luCZMLM.js → index-qbTLKWyG.js} +1 -1
- package/dist/assets/infoDiagram-STP46IZ2-DBu8p9gd.js +2 -0
- package/dist/assets/{isEmpty-CqX_YTIf.js → isEmpty-CnOLuQIv.js} +1 -1
- package/dist/assets/{journeyDiagram-BIP6EPQ6-Y5w_Tqe_.js → journeyDiagram-BIP6EPQ6-6U_vHJBH.js} +1 -1
- package/dist/assets/{kanban-definition-6OIFK2YF-DbXs5Rxi.js → kanban-definition-6OIFK2YF-DgnR14ys.js} +1 -1
- package/dist/assets/{layout-BCNPDACj.js → layout-RHmq4fP9.js} +1 -1
- package/dist/assets/{linear-uO6UVhXt.js → linear-CLdOVPGV.js} +1 -1
- package/dist/assets/links-Dd1icsEk.js +7 -0
- package/dist/assets/{logs-panel-BEQ1eRUp.js → logs-panel-CjbuhBLx.js} +1 -1
- package/dist/assets/{markdown-renderer-Dmzbb00W.js → markdown-renderer-X5YJvAZq.js} +3 -3
- package/dist/assets/{mermaid-qRc4MXIj.js → mermaid-Bl2T5oEC.js} +1 -1
- package/dist/assets/{mermaid.core-CvvJtCRj.js → mermaid.core-CfukBvGI.js} +4 -4
- package/dist/assets/min-BXIes1Za.js +1 -0
- package/dist/assets/{mindmap-definition-Q6HEUPPD-G5NognM-.js → mindmap-definition-Q6HEUPPD-BXCjP4Lu.js} +1 -1
- package/dist/assets/{number-overlay-editor-DPr5sHFu.js → number-overlay-editor-BUyqkSes.js} +1 -1
- package/dist/assets/{outline-panel-gxQXvVi4.js → outline-panel-BvGcPKdd.js} +1 -1
- package/dist/assets/{packages-panel-B1T0VPlg.js → packages-panel-BichDQWG.js} +1 -1
- package/dist/assets/{pieDiagram-ADFJNKIX-DK9SHkfc.js → pieDiagram-ADFJNKIX-CMzJFIJM.js} +1 -1
- package/dist/assets/{quadrantDiagram-LMRXKWRM-D1DdWF8C.js → quadrantDiagram-LMRXKWRM-CfGssUlO.js} +1 -1
- package/dist/assets/{react-plotly-CTwajqCb.js → react-plotly-DR3hV0HW.js} +1 -1
- package/dist/assets/{requirementDiagram-4UW4RH46-DnjDAypr.js → requirementDiagram-4UW4RH46-CfrFolth.js} +1 -1
- package/dist/assets/{run-page-CQY9im22.js → run-page-Bqd_4ePD.js} +1 -1
- package/dist/assets/{sankeyDiagram-GR3RE2ED-B67Va-ER.js → sankeyDiagram-GR3RE2ED-D_UttKU0.js} +1 -1
- package/dist/assets/scratchpad-panel-D5N15ji1.js +1 -0
- package/dist/assets/secrets-panel-BpbnAO4R.js +1 -0
- package/dist/assets/{sequenceDiagram-C3RYC4MD-DiWgZPtN.js → sequenceDiagram-C3RYC4MD-MdfQQApP.js} +1 -1
- package/dist/assets/{slides-component-DhpPRtQp.js → slides-component-C0z7rXmk.js} +1 -1
- package/dist/assets/{snippets-panel-CLkBXhJ2.js → snippets-panel-wlpZ_Wzx.js} +1 -1
- package/dist/assets/{sortBy-D4OG7w4O.js → sortBy-BW_zNHP6.js} +1 -1
- package/dist/assets/{state-Dz_3JyED.js → state-CDooX-dk.js} +1 -1
- package/dist/assets/{stateDiagram-KXAO66HF-ByF2AULw.js → stateDiagram-KXAO66HF-H7kfw3ot.js} +1 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-YMeb9qMR.js +1 -0
- package/dist/assets/{storage-Dr0CC44z.js → storage-b1QCapTq.js} +6 -6
- package/dist/assets/{terminal-BtdissBf.js → terminal-CPV44BXz.js} +1 -1
- package/dist/assets/{time-DKdOTnQg.js → time-DDy3xv5Y.js} +1 -1
- package/dist/assets/{timeline-definition-XQNQX7LJ-DzER9bf6.js → timeline-definition-XQNQX7LJ-J-cPRT2_.js} +1 -1
- package/dist/assets/{tracing-Dpx5M-u3.js → tracing-3eHHRUiJ.js} +2 -2
- package/dist/assets/{tracing-panel-hCjBkSER.js → tracing-panel-BMgy3D7d.js} +2 -2
- package/dist/assets/{trash-C6Ko-g5q.js → trash--tonOuDe.js} +1 -1
- package/dist/assets/{tree-BHN2gcCF.js → tree-ouIGEsVg.js} +6 -6
- package/dist/assets/{treemap-75Q7IDZK-DR79Mhzt.js → treemap-75Q7IDZK-CzJTJ_3R.js} +20 -20
- package/dist/assets/{variable-panel-PFBCFz36.js → variable-panel-sFTn4Oih.js} +1 -1
- package/dist/assets/{vega-component-Db6-uY4C.js → vega-component-BkPkzX9r.js} +1 -1
- package/dist/assets/{xychartDiagram-6GGTOJPD-DWzBP3tZ.js → xychartDiagram-6GGTOJPD-BZ8WOb_8.js} +1 -1
- package/dist/index.html +10 -3
- package/package.json +6 -6
- package/src/__mocks__/common.ts +5 -3
- package/src/__mocks__/notebook.ts +2 -2
- 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__/data-table.test.tsx +2 -2
- 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 +1 -1
- 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 +6 -5
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
- 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 +6 -2
- 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 +12 -6
- package/src/components/editor/navigation/clipboard.ts +2 -2
- package/src/components/editor/output/ConsoleOutput.tsx +1 -1
- package/src/components/editor/output/JsonOutput.tsx +1 -1
- package/src/components/editor/output/MarimoErrorOutput.tsx +25 -25
- 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/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 +1 -1
- package/src/core/codemirror/language/__tests__/sql-validation.test.ts +1 -1
- 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/{validation-errors.ts → banner-validation-errors.ts} +9 -3
- 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.ts +151 -24
- package/src/core/codemirror/language/languages/sql/utils.ts +4 -1
- package/src/core/codemirror/language/panel/sql.tsx +6 -1
- 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 +3 -1
- package/src/core/datasets/request-registry.ts +17 -10
- 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/main.ts +2 -2
- package/src/core/islands/parse.ts +1 -3
- package/src/core/kernel/messages.ts +1 -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/types.ts +1 -1
- package/src/core/variables/state.ts +2 -2
- package/src/core/wasm/__tests__/state.test.ts +1 -1
- package/src/core/websocket/useMarimoWebSocket.tsx +5 -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/impl/DataTablePlugin.tsx +7 -2
- 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/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/utils/Logger.ts +1 -1
- package/src/utils/__tests__/data-views.test.ts +30 -68
- package/src/utils/__tests__/dom.test.ts +10 -10
- 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/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--KDTwKbG.js +0 -1
- package/dist/assets/_baseMap-Cu3o-eyO.js +0 -1
- package/dist/assets/_baseUniq-y7ZXnMo1.js +0 -1
- package/dist/assets/channel-DFaEx1fu.js +0 -1
- package/dist/assets/chat-panel-IoPMv8e2.js +0 -3
- package/dist/assets/classDiagram-KNZD7YFC-BsZtvV5O.js +0 -1
- package/dist/assets/classDiagram-v2-RKCZMP56-BsZtvV5O.js +0 -1
- package/dist/assets/clone-YBEvPE-s.js +0 -1
- package/dist/assets/command-palette-D7hOfvf6.js +0 -1
- package/dist/assets/edit-page-C5TsEeSo.js +0 -129
- package/dist/assets/index-CGDMlQfO.css +0 -1
- package/dist/assets/index-CelXfcd8.js +0 -580
- package/dist/assets/index-Cxyk7pt-.js +0 -68
- package/dist/assets/infoDiagram-STP46IZ2-wTALjfPc.js +0 -2
- package/dist/assets/links-Drv7cJgN.js +0 -7
- package/dist/assets/min-DYUOb1RR.js +0 -1
- package/dist/assets/scratchpad-panel-DlDfcDtW.js +0 -1
- package/dist/assets/secrets-panel-BDGyuGZA.js +0 -1
- package/dist/assets/stateDiagram-v2-UMBNRL4Z-CtBJqosP.js +0 -1
- package/src/__tests__/lru.test.ts +0 -74
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
ChdbConnectionSchema,
|
|
40
40
|
ClickhouseConnectionSchema,
|
|
41
41
|
type DatabaseConnection,
|
|
42
|
+
DatabricksConnectionSchema,
|
|
42
43
|
DataFusionConnectionSchema,
|
|
43
44
|
DuckDBConnectionSchema,
|
|
44
45
|
IcebergConnectionSchema,
|
|
@@ -210,6 +211,16 @@ const DATABASES = [
|
|
|
210
211
|
preferred: "redshift",
|
|
211
212
|
},
|
|
212
213
|
},
|
|
214
|
+
{
|
|
215
|
+
name: "Databricks",
|
|
216
|
+
schema: DatabricksConnectionSchema,
|
|
217
|
+
color: "#c41e0c",
|
|
218
|
+
logo: "databricks",
|
|
219
|
+
connectionLibraries: {
|
|
220
|
+
libraries: ["sqlalchemy", "sqlmodel", "ibis"],
|
|
221
|
+
preferred: "sqlalchemy",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
213
224
|
] satisfies ConnectionSchema[];
|
|
214
225
|
|
|
215
226
|
const DATA_CATALOGS = [
|
|
@@ -14,7 +14,8 @@ export type ConnectionLibrary =
|
|
|
14
14
|
| "pyiceberg"
|
|
15
15
|
| "ibis"
|
|
16
16
|
| "motherduck"
|
|
17
|
-
| "redshift"
|
|
17
|
+
| "redshift"
|
|
18
|
+
| "databricks";
|
|
18
19
|
|
|
19
20
|
export const ConnectionDisplayNames: Record<ConnectionLibrary, string> = {
|
|
20
21
|
sqlmodel: "SQLModel",
|
|
@@ -26,6 +27,7 @@ export const ConnectionDisplayNames: Record<ConnectionLibrary, string> = {
|
|
|
26
27
|
ibis: "Ibis",
|
|
27
28
|
motherduck: "MotherDuck",
|
|
28
29
|
redshift: "Redshift",
|
|
30
|
+
databricks: "Databricks",
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
abstract class CodeGenerator<T extends DatabaseConnection["type"]> {
|
|
@@ -55,6 +57,9 @@ abstract class CodeGenerator<T extends DatabaseConnection["type"]> {
|
|
|
55
57
|
case "duckdb":
|
|
56
58
|
imports.add("import duckdb");
|
|
57
59
|
break;
|
|
60
|
+
case "ibis":
|
|
61
|
+
imports.add("import ibis");
|
|
62
|
+
break;
|
|
58
63
|
}
|
|
59
64
|
return imports;
|
|
60
65
|
}
|
|
@@ -138,10 +143,38 @@ class SecretContainer {
|
|
|
138
143
|
return `{${value}}`;
|
|
139
144
|
}
|
|
140
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Generate a password variable for connection strings, supporting inline values,
|
|
148
|
+
* environment variable lookups, and f-string formatting.
|
|
149
|
+
* @param {string|undefined} password - Fallback password value.
|
|
150
|
+
* @param {string} passwordPlaceholder - Environment variable name.
|
|
151
|
+
* @param {boolean} inFString - If true, wrap for Python f-string.
|
|
152
|
+
* @param {string} [variableName] - Variable name (default: "password").
|
|
153
|
+
* @returns {string}
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* `printPassword("token123", "DATABRICKS_ACCESS_TOKEN", true, "access_token")`
|
|
157
|
+
*
|
|
158
|
+
* Returns:
|
|
159
|
+
* ```python
|
|
160
|
+
* _access_token = os.environ.get("DATABRICKS_ACCESS_TOKEN", "token123")
|
|
161
|
+
* f"db://sample:{_access_token}@sample.com"
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* `printPassword("token123", "DATABRICKS_ACCESS_TOKEN", false, "access_token")`
|
|
166
|
+
*
|
|
167
|
+
* Returns:
|
|
168
|
+
* ```python
|
|
169
|
+
* access_token = os.environ.get("DATABRICKS_ACCESS_TOKEN", "token123")
|
|
170
|
+
* f"db://sample:access_token@sample.com"
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
141
173
|
printPassword(
|
|
142
174
|
password: string | undefined,
|
|
143
175
|
passwordPlaceholder: string,
|
|
144
176
|
inFString: boolean,
|
|
177
|
+
variableName?: string,
|
|
145
178
|
): string {
|
|
146
179
|
// Inline passwords should use printInFString, otherwise use print
|
|
147
180
|
const printMethod = inFString
|
|
@@ -149,8 +182,8 @@ class SecretContainer {
|
|
|
149
182
|
: this.print.bind(this);
|
|
150
183
|
|
|
151
184
|
return isSecret(password)
|
|
152
|
-
? printMethod("password", password)
|
|
153
|
-
: printMethod("password", passwordPlaceholder, password);
|
|
185
|
+
? printMethod(variableName || "password", password)
|
|
186
|
+
: printMethod(variableName || "password", passwordPlaceholder, password);
|
|
154
187
|
}
|
|
155
188
|
|
|
156
189
|
getSecrets(): Record<string, string> {
|
|
@@ -557,7 +590,7 @@ class PyIcebergGenerator extends CodeGenerator<"iceberg"> {
|
|
|
557
590
|
class DataFusionGenerator extends CodeGenerator<"datafusion"> {
|
|
558
591
|
generateImports(): string[] {
|
|
559
592
|
// To trigger installation of ibis-datafusion
|
|
560
|
-
return ["
|
|
593
|
+
return ["from datafusion import SessionContext"];
|
|
561
594
|
}
|
|
562
595
|
|
|
563
596
|
generateConnectionCode(): string {
|
|
@@ -578,7 +611,7 @@ class DataFusionGenerator extends CodeGenerator<"datafusion"> {
|
|
|
578
611
|
|
|
579
612
|
class PySparkGenerator extends CodeGenerator<"pyspark"> {
|
|
580
613
|
generateImports(): string[] {
|
|
581
|
-
return ["
|
|
614
|
+
return ["from pyspark.sql import SparkSession"];
|
|
582
615
|
}
|
|
583
616
|
|
|
584
617
|
generateConnectionCode(): string {
|
|
@@ -668,6 +701,70 @@ ${formatUrlParams(params, (inner) => ` ${inner}`)},
|
|
|
668
701
|
}
|
|
669
702
|
}
|
|
670
703
|
|
|
704
|
+
class DatabricksGenerator extends CodeGenerator<"databricks"> {
|
|
705
|
+
generateImports(): string[] {
|
|
706
|
+
return [];
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
generateConnectionCode(): string {
|
|
710
|
+
const useFString = this.orm !== "ibis";
|
|
711
|
+
|
|
712
|
+
const accessToken = this.secrets.printPassword(
|
|
713
|
+
this.connection.access_token,
|
|
714
|
+
"DATABRICKS_ACCESS_TOKEN",
|
|
715
|
+
useFString,
|
|
716
|
+
"access_token",
|
|
717
|
+
);
|
|
718
|
+
|
|
719
|
+
const serverHostname = this.secrets.printPassword(
|
|
720
|
+
this.connection.server_hostname,
|
|
721
|
+
"DATABRICKS_SERVER_HOSTNAME",
|
|
722
|
+
useFString,
|
|
723
|
+
"server_hostname",
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
const httpPath = this.secrets.printPassword(
|
|
727
|
+
this.connection.http_path,
|
|
728
|
+
"DATABRICKS_HTTP_PATH",
|
|
729
|
+
useFString,
|
|
730
|
+
"http_path",
|
|
731
|
+
);
|
|
732
|
+
|
|
733
|
+
const catalog = this.connection.catalog
|
|
734
|
+
? this.secrets.printInFString("catalog", this.connection.catalog)
|
|
735
|
+
: undefined;
|
|
736
|
+
const schema = this.connection.schema
|
|
737
|
+
? this.secrets.printInFString("schema", this.connection.schema)
|
|
738
|
+
: undefined;
|
|
739
|
+
|
|
740
|
+
let BASE_URL = `databricks://token:${accessToken}@${serverHostname}?http_path=${httpPath}`;
|
|
741
|
+
if (catalog) {
|
|
742
|
+
BASE_URL += `&catalog=${catalog}`;
|
|
743
|
+
}
|
|
744
|
+
if (schema) {
|
|
745
|
+
BASE_URL += `&schema=${schema}`;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
if (this.orm === "ibis") {
|
|
749
|
+
const catalogParam = catalog ? `\n catalog=${catalog},` : "";
|
|
750
|
+
const schemaParam = schema ? `\n schema=${schema},` : "";
|
|
751
|
+
|
|
752
|
+
return dedent(`
|
|
753
|
+
engine = ibis.databricks.connect(
|
|
754
|
+
server_hostname=${serverHostname},
|
|
755
|
+
http_path=${httpPath},${catalogParam}${schemaParam}
|
|
756
|
+
access_token=${accessToken}
|
|
757
|
+
)
|
|
758
|
+
`);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
return dedent(`
|
|
762
|
+
DATABASE_URL = f"${BASE_URL}"
|
|
763
|
+
engine = ${this.orm}.create_engine(DATABASE_URL)
|
|
764
|
+
`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
671
768
|
class CodeGeneratorFactory {
|
|
672
769
|
public secrets = new SecretContainer();
|
|
673
770
|
|
|
@@ -706,6 +803,8 @@ class CodeGeneratorFactory {
|
|
|
706
803
|
return new PySparkGenerator(connection, orm, this.secrets);
|
|
707
804
|
case "redshift":
|
|
708
805
|
return new RedshiftGenerator(connection, orm, this.secrets);
|
|
806
|
+
case "databricks":
|
|
807
|
+
return new DatabricksGenerator(connection, orm, this.secrets);
|
|
709
808
|
default:
|
|
710
809
|
assertNever(connection);
|
|
711
810
|
}
|
|
@@ -16,18 +16,16 @@ function passwordField() {
|
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function tokenField() {
|
|
20
|
-
|
|
21
|
-
.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}),
|
|
30
|
-
);
|
|
19
|
+
function tokenField(label?: string, required?: boolean) {
|
|
20
|
+
const field = z.string().describe(
|
|
21
|
+
FieldOptions.of({
|
|
22
|
+
label: label || "Token",
|
|
23
|
+
inputType: "password",
|
|
24
|
+
placeholder: "token",
|
|
25
|
+
optionRegex: ".*token.*",
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
28
|
+
return required ? field.nonempty() : field.optional();
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
function warehouseNameField() {
|
|
@@ -43,20 +41,22 @@ function warehouseNameField() {
|
|
|
43
41
|
);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
function uriField() {
|
|
47
|
-
|
|
44
|
+
function uriField(label?: string, required?: boolean) {
|
|
45
|
+
const field = z
|
|
48
46
|
.string()
|
|
49
|
-
.
|
|
50
|
-
|
|
47
|
+
.describe(
|
|
48
|
+
FieldOptions.of({ label: label || "URI", optionRegex: ".*uri.*" }),
|
|
49
|
+
);
|
|
50
|
+
return required ? field.nonempty() : field.optional();
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function hostField() {
|
|
53
|
+
function hostField(label?: string) {
|
|
54
54
|
return z
|
|
55
55
|
.string()
|
|
56
56
|
.nonempty()
|
|
57
57
|
.describe(
|
|
58
58
|
FieldOptions.of({
|
|
59
|
-
label: "Host",
|
|
59
|
+
label: label || "Host",
|
|
60
60
|
placeholder: "localhost",
|
|
61
61
|
optionRegex: ".*host.*",
|
|
62
62
|
}),
|
|
@@ -464,6 +464,23 @@ export const RedshiftConnectionSchema = z
|
|
|
464
464
|
})
|
|
465
465
|
.describe(FieldOptions.of({ direction: "two-columns" }));
|
|
466
466
|
|
|
467
|
+
export const DatabricksConnectionSchema = z
|
|
468
|
+
.object({
|
|
469
|
+
type: z.literal("databricks"),
|
|
470
|
+
access_token: tokenField("Access Token", true),
|
|
471
|
+
server_hostname: hostField("Server Hostname"),
|
|
472
|
+
http_path: uriField("HTTP Path", true),
|
|
473
|
+
catalog: z
|
|
474
|
+
.string()
|
|
475
|
+
.optional()
|
|
476
|
+
.describe(FieldOptions.of({ label: "Catalog" })),
|
|
477
|
+
schema: z
|
|
478
|
+
.string()
|
|
479
|
+
.optional()
|
|
480
|
+
.describe(FieldOptions.of({ label: "Schema" })),
|
|
481
|
+
})
|
|
482
|
+
.describe(FieldOptions.of({ direction: "two-columns" }));
|
|
483
|
+
|
|
467
484
|
export const DatabaseConnectionSchema = z.discriminatedUnion("type", [
|
|
468
485
|
PostgresConnectionSchema,
|
|
469
486
|
MySQLConnectionSchema,
|
|
@@ -480,6 +497,7 @@ export const DatabaseConnectionSchema = z.discriminatedUnion("type", [
|
|
|
480
497
|
DataFusionConnectionSchema,
|
|
481
498
|
PySparkConnectionSchema,
|
|
482
499
|
RedshiftConnectionSchema,
|
|
500
|
+
DatabricksConnectionSchema,
|
|
483
501
|
]);
|
|
484
502
|
|
|
485
503
|
export type DatabaseConnection = z.infer<typeof DatabaseConnectionSchema>;
|
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
/* Copyright 2024 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
+
import { useAtomValue, useSetAtom } from "jotai";
|
|
3
4
|
import { WrenchIcon } from "lucide-react";
|
|
4
5
|
import { Button } from "@/components/ui/button";
|
|
5
6
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
7
|
+
import { aiCompletionCellAtom } from "@/core/ai/state";
|
|
6
8
|
import { notebookAtom, useCellActions } from "@/core/cells/cells";
|
|
7
9
|
import type { CellId } from "@/core/cells/ids";
|
|
10
|
+
import { aiEnabledAtom } from "@/core/config/config";
|
|
8
11
|
import { getAutoFixes } from "@/core/errors/errors";
|
|
9
12
|
import type { MarimoError } from "@/core/kernel/messages";
|
|
10
13
|
import { store } from "@/core/state/jotai";
|
|
14
|
+
import { cn } from "@/utils/cn";
|
|
11
15
|
|
|
12
16
|
export const AutoFixButton = ({
|
|
13
17
|
errors,
|
|
14
18
|
cellId,
|
|
19
|
+
className,
|
|
15
20
|
}: {
|
|
16
21
|
errors: MarimoError[];
|
|
17
22
|
cellId: CellId;
|
|
18
23
|
className?: string;
|
|
19
24
|
}) => {
|
|
20
25
|
const { createNewCell } = useCellActions();
|
|
21
|
-
const
|
|
26
|
+
const aiEnabled = useAtomValue(aiEnabledAtom);
|
|
27
|
+
const autoFixes = errors.flatMap((error) =>
|
|
28
|
+
getAutoFixes(error, { aiEnabled }),
|
|
29
|
+
);
|
|
30
|
+
const setAiCompletionCell = useSetAtom(aiCompletionCellAtom);
|
|
22
31
|
|
|
23
32
|
if (autoFixes.length === 0) {
|
|
24
33
|
return null;
|
|
@@ -33,7 +42,7 @@ export const AutoFixButton = ({
|
|
|
33
42
|
<Button
|
|
34
43
|
size="xs"
|
|
35
44
|
variant="outline"
|
|
36
|
-
className="my-2 font-normal"
|
|
45
|
+
className={cn("my-2 font-normal", className)}
|
|
37
46
|
onClick={() => {
|
|
38
47
|
const editorView =
|
|
39
48
|
store.get(notebookAtom).cellHandles[cellId].current?.editorView;
|
|
@@ -48,6 +57,7 @@ export const AutoFixButton = ({
|
|
|
48
57
|
},
|
|
49
58
|
editor: editorView,
|
|
50
59
|
cellId: cellId,
|
|
60
|
+
setAiCompletionCell,
|
|
51
61
|
});
|
|
52
62
|
// Focus the editor
|
|
53
63
|
editorView?.focus();
|
|
@@ -2,29 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
import { AlertCircleIcon } from "lucide-react";
|
|
4
4
|
import type { CellId } from "@/core/cells/ids";
|
|
5
|
-
import { useSqlValidationErrorsForCell } from "@/core/codemirror/language/languages/sql/validation-errors";
|
|
5
|
+
import { useSqlValidationErrorsForCell } from "@/core/codemirror/language/languages/sql/banner-validation-errors";
|
|
6
6
|
|
|
7
|
-
export const SqlValidationErrorBanner = ({
|
|
7
|
+
export const SqlValidationErrorBanner = ({
|
|
8
|
+
cellId,
|
|
9
|
+
hide,
|
|
10
|
+
}: {
|
|
11
|
+
cellId: CellId;
|
|
12
|
+
hide: boolean;
|
|
13
|
+
}) => {
|
|
8
14
|
const error = useSqlValidationErrorsForCell(cellId);
|
|
9
15
|
|
|
10
|
-
if (!error) {
|
|
16
|
+
if (!error || hide) {
|
|
11
17
|
return;
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
return (
|
|
15
|
-
<div className="p-3 text-sm flex flex-col text-muted-foreground gap-1.5 bg-destructive/
|
|
21
|
+
<div className="p-3 text-sm flex flex-col text-muted-foreground gap-1.5 bg-destructive/4">
|
|
16
22
|
<div className="flex items-start gap-1.5">
|
|
17
23
|
<AlertCircleIcon size={13} className="mt-[3px] text-destructive" />
|
|
18
24
|
<p>
|
|
19
25
|
<span className="font-bold text-destructive">{error.errorType}:</span>{" "}
|
|
20
|
-
{error.errorMessage}
|
|
26
|
+
<span className="whitespace-pre-wrap">{error.errorMessage}</span>
|
|
21
27
|
</p>
|
|
22
28
|
</div>
|
|
23
29
|
|
|
24
30
|
{error.codeblock && (
|
|
25
31
|
<pre
|
|
26
32
|
lang="sql"
|
|
27
|
-
className="text-xs bg-muted rounded p-2 pb-0 mx-3
|
|
33
|
+
className="text-xs bg-muted/80 rounded p-2 pb-0 mx-3 font-medium whitespace-pre-wrap"
|
|
28
34
|
>
|
|
29
35
|
{error.codeblock}
|
|
30
36
|
</pre>
|
|
@@ -28,7 +28,7 @@ interface Props {
|
|
|
28
28
|
cellId: CellId;
|
|
29
29
|
cellName: string;
|
|
30
30
|
className?: string;
|
|
31
|
-
consoleOutputs:
|
|
31
|
+
consoleOutputs: WithResponse<OutputMessage>[];
|
|
32
32
|
stale: boolean;
|
|
33
33
|
debuggerActive: boolean;
|
|
34
34
|
onRefactorWithAI?: (opts: { prompt: string }) => void;
|
|
@@ -200,7 +200,7 @@ const LEAF_RENDERERS = {
|
|
|
200
200
|
};
|
|
201
201
|
|
|
202
202
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
|
-
const MIME_TYPES:
|
|
203
|
+
const MIME_TYPES: DataType<any>[] = Object.entries(LEAF_RENDERERS).map(
|
|
204
204
|
([leafType, render]) => ({
|
|
205
205
|
is: (value) => typeof value === "string" && value.startsWith(leafType),
|
|
206
206
|
PostComponent: PyCopyButton,
|
|
@@ -77,7 +77,7 @@ export const MarimoErrorOutput = ({
|
|
|
77
77
|
alertVariant = "default";
|
|
78
78
|
titleColor = "text-secondary-foreground";
|
|
79
79
|
} else if (errors.some((e) => e.type === "sql-error")) {
|
|
80
|
-
titleContents = "SQL
|
|
80
|
+
titleContents = "SQL error";
|
|
81
81
|
} else {
|
|
82
82
|
// Check for exception type
|
|
83
83
|
const exceptionError = errors.find((e) => e.type === "exception");
|
|
@@ -500,25 +500,30 @@ export const MarimoErrorOutput = ({
|
|
|
500
500
|
<div key="sql-errors">
|
|
501
501
|
{sqlErrors.map((error, idx) => {
|
|
502
502
|
const line =
|
|
503
|
-
error.sql_line
|
|
504
|
-
const col =
|
|
503
|
+
error.sql_line == null ? null : Math.trunc(error?.sql_line) + 1;
|
|
504
|
+
const col =
|
|
505
|
+
error.sql_col == null ? null : Math.trunc(error?.sql_col) + 1;
|
|
505
506
|
return (
|
|
506
|
-
<div key={`sql-error-${idx}`} className="space-y-2">
|
|
507
|
-
<p className="text-muted-foreground">{error.msg}</p>
|
|
507
|
+
<div key={`sql-error-${idx}`} className="space-y-2 mt-2">
|
|
508
|
+
<p className="text-muted-foreground font-medium">{error.msg}</p>
|
|
508
509
|
{error.hint && (
|
|
509
510
|
<div className="flex items-start gap-2">
|
|
510
|
-
<InfoIcon
|
|
511
|
-
|
|
511
|
+
<InfoIcon
|
|
512
|
+
size={11}
|
|
513
|
+
className="text-muted-foreground mt-1 flex-shrink-0"
|
|
514
|
+
/>
|
|
515
|
+
<p className="whitespace-pre-wrap text-sm text-muted-foreground">
|
|
512
516
|
{error.hint}
|
|
513
|
-
</
|
|
517
|
+
</p>
|
|
514
518
|
</div>
|
|
515
519
|
)}
|
|
516
520
|
{error.sql_statement && (
|
|
517
|
-
<
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
521
|
+
<pre
|
|
522
|
+
lang="sql"
|
|
523
|
+
className="text-xs bg-muted/80 rounded whitespace-pre-wrap p-3.5"
|
|
524
|
+
>
|
|
525
|
+
{error.sql_statement.trim()}
|
|
526
|
+
</pre>
|
|
522
527
|
)}
|
|
523
528
|
{line !== null && col !== null && (
|
|
524
529
|
<p className="text-xs text-muted-foreground">
|
|
@@ -528,18 +533,13 @@ export const MarimoErrorOutput = ({
|
|
|
528
533
|
</div>
|
|
529
534
|
);
|
|
530
535
|
})}
|
|
531
|
-
{cellId &&
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
Check your SQL syntax and ensure you're using supported SQL
|
|
539
|
-
dialect features. The error location can help you identify the
|
|
540
|
-
problematic part of your query.
|
|
541
|
-
</p>
|
|
542
|
-
</Tip>
|
|
536
|
+
{cellId && (
|
|
537
|
+
<AutoFixButton
|
|
538
|
+
errors={sqlErrors}
|
|
539
|
+
cellId={cellId}
|
|
540
|
+
className="mt-2.5"
|
|
541
|
+
/>
|
|
542
|
+
)}
|
|
543
543
|
</div>,
|
|
544
544
|
);
|
|
545
545
|
}
|
|
@@ -108,7 +108,7 @@ export const MarimoTracebackOutput = ({
|
|
|
108
108
|
Fix with AI
|
|
109
109
|
</Button>
|
|
110
110
|
)}
|
|
111
|
-
{tracebackInfo && !isWasm() && (
|
|
111
|
+
{tracebackInfo && tracebackInfo.kind === "cell" && !isWasm() && (
|
|
112
112
|
<Tooltip content={"Attach pdb to the exception point."}>
|
|
113
113
|
<Button
|
|
114
114
|
size="xs"
|
|
@@ -180,7 +180,7 @@ function lastLine(text: string): string {
|
|
|
180
180
|
|
|
181
181
|
export const replaceTracebackFilenames = (domNode: DOMNode) => {
|
|
182
182
|
const info = getTracebackInfo(domNode);
|
|
183
|
-
if (info) {
|
|
183
|
+
if (info?.kind === "cell") {
|
|
184
184
|
const tooltipContent = <InsertBreakpointContent />;
|
|
185
185
|
return (
|
|
186
186
|
<span className="nb">
|
|
@@ -211,6 +211,21 @@ export const replaceTracebackFilenames = (domNode: DOMNode) => {
|
|
|
211
211
|
</span>
|
|
212
212
|
);
|
|
213
213
|
}
|
|
214
|
+
if (info?.kind === "file") {
|
|
215
|
+
return (
|
|
216
|
+
<div
|
|
217
|
+
className="inline-block cursor-pointer text-destructive hover:underline"
|
|
218
|
+
onClick={(_) => {
|
|
219
|
+
getRequestClient().openFile({
|
|
220
|
+
path: info.filePath,
|
|
221
|
+
lineNumber: info.lineNumber,
|
|
222
|
+
});
|
|
223
|
+
}}
|
|
224
|
+
>
|
|
225
|
+
<span className="nb">"{info.filePath}"</span>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
214
229
|
};
|
|
215
230
|
|
|
216
231
|
export const replaceTracebackPrefix = (domNode: DOMNode) => {
|
|
@@ -68,13 +68,13 @@ export interface GridLayout extends Omit<SerializedGridLayout, "cells"> {
|
|
|
68
68
|
/**
|
|
69
69
|
* The cells in the layout.
|
|
70
70
|
*/
|
|
71
|
-
cells:
|
|
71
|
+
cells: {
|
|
72
72
|
i: string;
|
|
73
73
|
x: number;
|
|
74
74
|
y: number;
|
|
75
75
|
w: number;
|
|
76
76
|
h: number;
|
|
77
|
-
}
|
|
77
|
+
}[];
|
|
78
78
|
|
|
79
79
|
scrollableCells: Set<CellId>;
|
|
80
80
|
|
|
@@ -8,7 +8,7 @@ import { VerticalLayoutPlugin } from "./vertical-layout/vertical-layout";
|
|
|
8
8
|
|
|
9
9
|
// If more renderers are added, we may want to consider lazy loading them.
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
-
export const cellRendererPlugins:
|
|
11
|
+
export const cellRendererPlugins: ICellRendererPlugin<any, any>[] = [
|
|
12
12
|
GridLayoutPlugin,
|
|
13
13
|
SlidesLayoutPlugin,
|
|
14
14
|
VerticalLayoutPlugin,
|
|
@@ -198,7 +198,7 @@ const ActionButtons: React.FC<{
|
|
|
198
198
|
actions.push(
|
|
199
199
|
<DropdownMenuItem
|
|
200
200
|
onSelect={onToggleShowCode}
|
|
201
|
-
|
|
201
|
+
data-testid="notebook-action-show-code"
|
|
202
202
|
key="show-code"
|
|
203
203
|
>
|
|
204
204
|
<Code2Icon className="mr-2" size={14} strokeWidth={1.5} />
|
|
@@ -213,7 +213,7 @@ const ActionButtons: React.FC<{
|
|
|
213
213
|
actions.push(
|
|
214
214
|
<DropdownMenuItem
|
|
215
215
|
onSelect={handleDownloadAsHTML}
|
|
216
|
-
|
|
216
|
+
data-testid="notebook-action-download-html"
|
|
217
217
|
key="download-html"
|
|
218
218
|
>
|
|
219
219
|
<FolderDownIcon className="mr-2" size={14} strokeWidth={1.5} />
|
|
@@ -222,7 +222,7 @@ const ActionButtons: React.FC<{
|
|
|
222
222
|
<DropdownMenuSeparator key="download-html-separator" />,
|
|
223
223
|
<DropdownMenuItem
|
|
224
224
|
onSelect={handleDownloadAsPNG}
|
|
225
|
-
|
|
225
|
+
data-testid="notebook-action-download-png"
|
|
226
226
|
key="download-png"
|
|
227
227
|
>
|
|
228
228
|
<ImageIcon className="mr-2" size={14} strokeWidth={1.5} />
|
|
@@ -239,7 +239,7 @@ const ActionButtons: React.FC<{
|
|
|
239
239
|
// as this may be used in custom css to hide/show the actions dropdown
|
|
240
240
|
return (
|
|
241
241
|
<div
|
|
242
|
-
|
|
242
|
+
data-testid="notebook-actions-dropdown"
|
|
243
243
|
className={cn(
|
|
244
244
|
"right-0 top-0 z-50 m-4 no-print flex gap-2 print:hidden",
|
|
245
245
|
// If the notebook is static, we have a banner at the top, so
|
|
@@ -419,10 +419,10 @@ export const VerticalLayoutPlugin: ICellRendererPlugin<
|
|
|
419
419
|
};
|
|
420
420
|
|
|
421
421
|
export function groupCellsByColumn(
|
|
422
|
-
cells:
|
|
423
|
-
):
|
|
422
|
+
cells: (CellRuntimeState & CellData)[],
|
|
423
|
+
): [number, (CellRuntimeState & CellData)[]][] {
|
|
424
424
|
// Group cells by column
|
|
425
|
-
const cellsByColumn = new Map<number,
|
|
425
|
+
const cellsByColumn = new Map<number, (CellRuntimeState & CellData)[]>();
|
|
426
426
|
let lastSeenColumn = 0;
|
|
427
427
|
cells.forEach((cell) => {
|
|
428
428
|
const column = cell.config.column ?? lastSeenColumn;
|
|
@@ -59,7 +59,7 @@ interface Props<T extends FieldValues> {
|
|
|
59
59
|
form: UseFormReturn<T>;
|
|
60
60
|
schema: z.ZodType;
|
|
61
61
|
path?: Path<T>;
|
|
62
|
-
renderers:
|
|
62
|
+
renderers: FormRenderer<T>[] | undefined;
|
|
63
63
|
children?: React.ReactNode;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -82,7 +82,7 @@ export function renderZodSchema<T extends FieldValues, S>(
|
|
|
82
82
|
schema: z.ZodType<S>,
|
|
83
83
|
form: UseFormReturn<T>,
|
|
84
84
|
path: Path<T>,
|
|
85
|
-
renderers:
|
|
85
|
+
renderers: FormRenderer<T>[],
|
|
86
86
|
) {
|
|
87
87
|
// Try custom renderers first
|
|
88
88
|
for (const renderer of renderers) {
|
|
@@ -330,7 +330,7 @@ export function renderZodSchema<T extends FieldValues, S>(
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
if (schema instanceof z.ZodDiscriminatedUnion) {
|
|
333
|
-
const options = schema._def.options as
|
|
333
|
+
const options = schema._def.options as z.ZodType<unknown>[];
|
|
334
334
|
const discriminator = schema._def.discriminator;
|
|
335
335
|
const optionsMap = schema._def.optionsMap;
|
|
336
336
|
return (
|
|
@@ -392,7 +392,7 @@ export function renderZodSchema<T extends FieldValues, S>(
|
|
|
392
392
|
control={form.control}
|
|
393
393
|
name={path}
|
|
394
394
|
render={({ field }) => {
|
|
395
|
-
const options = schema._def.options as
|
|
395
|
+
const options = schema._def.options as z.ZodType<unknown>[];
|
|
396
396
|
let value: string = field.value;
|
|
397
397
|
const types = options.map((option) => {
|
|
398
398
|
return getUnionLiteral(option)._def.value;
|
|
@@ -812,6 +812,6 @@ const MultiSelectFormField = ({
|
|
|
812
812
|
);
|
|
813
813
|
};
|
|
814
814
|
|
|
815
|
-
function joinPath<T>(...parts:
|
|
815
|
+
function joinPath<T>(...parts: (string | number)[]): Path<T> {
|
|
816
816
|
return parts.filter((part) => part !== "").join(".") as Path<T>;
|
|
817
817
|
}
|
|
@@ -8,6 +8,7 @@ export const ExternalLink = ({
|
|
|
8
8
|
| `https://console.anthropic.com/${string}`
|
|
9
9
|
| `https://aistudio.google.com/${string}`
|
|
10
10
|
| `https://github.com/${string}`
|
|
11
|
+
| `https://openrouter.ai/${string}`
|
|
11
12
|
| `https://docs.marimo.io/${string}`
|
|
12
13
|
| `https://docs.python.org/${string}`
|
|
13
14
|
| `https://marimo.io/${string}`
|